Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion MbedTLS-Migration/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ SOURCES = chapter01.md \
chapter09.md \
chapter10.md

PDF = MbedTLS-wolfSSL-Migration-Guide.pdf
ifeq ($(DOC_LANG),JA)
PDF = MbedTLS-wolfSSL-Migration-Guide-jp.pdf
else
PDF = MbedTLS-wolfSSL-Migration-Guide.pdf
endif

.PHONY: html-prep
html-prep:
Expand Down
35 changes: 35 additions & 0 deletions MbedTLS-Migration/mkdocs-ja.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
site_name: Mbed TLS 移行ガイド
site_url: https://wolfssl.com/
docs_dir: build/html/
site_dir: html/
copyright: Copyright © 2026 wolfSSL Inc.
nav:
- "1. はじめに": index.md
- "2. 設計上の違い": chapter02.md
- "3. TLS クライアントの移植": chapter03.md
- "4. よくある落とし穴": chapter04.md
- "5. ハードウェアとプラットフォーム": chapter05.md
- "6. Mbed TLS にない機能": chapter06.md
- "7. はじめよう": chapter07.md
- "8. API 対応表": chapter08.md
- "9. 設定オプションの対応": chapter09.md
- "10. サポート": chapter10.md
theme:
name: null
custom_dir: ../mkdocs-material/material
language: ja
palette:
primary: indigo
accent: indigo
font:
text: Roboto
code: Roboto Mono
icon: "logo.png"
logo: logo.png
favicon: logo.png
feature:
tabs: true
extra_css: [skin.css]
extra:
generator: false
use_directory_urls: false
43 changes: 43 additions & 0 deletions MbedTLS-Migration/src-ja/chapter01.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# はじめに

本ガイドは、組み込み機器およびホスト上のアプリケーションを Mbed TLS から wolfSSL へ移行する開発者のためのものです。
移行に関わる主な設計上の違い、TLS クライアントの比較コード、実際の移行で頻繁に見られる落とし穴、そして API と設定の完全な対応表を収録しています。

## 対象読者

本ガイドは、Mbed TLS 3.6 または 4.x をベースにした製品を保守しており、wolfSSL への移行を計画・検討している C 言語開発者およびアーキテクトを対象としています。
現在お使いの製品で利用している Mbed TLS API についての知識を前提としています。

## 対象範囲

本ガイドは Mbed TLS 3.6 と 4.x の両方を対象とし、主に 4.x を基準として説明します。
TLS 層の API(`mbedtls_ssl_*`)は、暗号層に比べると 3.6 から 4.x への変更がはるかに少ないため、本ガイドの大部分は両バージョンに当てはまります。
両バージョンで異なる箇所については、本文中でその旨を明記しています。

本ガイドは TLS と DTLS を中心に扱います。
Mbed TLS や PSA Crypto の関数を直接呼び出しているコードは、ネイティブの wolfCrypt `wc_*` API へ移行することも、wolfPSA を介して wolfCrypt 上で PSA Crypto API をそのまま使い続けることもできます([Mbed TLS にない機能](chapter06.md)を参照)。

## Mbed TLS のサポート状況

2026年10月時点の状況は次のとおりです。

| ブランチ | 状況 |
| -------------------- | -------------------------------------------------------------------------------- |
| 2.28 LTS | サポート終了。最終リリースは 2.28.10(2025年3月)。 |
| 3.6 LTS | 2027年3月までメンテナンス。最新リリースは 3.6.7(2026年7月)。 |
| 4.0 | 最初の 4.x リリース(2025年10月)。暗号機能は TF-PSA-Crypto 1.0 として分離。 |
| 4.1 LTS | 2029年3月まで修正提供予定と発表。最新リリースは 4.1.1(2026年7月)。 |
| 4.2 | 現行のメインラインリリース(2026年7月)。TF-PSA-Crypto 1.2 を使用。 |

