diff --git a/wolfSSL/mkdocs-ja.yml b/wolfSSL/mkdocs-ja.yml index f13f95b5..b9469627 100644 --- a/wolfSSL/mkdocs-ja.yml +++ b/wolfSSL/mkdocs-ja.yml @@ -9,7 +9,7 @@ nav: - "3. wolfSSL入門": chapter03.md - "4. 機能": chapter04.md - "5. ポータビリティ": chapter05.md - - "6. コールバク": chapter06.md + - "6. コールバック": chapter06.md - "7. 鍵と証明書": chapter07.md - "8. デバッグ": chapter08.md - "9. ライブラリー設計方針": chapter09.md @@ -31,7 +31,7 @@ nav: - "wolfSSL 初期化": group__TLS.md - "B. wolfCrypt API レファレンス": - "ASN.1": group__ASN.md - - "ベースエンコード": group__Base__Encoding.md + - "ベースエンコーディング": group__Base__Encoding.md - "圧縮": group__Compression.md - "エラーレポート": group__Error.md - "IoT-Safeモジュール": group__IoTSafe.md @@ -48,7 +48,7 @@ nav: - "暗号アルゴリズム - Camellia": group__Camellia.md - "暗号アルゴリズム - ChaCha": group__ChaCha.md - "暗号アルゴリズム - ChaCha20_Poly1305": group__ChaCha20Poly1305.md - - "Algorithms - CMAC ": group__CMAC.md + - "暗号アルゴリズム - CMAC ": group__CMAC.md - "コールバック - CryptoCb": group__Crypto.md - "暗号アルゴリズム - Curve25519": group__Curve25519.md - "暗号アルゴリズム - Curve448": group__Curve448.md diff --git a/wolfSSL/src-ja/buckets.png b/wolfSSL/src-ja/buckets.png new file mode 100644 index 00000000..58521fc4 Binary files /dev/null and b/wolfSSL/src-ja/buckets.png differ diff --git a/wolfSSL/src-ja/chapter04.md b/wolfSSL/src-ja/chapter04.md index f5fe7752..1e9f99ef 100644 --- a/wolfSSL/src-ja/chapter04.md +++ b/wolfSSL/src-ja/chapter04.md @@ -1213,6 +1213,287 @@ wolfSSL Snifferを使用したCallbacksを`WOLFSSL_SNIFFER_WATCH`でオンにす * `sslEncryptedConns` +## 静的バッファ確保オプション + +wolfSSLでは**動的**メモリ管理が提供されていることを前提に処理が記述されています。すなわち、malloc/free関数でバッファを確保/解放できることを前提としています。 + +wolfSSLが内部で使用している暗号化ライブラリwolfCryptでは動的メモリを使用しない設定も可能です。これは動的メモリ管理機能を提供していない環境や、あるいは安全面の制約で動的メモリ管理機能の使用が制限されている環境では好ましいと言えます。 + +一方、組み込み機器ではOSを使用しない(いわゆるベアメタル)環境で使用する場合、あるいはリアルタイムOSを使用している場合でも動的メモリ管理機能が提供されていない場合があります。このような環境でwolfSSLを使用する方法として**静的バッファ確保オプション**を提供しています。 + +### 静的バッファ確保の基本動作 + +先に説明した「動的メモリ管理」はバッファを「指定されたサイズ(可変長)」に動的に切り出して提供する管理方法です。バッファの使用効率は高いですが処理が比較的複雑です。一方、wolfSSLが提供する「静的バッファ確保機能」は、あらかじめ(静的に)用意した何種類かのバッファのなかから、要求したサイズに近いものを検索して提供するメモリ管理機能のことを言います。バッファの要求元には要求サイズ以上の大きさを持ったメモリブロックが割り当てられることがあります(そのため使用効率が低下します)が、バッファの確保と解放はmalloc/freeと同様に行え、割り当て処理は単純ですみます。任意サイズのメモリブロックを動的に確保する動的メモリ確保を模擬した機能となっています。 + +静的バッファ確保機能の使用はwolfSSLにとっては動的メモリ機能と等価に使用されます。この機能はwolfSSLがメモリの確保/解放をXMALLOC/XFREE関数呼び出しに抽象化してあることで実現できています。一旦、静的バッファ確保機能が設定されると、以降wolfSSLは内部で使用するバッファや他の構造体の確保に静的バッファ確保機能を使用します。この機能はWOLFSSL_CTXに対して設定するので、このオブジェクトの生存期間中は機能が継続します。 + +WOLFSSL_CTXに設定された静的バッファ確保機能はスレッドセーフとなっています。同一のWOLFSSL_CTXを異なるスレッドで共有しながら使用している場合でも、バッファの確保/解放はwolfSSL内部で排他制御しながら利用します。 + +また、RTOSで使用されているメモリプールを使ったメモリ機能では未使用のメモリブロックが見つからない場合にはそのスレッド(タスク)は空きブロックが発生するまでサスペンドされますが、wolfSSLの静的バッファ確保機能にはそのような待ち合わせ機能はありません。 + +### 静的バッファの用途指定 + +静的バッファ確保機能では、2つの用途別にメモリを分けることが可能です。つまり、一般的な目的用とI/O用に使用するバッファを分けて割り当て/解放を行うことが可能です。I/Oに使用するバッファはTLSでの典型的必要サイズから最大2^16バイトまでを扱えるように比較的大きく(17KB程度)設定されていて、それ以外の一般的な用途のバッファサイズと異なる点と、I/Oを行うスレッド(タスク)とそれ以外のスレッドでのメモリ獲得/解放に伴う排他制御を排除したいという2つの理由で用途別に分けることを推奨しています。 + +さらに、バッファを設定した際に、同時に生成できるWOLFSSLオブジェクトの最大数を制限することができます。最大数を制限するとwolfSSL_new()関数を使う度に生成できるWOLFSSLオブジェクトの数がチェックされ、上限を超えるとエラーとなります。 + +### 静的バッファ確保機能の有効化 + +wolfSSLのビルド時に静的バッファ確保オプションを有効化します。autoconfツールを使用してビルドするシステムでは次のように”–enable-staticmemory“を指定します。 + +``` + $./configure --enable-staticmemory +``` + +あるいはuser_settings.hを使用している場合には次のマクロ定義を追加します: +``` +user_settings.h + + #define WOLFSSL_STATIC_MEMORY +``` +さらに、静的バッファ確保機能は与えられたバッファから確保するメモリブロックが枯渇した際に、NULLを返さず標準関数のmalloc()を追加で呼び出す実装となっています。もし、環境に動的メモリ管理機能が提供されていない場合にはリンクエラーとなります。したがって、この機能をディセーブルにする為に、**WOLFSSL_NO_MALLOC**マクロも定義しておきます: + +``` +user_settings.h + + #define WOLFSSL_STATIC_MEMORY + #define WOLFSSL_NO_MALLOC +``` + + +### 静的バッファ確保機能の利用方法 + +上記設定でwolfSSLをビルドすることにより、静的バッファ確保機能が有効となります。 + + +#### 静的バッファの設定関数とその引数 +さらにこの機能を利用するにあたってはアプリケーションは次の関数を呼び出してヒープとして使用するバッファを指定します: + +``` +int wolfSSL_CTX_load_static_memory( + WOLFSSL_CTX** ctx, /* 生成したWOLFSSL_CTXを受け取る為の変数へのポインタ */ + wolfSSL_Methos_func method,/* メソッド */ + unsigned char* buf, /* ヒープとして使用するバッファへのポインタ */ + unsigned int sz, /* ヒープとして使用するバッファのサイズ */ + int flag, /* ヒープの使用用途 */ + int max); /* 許可する最大平行動作数 */ +``` + + +- 引数**ctx**には生成されたWOLFSSL_CTX構造体へのポインタを受け取る変数のアドレスを指定します。
+- 引数**method**にはwolfSSLv23_client_method_**ex**()などの"_ex"が付いた関数の戻り値を指定します。
+- 引数**buf**,**sz**にはそれぞれヒープに使用するバッファのアドレスとそのサイズを指定します。設定すべきバッファのサイズの決定については「必要バッファのサイズの取得」を参照してください。
+- 引数**flag**には一般用途あるいはI/O用を指定する用途と静的バッファの確保状況のトラッキングを行うかどうかのフラグを組み合わせて指定します。一般用途を指定する場合には”0″あるいはWOLFMEM_GENERALを指定します。I/O用としての指定はWOLFMEM_IO_POOあるいはWOLFMEM_IO_POOL_FIXEDを指定します。静的バッファの確保状況のトラッキングを行う場合には用途を指定する値にWOLFMEM_TRACK_STATSをORして指定します。
+- 引数**max**は引数flagで指定したバッファの用途に関係します。バッファの用途が一般用の場合には、生成するWOLFSSLオブジェクトの最大同時生成数(同時に存在できるオブジェクト数)を設定することになります。制限を行う必要がなければ0を指定します。0以外の制限値を指定した場合には、その後のwolfSSL_newの呼び出しで生成するWOLFSSLオブジェクトの同時オブジェクト数が設定値を超える際には生成が失敗することになります。 + +#### 静的バッファの設定関数の呼び出し方 + +静的バッファ確保機能を利用する際には、この**wolfSSL_CTX_load_static_memory関数を2回呼び出します。最初は一般用途用にバッファを設定し、さらにそのバッファを使ってWOLFSSL_CTX構造体を確保します。2回目の呼び出しでは、I/O用バッファを設定します**: + + ``` + WOLFSSL_CTX* ctx = NULL; /* WOLFSSL_CTXを生成する場合にはNULLを指定 */ + int ret; + + #define MAX_CONCURRENT_TLS 0 + #define MAX_CONCURRENT_IO 0 + + unsigned char GEN_MEM[GEN_MEM_SIZE]; + unsigned char IO_MEM[IO_MEM_SIZE];  + + /* 最初の呼び出しで一般用静的バッファを設定してそこからWOLFSSL_CTXを生成する */ + ret = wolfSSL_CTX_load_static_memory( + &ctx, /* ctx変数の内容にはNULLをセットしておく */ + wolfSSLv23_client_method_ex(), /* "_ex"の付いた関数を使う */ + GEN_MEM, GEN_MEM_SIZE, /* 一般用途のバッファとそのサイズ */ + WOLFMEM_GENERAL, /* 一般用途で使用 */ + MAX_CONCURRENT_TLS); /* 最大許容同時接続数 */ + + /* 次は生成したWOLFSSL_CTXにI/O用静的バッファをセットする */ + ret = wolfSSL_CTX_load_static_memory( + &ctx, /* ctxには生成済み構造体が格納されている */ + NULL, /* 今度はctxの生成は行わないのでNULLをセット */ + IO_MEM, IO_MEM_SIZE, /* I/O用途のバッファとそのサイズ */ + WOLFMEM_IO_FIXED, + MAX_CONCURRENT_IO); + + + ``` +この後、WOLFSSL_CTX構造体の使用を終了した後は、通常のwolfSSL_CTX_free()を使って解放してください。 + + +### 静的バッファ確保機能の調整 + +wolfSSLで提供しているこの静的バッファ確保機能では指定されたバッファを次の図の様に複数の”バケット(bucket)”という領域に分けて管理します。バケット内には同一サイズの複数のメモリブロックがリンクされています。下図の中にはメモリブロックの管理のための構造は省略していますが、実際にはそれらの管理領域も含めて必要なサイズを持つバッファが与えられなければなりません。 + +![バケット](buckets.png) + +上記構造は一般用、I/O用のいずれのバッファにも適用されますが、I/O用バッファにはBucketは一種類しかありません。 + +#### 一般用バッファの設定用マクロ定義 + +各バケットはバケット内に含むメモリブロックの数とそのサイズに応じて大きさが異なります。 + +使用する各領域のメモリブロックサイズとブロックの個数が/wolfssl/wolfcrypt/memory.hに次のようなマクロで定義してあります: + +``` +/wolfssl/wolfcrypt/memory.h + + #define WOLFSSL_STATIC_ALIGN 16 /* 適用されるアライメント(デフォルト16バイト)*/ + #define WOLFMEM_MAX_BUCKETS 9    /* バケット数 */ + #define LARGEST_MEM_BUCKET 16128 /* 最大ブロックのサイズ */ + #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3456,4544,LARGEST_MEM_BUCKET + #define WOLFMEM_DIST 49,10,6,14,5,6,9,1,1 +``` + + +- **WOLFSSL_STATIC_ALIGN**はバッファのアライメントサイズを指定します。デフォルトで16バイトです。御使用のMCUでのアライメントサイズに合わせて変更する必要があります。 +- **WOLFMEM_MAX_BUCKETS**がバケットの数を示しています。9種類のサイズのバケットを使用することを意味しています。 +- **WOLFMEM_BUCKETS**が各バケット内のブロックのバイト数を小さいものから順にコンマ区切りで指定しています。この定義は一般用バッファに適用されます。 +- **WOLFMEM_DIST**が各バケットに含まれる同一サイズのブロックの数をWOLFMEM_BUCKETSの各ブロックに対応するようにそれらの個数をコンマ区切りで指定しています。この定義は一般用バッファに適用されます。 + +上記の例でいえば、ブロックサイズ64バイトのバケットが最小のサイズであり、そのバケットには49個のメモリブロックを用意することになります。次に大きいバケットはブロックサイズ128バイトで10個のメモリブロックを用意することを意味します。 + +上記定義値はデフォルトの値として使用していただけますが、実際の環境での使用時には各バケットのサイズとそこに含まれるメモリブロック数は調整が必要かもしれません。 + +#### I/O用バッファの設定用マクロ定義 + +I/O用途のバッファは上記一般用途と管理方法は同じですが、バケット数は”1”、バケット内のメモリブロックは1つだけです。またメモリブロックのサイズは**WOLFMEM_IO_SZ**で定義された値となっています。 + +このI/OバッファのサイズはTLSハンドシェークで送受信される最大パケットサイズを考慮して設定されていますが、この最大パケットサイズを**wolfSSL_CTX_UseMaxFragment**()を使ってより小さい値に設定することが可能です。この関数を使って最大パケットサイズを小さくした場合には、その値(この例では660バイト)をWOLFMEM_IO_SZとして設定してください。 + +``` + $ ./configure --enable-staticmemory C_EXTRA_FLAGS="-DWOLFMEM_IO_SZ=660" +``` + + +#### 必要バッファサイズの取得 + +静的バッファ確保機能に割り当てるバッファサイズ(すなわちwolfSSL_CTX_load_static_memory関数に渡すバッファサイズ)の決定に有用な関数を用意してあります。この章の冒頭でバッファが内部でバケットと管理領域からなる構造に構成されて使用されることを説明しました。実際にバッファのサイズを決定する際には、メモリブロックのサイズと管理領域の占めるサイズとパディングによる余分に必要なサイズも含めて計算する必要があります。この計算を行い、必要なバッファサイズを返してくれる関数を用意してあります。 + +wolfSSL_StaticBufferSz関数は、直前のセクションで紹介したマクロ定義値を基にに必要なバッファサイズを計算して返します。この関数が0より大きい値を返すまで、第2引数に与えるサイズは1000などの適当な値からスタートし、戻り値が正となるまでサイズを増やして何度も呼び出します。第3引数のflagには一般用バッファサイズを計算する場合には**WOLFMEM_GENERAL**を与え、I/O用バッファサイズを計算する場合には**WOLFMEM_IO_FIXED**あるいは**WOLFMEM_IO_POOL**を指定してください。 + +``` +int wolfSSL_StaticBufferSz(byte* buffer, /* バッファアドレス */ + word32 sz, /* バッファサイズ */ + int flag); /* バッファの用途 */ +``` + +この関数を使って一般用と、I/O用に必要なバッファサイズを取得し、前述のwolfSSL_CTX_load_static_memory関数に渡してください。 + +一旦バッファサイズが決定したら、上記wolfSSL_StaticBufferSz関数は呼び出す必要はありませんので、製品コードから呼び出し部分をコメントアウトするか削除していただけます。 + +### 静的バッファ利用状況のトラッキング + +静的バッファ確保機能を利用する際に、バッファの確保、解放に関する使用状況を記録させることができます。この使用状況を記録する機能は静的バッファ確保機能にデフォルトで含まれていますからビルド時の有効化として別段のマクロ設定は必要ありません。機能の有効化は実行時に行います。 + +#### トラッキングの有効化 + +トラッキング機能の有効化は先に説明したwolfSSL_CTX_load_static_memory関数の第5引数に**WOLFMEM_TRACK_STATS**をORして指定します。wolfSSL内部に**WOLFSSL_MEM_CONN_STATS構造体**が確保されそこにメモリブロックの使用状況が記録されていきます。 + +``` +wolfssl/wolfcrypt/memory.h + +struct WOLFSSL_MEM_CONN_STATS { + word32 peakMem; /* メモリ使用量最大値(バイト数) */ + word32 curMem; /* 現在のメモリ使用量 */ + word32 peakAlloc; /* メモリ確保量最大値 */ + word32 curAlloc; /* 現在のメモリ確保数 */ + word32 totalAlloc;/* 累計メモリ確保回数 */ + word32 totalFr; /* 累計メモリ解放回数 */ +}; +``` + +#### メモリ使用状況の取得 + +トラッキングが有効になった時点からメモリブロックの使用状況は記録が有効となります。プログラム実行の任意の時点で次の関数を呼び出して、引数で渡したWOLFSSL_CTXあるいはWOLFSSLオブジェクトに静的バッファ確保機能が使用されているか否かを戻り値で返します。使用されている場合には戻り値として”1″を返します。さらに記録されているメモリの使用状況を取得することができます。 + +``` +int wolfSSL_CTX_is_static_memory(WOLFSSL_CTX* ctx, + WOLFSSL_MEM_STATS* mem_stats); + +int wolfSSL_is_static_memory(WOLFSSL* ssl, + WOLFSSL_MEM_STATS* mem_stats); +``` +上記関数の引数として渡したWOLFSSL_MEM_STATS構造体は: + +``` +struct WOLFSSL_MEM_STATS { + word32 curAlloc; /* 現在のメモリ確保数 */ + word32 totalAlloc;/* 累計メモリ確保回数 */ + word32 totalFr; /* 累計メモリ解放回数 */ + word32 totalUse; /* N/A */ + word32 avaIO; /* I/O用ブロックの空きブロック数 */ + word32 maxHa; /* 一般用に設定した最大コネクション数 */ + word32 maxIO; /* I/O用に設定した最大コネクション数 */ + word32 blockSz[WOLFMEM_MAX_BUCKETS]; /* ブロックサイズの配列 */ + word32 avaBlock[WOLFMEM_MAX_BUCKETS];/* 空きブロック数の配列 */ + word32 usedBlock[WOLFMEM_MAX_BUCKETS]; + int flag;   /* 静的メモリ管理機能に設定したフラグ(バッファ用途等) */ + }; +``` +この構造体に返却された値が呼び出した時点の静的バッファ管理状態を示します。この機能はメモリーリークの検出や無駄に多く割り当てたメモリブロック数の調査などに利用できます。 + +### 静的バッファ管理API + +ここで紹介する関数はwolfSSL_CTX_load_static_memory関数の第2引数に指定するWOLFSSL_METHOD構造体へのポインタを取得する為に使用する関数です。こららの関数はアプリケーションをTLSあるいはDTLSプロトコルのクライアントあるいはサーバーのいずれとして動作させるのかによって選択すべき関数が異なります。静的バッファ管理機能を使う際には必ず関数名の最後に”_ex”が付加された以下の関数を指定してください。こららの関数は”_ex”がつかない関数と機能は同じで、内部でWOLFSSL_METHOD構造体を有効になった静的バッファ管理機能を使って確保する点だけが異なります。各関数の詳細はwolfSSLマニュアルの”wolfSSL APIリファレンス>wolfSSLコンテクストの設定”を参照してください。 + +#### WOLFSSL_METHOD構造体を返す関数群 + +TLSクライアント用関数 + +- `wolfTLSv1_3_client_method_ex` +- `wolfTLSv1_2_client_method_ex` +- `wolfTLSv1_1_client_method_ex` +- `wolfSSLv23_client_method_ex` + +TLSサーバ用関数 + +- `wolfTLSv1_3_server_method_ex` +- `wolfTLSv1_2_server_method_ex` +- `wolfTLSv1_1_server_method_ex` +- `wolfSSLv23_server_method_ex` + +DTLSクライアント用関数 + +- `wolfDTLSv1_3_client_method_ex` +- `wolfTLSv1_2_client_method_ex` +- `wolfTLSv1_1_client_method_ex` +- `wolfSSLv23_client_method_ex` + +DTLSサーバ用関数 + +- `wolfDTLSv1_3_server_method_ex` +- `wolfTLSv1_2_server_method_ex` +- `wolfTLSv1_1_server_method_ex` +- `wolfSSLv23_server_method_ex` + +#### 静的バッファ管理機能 API + +APIリファレンス + + +|関数|機能| +|:---|:---| +|`wolfSSL_CTX_load_static_memory`|WOLFSSL_CTXに静的バッファ管理用のバッファを設定します。| +|`wolfSSL_CTX_is_static_memory`|静的バッファ管理が設定されているかと設定されている場合にはその使用状況を取得します。| +|`wolfSSL_is_static_memory`|静的バッファ管理が設定されているかと設定されている場合にはその使用状況を取得します。| +|[`wolfSSL_StaticBufferSz`](group__Memory.md#function-wolfssl_staticbuffersz)|静的バッファ管理で必要なバッファサイズを計算します。| + + + + + + + + + + + + + + + + ## 圧縮 diff --git a/wolfSSL/src/buckets.png b/wolfSSL/src/buckets.png new file mode 100644 index 00000000..875701cd Binary files /dev/null and b/wolfSSL/src/buckets.png differ diff --git a/wolfSSL/src/chapter04.md b/wolfSSL/src/chapter04.md index f7fdd31f..44e98e1c 100644 --- a/wolfSSL/src/chapter04.md +++ b/wolfSSL/src/chapter04.md @@ -540,6 +540,190 @@ Statistics collecting with the sniffer can be compiled in with defining the macr * `sslKeyMatches` * `sslEncryptedConns` +## Static Buffer Allocation Option + + +By default, wolfSSL assumes that the execution environment provides dynamic memory allocation, i.e., buffers can be allocated/freed with the malloc/free functions. The wolfCrypt cryptography library, which wolfSSL uses internally for underlying cryptography operations, can alternatively be configured to not use dynamic memory. This can be helpful for environments without dynamic memory support, or safety-critical applications where dynamic memory use is disallowed. + +### Basic Operation of Static Buffer Allocation + +“Dynamic memory allocation” is a management method that dynamically finds/allocates and provides a buffer of a “specified size (variable length)”. Buffer usage efficiency is high, but processing is relatively complicated. On the other hand, the “static buffer allocation” provided by wolfSSL is a memory management model that searches for a buffer close to the requested size from among several types of buffers prepared in advance (statically) and provides it back to the caller. A memory block larger than the requested size may be allocated and returned to the requester of the buffer (thus reducing the efficiency of use). Although not as precise in memory management, it is simple and simulates dynamic memory allocation that dynamically allocates a memory block of any size. + +Using static-buffer-allocation is equivalent in API to using dynamic memory with wolfSSL. This functional equivalency is achieved in wolfSSL by abstracting memory allocation/free into XMALLOC/XFREE function calls. Once static-buffer-allocation is set, wolfSSL will use it from then on to allocate buffers and other structures used internally. Since this feature is set for WOLFSSL_CTX, it will continue to work for the lifetime of the context object. + +The static-buffer-allocation set in a WOLFSSL_CTX is thread-safe. Even if the same WOLFSSL_CTX is shared by different threads, buffer allocation/free is used under exclusive control inside wolfSSL. +In comparison to a memory pool functionality offered by an RTOS implementation, memory functionality in an RTOS will commonly suspend a thread (task) if an unused memory block cannot be found when requested until a free block becomes available. wolfSSL’s static memory functionality has no such synchronization capability. + +### Specifying Static Buffer Use + +With static-buffer-allocation in wolfSSL, it is possible to divide memory between two purposes. It’s possible to allocate and free buffers separately between general purposes and I/O use cases. The buffer used for I/O is set relatively large (about 17KB) to accommodate the maximum TLS fragment size of up to 2^16 bytes. This is different from the buffer sizes for other general uses. Additionally, when setting the buffer configuration the user can limit the maximum number of WOLFSSL objects that can be created simultaneously. If the maximum number of WOLFSSL sessions is limited, each use of the wolfSSL_new() function will check the number of WOLFSSL objects that can be created and will error out if the limit is exceeded. + +### Enabling Static Buffer Allocation + +Enable the static-buffer-allocation option when building wolfSSL. For systems built using Autoconf, specify “--enable-staticmemory” as follows: + +``` +$ ./configure --enable-staticmemory +``` +Or if you are using a user_settings.h header, add the following macro definition: + +``` +user_settings.h + +  #define WOLFSSL_STATIC_MEMORY +``` + +The static-buffer-allocation option is implemented by default to additionally call the standard function malloc() without returning NULL when the memory block allocated from the given buffer is exhausted. If the environment does not provide dynamic memory management functionality, a link error will occur. Therefore, also define the **WOLFSSL_NO_MALLOC** macro to disable this feature if needed: + +``` +user_settings.h + +  #define WOLFSSL_STATIC_MEMORY + #define WOLFSSL_NO_MALLOC +``` + +### Using Static Buffer Allocation + +This can be helpful for environments without dynamic memory support, or safety-critical applications where dynamic memory use is disallowed. + +#### Static buffer setup function and its arguments + +This can be helpful for environments without dynamic memory support, or safety-critical applications where dynamic memory use is disallowed. + +``` + +int wolfSSL_CTX_load_static_memory( + WOLFSSL_CTX** ctx, /* address of the variable to hold WOLFSSL_CTX */ + wolfSSL_method_func method,/* method pointer */ + unsigned char* buf, /* pointer to the buffer to use as heap */ + unsigned int sz, /* buffer size */ + int flag, /* heap usage */ + int max); /* maximum number of objects allowed */ + +``` + +* parameter **ctx** specifies the address of a variable that receives a pointer to the generated WOLFSSL_CTX structure. + +* parameter **method** specifies a function pointer with "_ex", such as wolfSSLv23_client_method_ex(). The functions that can be used are listed in a later chapter. + +* parameter **buf** and **sz** specify the address and size of the buffer used for the heap, respectively. For information on determining the buffer size to be set, see “**Obtaining the Required Buffer Size**”. + +* parameter **flag** is a flag that specifies the usage of the buffer. You can also specify whether to track the allocation status. When specifying for general use, specify "**0**" or **WOLFMEM_GENERAL**. For I/O use, specify **WOLFMEM_IO_POOL** or **WOLFMEM_IO_POOL_FIXED**. When tracking the allocation status of static buffers, **OR** the value specifying the usage with **WOLFMEM_TRACK_STATS**. + +* parameter **max** is related to the use of the buffer specified by the argument flag. If the buffer is for general use, you may want to set the maximum number of WOLFSSL objects that can be generated simultaneously (the number of objects that can exist at the same time). Specify **0** if there is **no need to limit**. If you specify a limit value other than 0, subsequent calls to wolfSSL_new() will fail if the number of concurrent WOLFSSL objects created exceeds the set value. + +#### How to call the static buffer setup function + +When using the static-buffer-allocation option, call the wolfSSL_CTX_load_static_memory() function **twice**. The first sets up a buffer for general use, and then uses that buffer to allocate a WOLFSSL_CTX structure. The second call sets up the I/O buffer: + +``` +WOLFSSL_CTX* ctx = NULL; /* pass NULL to generate WOLFSSL_CTX */ +int ret; + +#define MAX_CONCURRENT_TLS 0 +#define MAX_CONCURRENT_IO 0 + +unsigned char GEN_MEM[GEN_MEM_SIZE]; +unsigned char IO_MEM[IO_MEM_SIZE];  + + /* set up a general-purpose buffer and generate WOLFSSL_CTX from it on the first call. */ + ret = wolfSSL_CTX_load_static_memory( + &ctx, /* set NULL to ctx */ + wolfSSLv23_client_method_ex(), /* use function with "_ex" */ + GEN_MEM, GEN_MEM_SIZE, /* buffer and its size */ + WOLFMEM_GENERAL, /* general purpose */ + MAX_CONCURRENT_TLS); /* max concurrent objects */ + + /* set up a I/O-purpose buffer on the second call. */ + ret = wolfSSL_CTX_load_static_memory( + &ctx, /* make sure ctx is holding the object */ + NULL, /* pass it to NULL this time */ + IO_MEM, IO_MEM_SIZE, /* buffer and its size */ + WOLFMEM_IO_FIXED, /* I/O purpose */ + MAX_CONCURRENT_IO); /* max concurrent objects */ + +``` + +After this, when you are done using the WOLFSSL_CTX structure, free it with the usual wolfSSL_CTX_free(). + +### Adjustment of Static Buffer Allocation + +The static-buffer-allocation option provided by wolfSSL manages the specified buffer by dividing it into multiple areas called "buckets" as shown in the following diagram. Multiple memory blocks of the same size are linked within a bucket. The figure below omits the structure that manages the memory block, but a buffer with a size that includes the omitted structure is required. + +![Alt text](buckets.png) + +#### Macros for General Use Buffers + +Each bucket varies in size depending on the number of memory blocks it contains and their size. + +The memory block size and number of blocks for each area to be used are defined in /wolfssl/wolfcrypt/memory.h with the following macros: + +``` +/wolfssl/wolfcrypt/memory.h + + #define WOLFSSL_STATIC_ALIGN 16 /* alignment 16 bytes by default*/ + #define WOLFMEM_MAX_BUCKETS 9  /* number of buckets */ +  #define WOLFMEM_IO_SZ 16992 /* buffer size for I/O */ + #define LARGEST_MEM_BUCKET 16128 /* the max block size */ + #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3456, + 4544,LARGEST_MEM_BUCKET + #define WOLFMEM_DIST 49,10,6,14,5,6,9,1,1 + +``` + +* **WOLFSSL_STATIC_ALIGN** specifies the buffer alignment size. 16 bytes by default. You need to change it according to the alignment size of your MCU. +* **WOLFMEM_MAX_BUCKETS** shows the number of buckets. This means using 9 different bucket sizes. +* **WOLFMEM_BUCKETS** specifies the number of bytes in blocks in each bucket, separated by commas, from smallest to largest. This definition applies to general purpose buffers. + +* **WOLFMEM_DIST** specifies the number of same-sized blocks in each bucket, separated by commas, corresponding to each block in WOLFMEM_BUCKETS. This definition applies to general purpose buffers. + +In the example above, a bucket with a block size of 64 bytes is the minimum size, and that bucket would have 49 memory blocks. The next larger bucket means 10 memory blocks with a block size of 128 bytes. The above defined values can be used as default values, but the size of each bucket and the number of memory blocks it contains may need to be adjusted when used in an actual environment. + +#### Macros for I/O Use Buffers + +For TLS client + +- `wolfTLSv1_3_client_method_ex` +- `wolfTLSv1_2_client_method_ex` +- `wolfTLSv1_1_client_method_ex` +- `wolfSSLv23_client_method_ex` + +For TLS server +- `wolfTLSv1_3_server_method_ex` +- `wolfTLSv1_2_server_method_ex` +- `wolfTLSv1_1_server_method_ex` +- `wolfSSLv23_server_method_ex` + +For DTLS client + +- `wolfDTLSv1_3_client_method_ex` +- `wolfTLSv1_2_client_method_ex` +- `wolfTLSv1_1_client_method_ex` +- `wolfSSLv23_client_method_ex` + +For DTLS server + +- `wolfDTLSv1_3_server_method_ex` +- `wolfTLSv1_2_server_method_ex` +- `wolfTLSv1_1_server_method_ex` +- `wolfSSLv23_server_method_ex` + +#### APIs for Static Buffer Allocation + + +|API|description| +|:---|:---| +|`wolfSSL_CTX_load_static_memory`|Set buffer for WOLFSSL_CTX as a heap memory. +|`wolfSSL_CTX_is_static_memory`|Returns whether "Static buffer Allocation" is used. If it is the case, gets usage report. +|`wolfSSL_is_static_memory`|Returns whether "Static buffer Allocation" is used. If it is the case, gets usage report. | +|[`wolfSSL_StaticBufferSz`](group__Memory.md#function-wolfssl_staticbuffersz)| Calculate required buffer size for "Static buffer Allocation" based on the macros defined in /wolfssl/wolfcrypt/memory.h. | + + + + + + + ## Compression wolfSSL supports data compression with the **zlib** library. The `./configure` build system detects the presence of this library, but if you're building in some other way define the constant `HAVE_LIBZ` and include the path to zlib.h for your includes.