wolfSSL は、商用の TLS / 暗号ライブラリの中でも最も小さい部類に入ります。最大の課題は、どの設定項目を選ぶかです。本記事では、特に効果の大きい 10 の設定項目を簡単に紹介します。
ビルドを設定する 2 つの方法
以下で紹介する定義やフラグは、次のどちらの方法でも指定できます。
- Autoconf / configure(
./configure):--enable-X/--disable-XスイッチとCFLAGS="-DSOME_DEFINE"を./configureに渡します。選択内容はwolfssl/options.hに書き出され、settings.hがこれを自動的にインクルードします。デスクトップ、サーバー、組み込み Linux 向けのビルドでは、これが標準的な方法です WOLFSSL_USER_SETTINGS+user_settings.h:IDE プロジェクトやクロスコンパイルする MCU 向けのビルドでは、WOLFSSL_USER_SETTINGSをグローバルに定義し、すべてのビルドオプションを独自のuser_settings.hヘッダーに記述します。settings.hがこれを自動的にインクルードします。テンプレートの例はexamples/configs/を参照してください。autoconf と組み合わせる場合は、./configure --enable-usersettingsも使用できます
1. 設定テンプレートの活用
小さなビルドへの一番の近道は、全部入りのデフォルトから始めないことです。examples/configs/ には十数種類の既製プロファイルが用意されており、フットプリントの削減で特に重要なのは次の 2 つです。
user_settings_baremetal.h:ファイルシステムなし、静的メモリ、SINGLE_THREADED、WOLFSSL_USER_IO、WOLFSSL_SP_MATH、WOLFSSL_SP_SMALL、WOLFCRYPT_ONLY、ECC は P-256 のみ、AES-GCM、SHA-256、HKDF で、それ以外はすべて無効です。暗号機能だけを使うデバイスの出発点に適していますuser_settings_tinytls13.h:最小の TLS 1.3 プロファイルです。詳しくは項目 2 で説明します
いずれかを user_settings.h としてコピーし、--enable-usersettings でビルドすれば、以下の項目の大半はすでに有効になっています。
2. –enable-tinytls13:最小の TLS 1.3 フットプリント
--enable-tinytls13(または WOLFSSL_TINY_TLS13)は、settings.h 内で、最小かつ整合の取れた TLS 1.3 構成に展開される包括オプションです。その内容は、TLS 1.3 のみ、X25519 による PSK + ECDHE、AES-128-GCM、SHA-256、SP math small、ASN.1 と X.509 は一切なしで、さらに --enable-lowresource のバンドルも自動で有効になります。
この最小構成を超える機能はすべてオプトインで追加でき、カンマ区切りのサブオプション(--enable-tinytls13=cert,p256,sha384)または examples/configs/user_settings_tinytls13.h 内の定義で指定します。指定できるのは、cert(最小限の X.509 ECDSA P-256 検証)、mutualauth、rsaverify、p256、asm(small-C の代わりにアセンブリを使用)、sha384、mldsa(ML-DSA-44 の検証のみ)のほか、WOLFSSL_TINY_TLS13_SERVER と WOLFSSL_TINY_TLS13_STATIC_MEM です。
-Os -flto -Wl,--gc-sections を指定して Cortex-M4 で計測したところ、.text は PSK の最小構成で 35 KB、cert プロファイルで 73 KB でした。同じ機能セットを本記事のほかのすべての項目を使って手作業でチューニングした場合は 84 KB です。つまりこの包括オプションは、入念に手動チューニングしても削りきれない約 11 KB を削減でき、X.509 を完全に取り除けば削減量は約 50 KB になります。ただし、cert プロファイルは意図的にセキュリティを抑えた検証パス(名前制約なし、ASN.1 の緩和、CRL なし)であり、インターネット上の公開 PKI ではなく、既知の CA やピン留めした CA と組み合わせて使うことを想定しています。
3. WOLFCRYPT_ONLY:TLS 層の完全な除去
デバイスが暗号プリミティブだけを必要とする場合(ブートローダーの署名検証、セキュアストレージの暗号化、COSE / JWS 署名など)は、WOLFCRYPT_ONLY を定義するか、--enable-cryptonly を指定します。これにより、src/internal.c、src/ssl.c、TLS ステートマシン、暗号スイート関連の処理、TLS 1.2 / 1.3 のレコード層が完全に取り除かれます。
4. 単精度数学ライブラリ(SP math)への限定:WOLFSSL_SP_MATH + WOLFSSL_SP_SMALL
WOLFSSL_SP_MATH は、汎用の多倍長整数ライブラリ(sp_int.c / integer.c / tfm.c)を、実際に使用する鍵サイズ専用の固定長ルーチンに置き換えます。WOLFSSL_SP_SMALL は、アンロール版ではなく、コンパクトなループ版を選択します。暗号機能のみのビルドでは、これが最も効果の大きい設定です。configure では --enable-sp=small --enable-sp-math を指定します。
tinytls13 の包括オプションでは両方が自動で設定されるため、この項目は tinytls13 を使わないビルド向けです。
5. 非推奨・未使用のアルゴリズムと機能の無効化
./configure でビルドする場合、以下はデフォルトで無効です。しかし user_settings.h を使用する場合は無効になっていないため、手動で追加する必要があります。
#define NO_DES3
#define NO_MD5
#define NO_RC4
#define NO_DSA
#define NO_DH /* if you only use ECDHE */
#define NO_PWDBASED
#define NO_PKCS12
--enable-lowresource は、関連する小型化用の定義をまとめて有効にします。対象は RSA_LOW_MEM、CURVE25519_SMALL、ED25519_SMALL、GCM_SMALL、WOLFSSL_AES_SMALL_TABLES、WOLFSSL_AES_NO_UNROLL、USE_SLOW_SHA / USE_SLOW_SHA256 / USE_SLOW_SHA512、WOLFSSL_SMALL_CERT_VERIFY、WOLFSSL_NO_ASYNC_IO、NO_SESSION_CACHE で、合計すると通常 5〜15 KB の削減になります。user_settings_baremetal.h のインラインコメントには個々の削減量が記載されており、AES のアンロール無効化で約 2 KB、USE_SLOW_SHA256 で約 1 KB、WOLFSSL_AES_SMALL_TABLES で数 KB です。--enable-tinytls13 を使用すると、このバンドルは自動的に有効になります。
6. ECC 曲線と鍵サイズの絞り込み
wolfSSL はデフォルトで、すべての NIST 曲線と、一般的なすべての RSA / DH の鍵サイズをコンパイルします。ほとんどの製品で使うのはそのうち 1 つです。
#define ECC_USER_CURVES /* only P-256 enabled by default */
/* #define NO_ECC256 */
/* leave NO_ECC192 / NO_ECC224 / NO_ECC384 / NO_ECC521 in effect */
検証のみのパス(ブートローダーやイメージの認証処理)では、NO_ECC_SIGN、NO_ECC_DHE、NO_ECC_KEY_EXPORT を追加します。これにより検証処理は目に見えて小さくなります。RSA / DH も同様で、2048 ビットだけが必要なら WOLFSSL_SP_3072 と WOLFSSL_SP_4096 を未定義のままにしておけば、より大きな SP math のテーブルはコンパイルされません。
7. 出荷前の診断機能の無効化
DEBUG_WOLFSSL(--enable-debug)は、立ち上げ作業の後も有効のまま残されがちな設定の中で、最もコストの大きいものです。ベースラインのクライアントでは、.text が 21.8 KB 増加しました(86,249 B から 108,097 B)。このうち wolfSSL のロギングコードとフォーマット文字列は約 15.5 KB にすぎず、残りの約 6.3 KB は printf 関連の処理で、本来なら stdio をまったくリンクしないイメージにまで取り込まれてしまいます。現場でログが必要な場合は、stdio のコストを払うのではなく、wolfSSL_SetLoggingCb() や WOLFSSL_USER_LOG / WOLFSSL_DEBUG_PRINTF_FN で独自の出力先に送ってください。
これと対になるのが NO_ERROR_STRINGS(--disable-errorstrings)で、人が読むためのエラーテキストを収めた 12.4 KB のテーブルを取り除きます。ただし --gc-sections を使用している場合、エラー文字列を一切フォーマットしないビルドでは、このテーブルはすでに破棄されています(筆者の検証環境では、この定義による削減は 88 バイトでした)。効果を発揮するのは、--gc-sections で未使用セクションを削除していない場合や、アプリケーションが実際にエラー文字列 API を呼び出す場合です。出荷前には、マップファイルを vfprintf と wc_ErrorString で grep して確認してください。
8. コンパイラとリンカーのフラグ
ツールチェーンは configure のフラグと同じくらい重要です。
CFLAGS += -Os -ffunction-sections -fdata-sections
LDFLAGS += -Wl,--gc-sections -flto
-Os を使うと、Cortex-M では通常、-O2 よりさらに 5〜10% 小さくなります。--gc-sections は、.o ファイル全体を取り込むのではなく、参照されていない関数とデータを取り除きます。-flto は翻訳単位をまたいでインライン化を判断し、さらに数パーセント削減します。これらは wolfSSL の定義とは無関係で、リンクするほかのすべてのライブラリにも効果があります。
項目 2 の数値はデッドコードを除去した LTO リンクで得たものなので、再現にはこれらのフラグが欠かせません。
9. オンチップの暗号アクセラレーターの活用
MCU に AES / HASH / RNG のペリフェラルがある場合、wolfCrypt の処理をそこに回すことで、ソフトウェア実装がリンクから外れます。STM32 では、WOLFSSL_STM32_BARE(レジスタを直接操作)または WOLFSSL_STM32_CUBEMX(HAL)に加えて、STM32_CRYPTO / STM32_HASH / STM32_RNG / WOLFSSL_STM32_PKA を使用します。計測では、検証環境を純粋なソフトウェア実装に戻すと、最終イメージが約 37 KB 増加しました。同じ考え方は、Arm v8-M の暗号拡張、NXP CAU/MMCAU、Microchip ATECC などにも当てはまります。
10. 手作業による TLS コードの削減
TLS を残す必要があり、かつ tinytls13 が合わない場合(TLS 1.2、完全な X.509 パス、またはプロファイル外の機能が必要な場合)は、ハンドシェイクのステートマシンと X.509 / ASN.1 まわりを手作業で削ります。
#define WOLFSSL_NO_CLIENT /* server-only build */
#define WOLFSSL_NO_SERVER /* client-only build (mutually exclusive) */
#define NO_OLD_TLS /* drop TLS 1.0 / 1.1 */
#define WOLFSSL_NO_TLS12 /* TLS 1.3 only */
#define WOLFSSL_AEAD_ONLY /* AEAD cipher suites only */
#define NO_SESSION_CACHE
WOLFSSL_NO_CLIENT / WOLFSSL_NO_SERVER は、製品に含めない側のハンドシェイク処理を取り除きます。WOLFSSL_NO_TLS12 + NO_OLD_TLS で TLS 1.3 のみが残り、レコード層が最小になります。通信の両端で事前共有鍵を使用する場合は、NO_CERTS / NO_ASN で証明書チェーンの処理を取り除けます。
tinytls13 の包括オプションはこれらをすべて設定したうえで、さらに約 11 KB 削減します。
まとめ
| 設定項目 | 削減量 |
|---|---|
--enable-tinytls13(同等の手動チューニングとの比較) | 最終イメージで約 11 KB(X.509 を除去できれば約 50 KB) |
WOLFSSL_SP_SMALL | libwolfssl.a で約 130 KB |
NO_RSA + NO_DH + NO_DES3 | libwolfssl.a で約 62 KB |
DEBUG_WOLFSSL の有効化(無効化し忘れ) | 最終イメージで約 22 KB |
| オンチップ暗号オフロード | 最終イメージで約 37 KB |
--enable-lowresource バンドル | 約 5〜15 KB |
ECC_USER_CURVES + NO_ECC_SIGN、WOLFSSL_SMALL_STACK、NO_FILESYSTEM、TLS の削減 | 上記の各項目に含まれる |
コンパイラの -Os + --gc-sections + -flto | ツールチェーンに依存。通常はさらに 5〜15% |
TLS 1.3 を使用し、通信の両端を管理できる場合は、--enable-tinytls13 から始めて、必要なものだけを追加してください。TLS をまったく使用しない場合は、WOLFCRYPT_ONLY と user_settings_baremetal.h から始めてください。いずれの場合も、まずはテンプレートに目を通すことをおすすめします。上記のフラグは、どれも 1 行追加するだけで設定できます。
ベンチマークを行う際は、BENCH_EMBEDDED を指定してビルドし、テストハーネスが大きなブロックサイズを使わないようにしてください。
今すぐ wolfSSL をダウンロード
もし弊社製品についてご質問があれば、お問い合わせ窓口info@wolfssl.jpまでご連絡をお願い致します。
原文:https://www.wolfssl.com/top-10-things-to-reduce-wolfssl-code-size/