2026年10月、Mbed TLS チームは、現在のメンテナが 2027年4月に TLS および X.509 ライブラリの開発から離れることを[発表](https://lists.trustedfirmware.org/archives/list/mbed-tls@lists.trustedfirmware.org/thread/YPIGCB7WN6GCHOGEGKOJXUYAP7OK527W/)しました。
新たなメンテナが引き継がない限り、これらのライブラリのセキュリティ修正とリリースはその時点で終了し、4.1 LTS ブランチの TLS および X.509 部分も影響を受けます。
なお、暗号層である TF-PSA-Crypto は引き続き活発にメンテナンスされます。

## 本ガイドの使い方

1. [設計上の違い](chapter02.md)を読み、変わる概念を把握します。
2. [TLS クライアントの移植](chapter03.md)と [API 対応表](chapter08.md)を参照しながら、TLS の初期設定と I/O のコードを移植します。
3. [設定オプションの対応](chapter09.md)をチェックリストとして使い、Mbed TLS の設定で使用している機能を有効にして wolfSSL をビルドします。
4. 移植したコードを[よくある落とし穴](chapter04.md)と照らし合わせて確認します。
落とし穴の多くは、コンパイルは通るものの実行時に失敗するものです。
5. [はじめよう](chapter07.md)の説明に従い、既存の Mbed TLS の通信相手とのテストを行います。
50 changes: 50 additions & 0 deletions MbedTLS-Migration/src-ja/chapter02.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# 設計上の違い

本章では、Mbed TLS と wolfSSL の構造を比較し、以降の章で扱う移植作業の全体像を示します。

| 項目 | Mbed TLS | wolfSSL |
| ------------------ | ----------------------------------------- | ----------------------------------------- |
| コンテキストモデル | `mbedtls_ssl_config` と `mbedtls_ssl_context` | `WOLFSSL_CTX` と `WOLFSSL` |
| プロトコルとロール | `mbedtls_ssl_config_defaults()` の引数 | `wolfSSL_CTX_new()` に渡すメソッド |
| 暗号 API | レガシー API(3.6)または PSA(4.x) | ネイティブの wolfCrypt `wc_*` API、wolfPSA による PSA(オプション) |
| 乱数生成器(RNG) | アプリケーションが接続(3.6)、PSA 内部で管理(4.x) | セッションごとに内部で生成・シード |
| 設定 | `mbedtls_config.h`、`crypto_config.h` | `./configure`、CMake または `user_settings.h` |
| 戻り値 | 成功時 0、エラー時は負の値 | TLS 関数は `WOLFSSL_SUCCESS`(1)、`wc_*` 関数は 0 |
| トランスポート | `mbedtls_ssl_set_bio()` のコールバック | `wolfSSL_set_fd()` または I/O コールバック |
| ハードウェアオフロード | `_ALT`(3.6)または PSA ドライバ(4.x) | 暗号コールバックとツリー内のポート |
| ライセンス | Apache-2.0 または GPL-2.0-or-later | GPLv3 または商用ライセンス |

## 設定用に 1 つ、接続ごとに 1 つのコンテキスト

`mbedtls_ssl_config` は `WOLFSSL_CTX` に、`mbedtls_ssl_context` は `WOLFSSL` に置き換わります。
エンドポイント、トランスポート、プリセットを `mbedtls_ssl_config_defaults()` に渡す代わりに、`wolfSSL_CTX_new()` にメソッドを渡します。
`wolfTLS_client_method()` は双方がサポートする最も高い TLS バージョンをネゴシエートし、`wolfDTLSv1_3_client_method()` は DTLS 1.3 を選択します。
`WOLFSSL_CTX` は一度だけ設定してスレッド間で共有し、接続ごとに `WOLFSSL` を 1 つ作成します。

## RNG の接続処理は不要

wolfSSL では、3.6 の CTR-DRBG の接続処理も、4.x の `psa_crypto_init()` の呼び出しも必要ありません。
各 `WOLFSSL` は、プラットフォームのエントロピー源から自身の RNG をシードします。
ベアメタル環境では、`CUSTOM_RAND_GENERATE_SEED` または `wc_GenerateSeed()` の移植によってエントロピー源を一度だけ提供します。
これは `MBEDTLS_ENTROPY_HARDWARE_ALT` や `MBEDTLS_PSA_DRIVER_GET_ENTROPY` に相当するもので、wolfSSL はその上で Hash_DRBG を動作させます。
wolfCrypt を直接呼び出す場合、乱数を必要とする関数は明示的に `WC_RNG*` を引数に取ります。

## メモリフットプリント

Mbed TLS は、`MBEDTLS_SSL_IN_CONTENT_LEN` と `MBEDTLS_SSL_OUT_CONTENT_LEN` で縮小しない限り、デフォルトで接続ごとに 16 KB の入力バッファと 16 KB の出力バッファを確保します。
wolfSSL は各レコードを実際のサイズで割り当て、処理が終わると解放するため、ピーク使用量は受信する最大のレコードに応じて決まります。
ただし、双方が Max Fragment Length に合意しない限り、最大で 16 KB になる点は同じです。
`malloc()` を持たないシステム向けには、`--enable-staticmemory` により、すべてのメモリ割り当てをアプリケーションが用意したプールから行えます。

wolfSSL のブログ記事 2 本で、両ライブラリを計測しています。
[TLS 1.3 in 30.8 KB](https://www.wolfssl.com/tls-1-3-in-30-8-kb-wolfssl-vs-mbedtls/) では、Cortex-M33 上で wolfSSL のフラッシュ使用量が 5% から 44% 小さいという結果が得られました。
また、[同一条件でのベンチマーク](https://www.wolfssl.com/wolfssl-vs-mbedtls-an-apples-to-apples-benchmark-across-intel-arm-cortex-a-and-cortex-m-and-risc-v-targets/)では、Intel、ARM、RISC-V 上で wolfCrypt の公開鍵演算が数倍高速であることが確認されています。

## ライセンス

Mbed TLS は Apache-2.0 と GPL-2.0-or-later のデュアルライセンスです。
Apache-2.0 では、著作権表示などの要件を満たすだけでクローズドソースのファームウェアを出荷できます。
wolfSSL は GPLv3 と商用ライセンスのデュアルライセンスのため、クローズドソースのファームウェアの多くでは商用ライセンスが必要になります。
GPLv3 で回避できるケースはほとんどありません。
GPLv3 は、コンシューマ向け機器ではユーザーが改変したソフトウェアをインストールできることも求めますが、ロックダウンされたファームウェアでは通常それを許容できないためです。
エンジニアリング作業を始める前にライセンスの問題を解決できるよう、早めに wolfSSL までご相談ください。
145 changes: 145 additions & 0 deletions MbedTLS-Migration/src-ja/chapter03.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# TLS クライアントの移植

以下の 2 つの関数は、どちらも接続済みのソケット上で、CA ファイルを使ってサーバーを検証し、ホスト名を確認し、リクエストを送信して応答を読み取ります。
これらは Mbed TLS 4.1 と wolfSSL 5.9.4 でコンパイルし、それぞれ相手側ライブラリのテストサーバーに対して動作を確認しています。

## Mbed TLS 4.x

```c
#include <psa/crypto.h>
#include <mbedtls/ssl.h>
#include <mbedtls/net_sockets.h>
#include <mbedtls/x509_crt.h>

int tls_get(int fd, const char* host, const char* caFile)
{
int ret;
mbedtls_net_context net;
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
mbedtls_x509_crt ca;
unsigned char buf[256];
const char req[] = "GET / HTTP/1.0\r\n\r\n";

mbedtls_net_init(&net);
net.fd = fd;
mbedtls_ssl_init(&ssl);
mbedtls_ssl_config_init(&conf);
mbedtls_x509_crt_init(&ca);

ret = (int)psa_crypto_init(); /* 4.x: 証明書のパースより前に呼ぶ */
if (ret != PSA_SUCCESS)
goto out;
if ((ret = mbedtls_x509_crt_parse_file(&ca, caFile)) != 0)
goto out;
if ((ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
goto out;
mbedtls_ssl_conf_ca_chain(&conf, &ca, NULL);
/* 3.6 のみ: mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &drbg); */

if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0 ||
(ret = mbedtls_ssl_set_hostname(&ssl, host)) != 0)
goto out;
mbedtls_ssl_set_bio(&ssl, &net, mbedtls_net_send, mbedtls_net_recv, NULL);

while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE)
goto out;
}
ret = mbedtls_ssl_write(&ssl, (const unsigned char*)req, sizeof(req) - 1);
if (ret <= 0)
goto out;
do {
ret = mbedtls_ssl_read(&ssl, buf, sizeof(buf) - 1);
} while (ret == MBEDTLS_ERR_SSL_WANT_READ ||
ret == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET);
if (ret > 0)
ret = 0;
mbedtls_ssl_close_notify(&ssl);

out:
mbedtls_ssl_free(&ssl);
mbedtls_ssl_config_free(&conf);
mbedtls_x509_crt_free(&ca);
return ret;
}
```

## wolfSSL

```c
#include <wolfssl/options.h>
#include <wolfssl/ssl.h>
#include <string.h>

int tls_get(int fd, const char* host, const char* caFile)
{
int ret = -1;
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
char buf[256];
const char req[] = "GET / HTTP/1.0\r\n\r\n";

ctx = wolfSSL_CTX_new(wolfTLS_client_method()); /* TLS 1.2 または 1.3 */
if (ctx == NULL)
goto out;
if (wolfSSL_CTX_load_verify_locations(ctx, caFile, NULL)
!= WOLFSSL_SUCCESS)
goto out;
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);

ssl = wolfSSL_new(ctx);
if (ssl == NULL)
goto out;
if (wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME, host,
(unsigned short)strlen(host)) != WOLFSSL_SUCCESS ||
wolfSSL_check_domain_name(ssl, host) != WOLFSSL_SUCCESS ||
wolfSSL_set_fd(ssl, fd) != WOLFSSL_SUCCESS)
goto out;

ret = wolfSSL_connect(ssl);
if (ret != WOLFSSL_SUCCESS) {
ret = wolfSSL_get_error(ssl, ret);
goto out;
}
ret = wolfSSL_write(ssl, req, (int)sizeof(req) - 1);
if (ret <= 0) {
ret = wolfSSL_get_error(ssl, ret);
goto out;
}
ret = wolfSSL_read(ssl, buf, (int)sizeof(buf) - 1);
if (ret <= 0) {
ret = wolfSSL_get_error(ssl, ret);
goto out;
}
ret = 0;
wolfSSL_shutdown(ssl);

out:
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
return ret;
}
```

## 変更点

- RNG の設定と `psa_crypto_init()` は不要になります。
- `wolfSSL_CTX_load_verify_locations()` は 1 回の呼び出しで CA のパースと登録を行います。
また、`wolfSSL_CTX_set_verify()` によってピア検証を明示的に指定します([よくある落とし穴](chapter04.md)の「ピア検証は有効であり、有効のままにすべき」を参照)。
- ブロッキングソケットでは、`wolfSSL_connect()` がハンドシェイク全体を実行します。
ノンブロッキングソケットでは、`wolfSSL_get_error()` が `WOLFSSL_ERROR_WANT_READ` または `WOLFSSL_ERROR_WANT_WRITE` を返す間、再度呼び出します。
- `wolfSSL_UseSNI()` には SNI サポートが必要です。
`./configure` は x86 および aarch64 ホストでのみ SNI をデフォルトで有効にします。
組み込みターゲットでは、`--enable-sni` を指定してビルドするか、`HAVE_SNI` を定義してください。
- 読み取りループも不要になります。
4.0 以降の `mbedtls_ssl_read()` は、TLS 1.3 サーバーがチケットを送信するたびに `MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET` を返しますが、wolfSSL はチケットを内部で処理します。

失敗時、wolfSSL 版の関数は `wolfSSL_get_error()` のコードを返します。
その中には、ピアが接続を閉じたときの `WOLFSSL_ERROR_ZERO_RETURN` のように正の値もあります。
戻り値は `< 0` ではなく `!= 0` で判定してください。

`wolfSSL_Init()` は起動時に 1 回、`wolfSSL_Cleanup()` は終了時に 1 回だけ呼び出してください。
`wolfSSL_Cleanup()` はセッションキャッシュも解放するため、接続ごとに呼び出さないでください。
Loading
Loading