From 26562f4fd167cfc51ecaf5d0f1f40c45489bbbd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Frauenschl=C3=A4ger?= Date: Wed, 21 Oct 2026 08:54:10 +0200 Subject: [PATCH] Add Mbed TLS to wolfSSL migration guide New manual for porting products from Mbed TLS 3.6 and 4.x to wolfSSL: design differences, a side-by-side TLS client, common pitfalls, hardware and platform notes (crypto callbacks, Zephyr, ESP-IDF), features beyond Mbed TLS, interop testing, and full API and configuration mappings. Built with `make mbedtls-migration`, modelled on the Bouncy Castle migration guide. header.txt allows line breaks after underscores and the tables set explicit column widths, so long identifiers in the API tables wrap instead of overlapping the next column in the PDF. Two notes are temporary and should be dropped once the fixes are in a release: the session-ticket row in the configuration chapter (--enable-ticket-nonce-malloc for TLS 1.3 against Mbed TLS servers, wolfSSL/wolfssl#11745), and the ML-KEM decapsulation note in the hardware chapter (device-held keys, wolfSSL/wolfssl#11773, not in 5.9.4). --- Makefile | 8 +- MbedTLS-Migration/Makefile | 23 ++++ MbedTLS-Migration/header.txt | 27 +++++ MbedTLS-Migration/mkdocs.yml | 35 ++++++ MbedTLS-Migration/src/chapter01.md | 55 ++++++++++ MbedTLS-Migration/src/chapter02.md | 63 +++++++++++ MbedTLS-Migration/src/chapter03.md | 152 ++++++++++++++++++++++++++ MbedTLS-Migration/src/chapter04.md | 83 ++++++++++++++ MbedTLS-Migration/src/chapter05.md | 94 ++++++++++++++++ MbedTLS-Migration/src/chapter06.md | 81 ++++++++++++++ MbedTLS-Migration/src/chapter07.md | 41 +++++++ MbedTLS-Migration/src/chapter08.md | 86 +++++++++++++++ MbedTLS-Migration/src/chapter09.md | 38 +++++++ MbedTLS-Migration/src/chapter10.md | 40 +++++++ MbedTLS-Migration/test/linkcheck.json | 7 ++ MbedTLS-Migration/test/lintcheck.json | 4 + README.md | 1 + 17 files changed, 837 insertions(+), 1 deletion(-) create mode 100644 MbedTLS-Migration/Makefile create mode 100644 MbedTLS-Migration/header.txt create mode 100644 MbedTLS-Migration/mkdocs.yml create mode 100644 MbedTLS-Migration/src/chapter01.md create mode 100644 MbedTLS-Migration/src/chapter02.md create mode 100644 MbedTLS-Migration/src/chapter03.md create mode 100644 MbedTLS-Migration/src/chapter04.md create mode 100644 MbedTLS-Migration/src/chapter05.md create mode 100644 MbedTLS-Migration/src/chapter06.md create mode 100644 MbedTLS-Migration/src/chapter07.md create mode 100644 MbedTLS-Migration/src/chapter08.md create mode 100644 MbedTLS-Migration/src/chapter09.md create mode 100644 MbedTLS-Migration/src/chapter10.md create mode 100644 MbedTLS-Migration/test/linkcheck.json create mode 100644 MbedTLS-Migration/test/lintcheck.json diff --git a/Makefile b/Makefile index f04c6983..413121a1 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ WOLFCOSE_REF ?= main WOLFTPM_REF ?= master DOCKER_CMD=DOCKER_BUILDKIT=1 docker build $(DOCKER_CMD_EXTRA_ARGS) -t doc_build --build-arg MANPATH=$(MANPATH) --build-arg PDFFILE=$(PDFFILE) --build-arg V=$(V) --build-arg WOLFCOSE_REF=$(WOLFCOSE_REF) --build-arg WOLFTPM_REF=$(WOLFTPM_REF) --target=manual --output=build -f Dockerfile . -all: wolfssl wolfssh wolfboot wolfclu wolfcrypt-jni wolfmqtt wolfsentry wolfssl-jni wolftpm wolfhsm wolfcose wolfengine wolfprovider fips-ready tuning porting faq fips-faq bc-migration +all: wolfssl wolfssh wolfboot wolfclu wolfcrypt-jni wolfmqtt wolfsentry wolfssl-jni wolftpm wolfhsm wolfcose wolfengine wolfprovider fips-ready tuning porting faq fips-faq bc-migration mbedtls-migration build: $(Q)mkdir -p build @@ -134,5 +134,11 @@ bc-migration: PDFFILE=BouncyCastle-wolfSSL-Migration-Guide.pdf bc-migration: build $(Q)$(DOCKER_CMD) +.PHONY: mbedtls-migration +mbedtls-migration: MANPATH=MbedTLS-Migration +mbedtls-migration: PDFFILE=MbedTLS-wolfSSL-Migration-Guide.pdf +mbedtls-migration: build + $(Q)$(DOCKER_CMD) + clean: $(Q)rm -rf build diff --git a/MbedTLS-Migration/Makefile b/MbedTLS-Migration/Makefile new file mode 100644 index 00000000..3beca745 --- /dev/null +++ b/MbedTLS-Migration/Makefile @@ -0,0 +1,23 @@ +-include ../common/common.am +.DEFAULT_GOAL := all +all: pdf html + + +SOURCES = chapter01.md \ + chapter02.md \ + chapter03.md \ + chapter04.md \ + chapter05.md \ + chapter06.md \ + chapter07.md \ + chapter08.md \ + chapter09.md \ + chapter10.md + +PDF = MbedTLS-wolfSSL-Migration-Guide.pdf + +.PHONY: html-prep +html-prep: + +.PHONY: pdf-prep +pdf-prep: diff --git a/MbedTLS-Migration/header.txt b/MbedTLS-Migration/header.txt new file mode 100644 index 00000000..fc7c42ab --- /dev/null +++ b/MbedTLS-Migration/header.txt @@ -0,0 +1,27 @@ +% Mbed TLS Migration Guide ![](logo.png) + +--- +header-includes: + # Blank pages on new sections + - \usepackage{titlesec} + - \newcommand{\sectionbreak}{\clearpage} + # Fancy page headers + - \usepackage{fancyhdr} + - \pagestyle{fancy} + - \fancyfoot[LO,RE]{COPYRIGHT \copyright 2026 wolfSSL Inc.} + # Wrap long syntax highlighting code blocks + - \usepackage{fvextra} + - \DefineVerbatimEnvironment{Highlighting}{Verbatim}{breaklines,commandchars=\\\{\}} + # Wrap long non-syntax highlighted code blocks + - \usepackage{listings} + - \let\verbatim\undefined + - \let\verbatimend\undefined + - \lstnewenvironment{verbatim}{\lstset{breaklines,basicstyle=\ttfamily}}{} + # Allow line breaks after underscores in long identifiers + - \let\oldunderscore\_ + - \renewcommand{\_}{\oldunderscore\allowbreak} +# Keep monospace identifiers and options from being hyphenated +monofontoptions: + - HyphenChar=None +subparagraph: yes +--- diff --git a/MbedTLS-Migration/mkdocs.yml b/MbedTLS-Migration/mkdocs.yml new file mode 100644 index 00000000..7a3b3e4b --- /dev/null +++ b/MbedTLS-Migration/mkdocs.yml @@ -0,0 +1,35 @@ +site_name: Mbed TLS Migration Guide +site_url: https://wolfssl.com/ +docs_dir: build/html/ +site_dir: html/ +copyright: Copyright © 2026 wolfSSL Inc. +nav: + - "1. Introduction": index.md + - "2. Design Differences": chapter02.md + - "3. Porting a TLS Client": chapter03.md + - "4. Common Pitfalls": chapter04.md + - "5. Hardware and Platforms": chapter05.md + - "6. Features Beyond Mbed TLS": chapter06.md + - "7. Getting Started": chapter07.md + - "8. API Mapping": chapter08.md + - "9. Configuration Equivalents": chapter09.md + - "10. Support": chapter10.md +theme: + name: null + custom_dir: ../mkdocs-material/material + language: en + 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 diff --git a/MbedTLS-Migration/src/chapter01.md b/MbedTLS-Migration/src/chapter01.md new file mode 100644 index 00000000..16b097f4 --- /dev/null +++ b/MbedTLS-Migration/src/chapter01.md @@ -0,0 +1,55 @@ +# Introduction + +This guide helps developers move embedded and host applications from Mbed TLS +to wolfSSL. It covers the design differences that matter, a side-by-side TLS +client, the pitfalls seen most often in real migrations, and full API and +configuration mappings. + +## Audience + +This guide is for C developers and architects who maintain a product built on +Mbed TLS 3.6 or 4.x and are planning or evaluating a move to wolfSSL. It +assumes you know the Mbed TLS API your product uses today. + +## Scope + +The guide covers both Mbed TLS 3.6 and 4.x, with 4.x as the primary reference. +The TLS-layer calls (`mbedtls_ssl_*`) changed much less between 3.6 and 4.x +than the crypto layer did, so most of the guide applies to both. Where the two +versions differ, the text says so. + +The guide focuses on TLS and DTLS. Code that calls Mbed TLS or PSA crypto +functions directly can move to the native wolfCrypt `wc_*` API, or keep the +PSA Crypto API on top of wolfCrypt through wolfPSA (see +[Features Beyond Mbed TLS](chapter06.md)). + +## Mbed TLS Support Status + +As of October 2026: + +| Branch | Status | +| -------------------- | -------------------------------------------------------------------------------- | +| 2.28 LTS | End of life. The last release was 2.28.10 (March 2025). | +| 3.6 LTS | Maintained until March 2027. Latest release 3.6.7 (July 2026). | +| 4.0 | First 4.x release (October 2025), with crypto split out into TF-PSA-Crypto 1.0. | +| 4.1 LTS | Announced with fixes until March 2029. Latest release 4.1.1 (July 2026). | +| 4.2 | Current mainline release (July 2026), with TF-PSA-Crypto 1.2. | + +In October 2026 the Mbed TLS team +[announced](https://lists.trustedfirmware.org/archives/list/mbed-tls@lists.trustedfirmware.org/thread/YPIGCB7WN6GCHOGEGKOJXUYAP7OK527W/) +that its current maintainers will stop working on the TLS and X.509 libraries +in April 2027. Unless new maintainers take over, security fixes and releases +for those libraries end then, which also affects the TLS and X.509 part of the +4.1 LTS branch. The crypto layer, TF-PSA-Crypto, stays actively maintained. + +## How to Use This Guide + +1. Read [Design Differences](chapter02.md) for the concepts that change. +2. Port your TLS setup and I/O code using + [Porting a TLS Client](chapter03.md) and the [API Mapping](chapter08.md). +3. Build wolfSSL with the features your Mbed TLS configuration uses, using + [Configuration Equivalents](chapter09.md) as a checklist. +4. Check your port against [Common Pitfalls](chapter04.md). Most of them + compile fine and fail at runtime. +5. Test against your existing Mbed TLS peers, as described in + [Getting Started](chapter07.md). diff --git a/MbedTLS-Migration/src/chapter02.md b/MbedTLS-Migration/src/chapter02.md new file mode 100644 index 00000000..b2c5f3f2 --- /dev/null +++ b/MbedTLS-Migration/src/chapter02.md @@ -0,0 +1,63 @@ +# Design Differences + +This chapter compares how Mbed TLS and wolfSSL are structured, to frame the +porting work in the following chapters. + +| Topic | Mbed TLS | wolfSSL | +| ------------------ | ----------------------------------------- | ----------------------------------------- | +| Context model | `mbedtls_ssl_config` plus `mbedtls_ssl_context` | `WOLFSSL_CTX` plus `WOLFSSL` | +| Protocol and role | `mbedtls_ssl_config_defaults()` arguments | The method passed to `wolfSSL_CTX_new()` | +| Crypto API | Legacy (3.6) or PSA (4.x) | Native wolfCrypt `wc_*` API, optional PSA via wolfPSA | +| RNG | Wired up by the application (3.6), internal to PSA (4.x) | Created and seeded internally per session | +| Configuration | `mbedtls_config.h`, `crypto_config.h` | `./configure`, CMake or `user_settings.h` | +| Return codes | 0 on success, negative error | `WOLFSSL_SUCCESS` (1) for TLS calls, 0 for `wc_*` calls | +| Transport | `mbedtls_ssl_set_bio()` callbacks | `wolfSSL_set_fd()` or I/O callbacks | +| Hardware offload | `_ALT` (3.6) or PSA drivers (4.x) | Crypto callbacks plus in-tree ports | +| License | Apache-2.0 or GPL-2.0-or-later | GPLv3 or commercial | + +## One Context for Configuration, One per Connection + +An `mbedtls_ssl_config` becomes a `WOLFSSL_CTX`, and an `mbedtls_ssl_context` +becomes a `WOLFSSL`. Instead of passing endpoint, transport and preset to +`mbedtls_ssl_config_defaults()`, you pass a method to `wolfSSL_CTX_new()`: +`wolfTLS_client_method()` negotiates the highest TLS version both sides +support, and `wolfDTLSv1_3_client_method()` selects DTLS 1.3. Configure the +`WOLFSSL_CTX` once, share it across threads, and create one `WOLFSSL` per +connection. + +## No RNG Plumbing + +wolfSSL needs neither the 3.6 CTR-DRBG wiring nor the 4.x `psa_crypto_init()` +call: every `WOLFSSL` seeds its own RNG from the platform entropy source. On +bare metal you provide that source once, through `CUSTOM_RAND_GENERATE_SEED` +or a `wc_GenerateSeed()` port, the counterpart of +`MBEDTLS_ENTROPY_HARDWARE_ALT` or `MBEDTLS_PSA_DRIVER_GET_ENTROPY`, and wolfSSL +runs its Hash_DRBG on top. When you call wolfCrypt directly, functions that +need randomness take an explicit `WC_RNG*`. + +## Memory Footprint + +Mbed TLS reserves a 16 KB input and a 16 KB output buffer per connection by +default, unless you shrink them with `MBEDTLS_SSL_IN_CONTENT_LEN` and +`MBEDTLS_SSL_OUT_CONTENT_LEN`. wolfSSL allocates each record at its actual size +and frees it once processed, so peak use follows the largest record you see, +still up to 16 KB unless both sides agree on Max Fragment Length. For systems +without `malloc()`, `--enable-staticmemory` serves every allocation from pools +you provide. + +Two wolfSSL blog posts measured both libraries: +[TLS 1.3 in 30.8 KB](https://www.wolfssl.com/tls-1-3-in-30-8-kb-wolfssl-vs-mbedtls/) +found wolfSSL 5% to 44% smaller in flash on a Cortex-M33, and +[an apples-to-apples benchmark](https://www.wolfssl.com/wolfssl-vs-mbedtls-an-apples-to-apples-benchmark-across-intel-arm-cortex-a-and-cortex-m-and-risc-v-targets/) +found wolfCrypt's public-key operations several times faster on Intel, ARM and +RISC-V. + +## Licensing + +Mbed TLS is dual licensed under Apache-2.0 and GPL-2.0-or-later. Apache-2.0 lets +you ship closed-source firmware with only notice requirements. wolfSSL is dual +licensed under GPLv3 and a commercial license, so most closed-source firmware +needs a commercial license. GPLv3 is rarely a way around it: for consumer +devices it also requires that users can install modified software, which +locked-down firmware usually cannot allow. Contact wolfSSL early, so licensing +is settled before engineering starts. diff --git a/MbedTLS-Migration/src/chapter03.md b/MbedTLS-Migration/src/chapter03.md new file mode 100644 index 00000000..63b71bb2 --- /dev/null +++ b/MbedTLS-Migration/src/chapter03.md @@ -0,0 +1,152 @@ +# Porting a TLS Client + +Both functions below verify the server against a CA file, check its host name, +send a request and read the reply over an already connected socket. They were +compiled against Mbed TLS 4.1 and wolfSSL 5.9.4, and each was run against the +other library's test server. + +## Mbed TLS 4.x + +```c +#include +#include +#include +#include + +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: before any parsing */ + 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 only: 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 +#include +#include + +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 or 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; +} +``` + +## What Changed + +- The RNG setup and `psa_crypto_init()` are gone. +- `wolfSSL_CTX_load_verify_locations()` parses and installs the CA in one call, + and `wolfSSL_CTX_set_verify()` makes peer verification explicit (see + "Peer Verification Is On, and Should Stay On" in + [Common Pitfalls](chapter04.md)). +- `wolfSSL_connect()` drives the whole handshake on a blocking socket. With a + non-blocking one, call it again while `wolfSSL_get_error()` returns + `WOLFSSL_ERROR_WANT_READ` or `WOLFSSL_ERROR_WANT_WRITE`. +- `wolfSSL_UseSNI()` needs SNI support, which `./configure` enables by + default only on x86 and aarch64 hosts. On embedded targets, build with + `--enable-sni` or define `HAVE_SNI`. +- The read loop is gone too. Since 4.0, `mbedtls_ssl_read()` returns + `MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET` whenever a TLS 1.3 server sends + a ticket, while wolfSSL handles tickets internally. + +On failure the wolfSSL version returns a `wolfSSL_get_error()` code, and some +of those are positive, such as `WOLFSSL_ERROR_ZERO_RETURN` when the peer closed +the connection. Check the result with `!= 0` rather than `< 0`. + +Call `wolfSSL_Init()` once at startup and `wolfSSL_Cleanup()` once at shutdown, +not around each connection, because `wolfSSL_Cleanup()` also frees the session +cache. diff --git a/MbedTLS-Migration/src/chapter04.md b/MbedTLS-Migration/src/chapter04.md new file mode 100644 index 00000000..53aa4ec3 --- /dev/null +++ b/MbedTLS-Migration/src/chapter04.md @@ -0,0 +1,83 @@ +# Common Pitfalls + +These are the issues seen most often when porting from Mbed TLS. Most of them +compile fine and fail at runtime. + +## Host Name Checks Need Their Own Call + +`mbedtls_ssl_set_hostname()` sends SNI and checks the server certificate +against the name. In wolfSSL, `wolfSSL_UseSNI()` only sends the extension and +`wolfSSL_check_domain_name()` enables the name check, so call both, as the +sample in [Porting a TLS Client](chapter03.md) does. Without the second call, +any certificate from a trusted CA is accepted for any host, a check Mbed TLS +3.6.3 and later enforce. Since wolfSSL 5.9.2, `wolfSSL_check_domain_name()` +accepts only fully qualified names and `localhost`, and returns +`WOLFSSL_FAILURE` for a single-label name such as `gateway` or an IP address, +where `mbedtls_ssl_set_hostname()` takes any name; use the fully qualified +name. For IP addresses, call `wolfSSL_check_ip_address()` and build with +`--enable-ip-alt-name`, or the handshake fails with `IPADDR_MISMATCH`. + +## Success Is 1, Not 0 + +Most `wolfSSL_*` configuration and handshake calls return `WOLFSSL_SUCCESS`, +which is 1. Code ported with `if (ret != 0)` checks will treat every success as +an error, or worse, every failure (`WOLFSSL_FAILURE` is 0) as success. +wolfCrypt's `wc_*` functions follow the Mbed TLS convention of 0 on success. +`wolfSSL_read()` and `wolfSSL_write()` return a byte count, and on failure +`wolfSSL_get_error(ssl, ret)` tells you why. + +## Build the Library and the Application with the Same Defines + +Many wolfSSL structures change size with the feature set, so a mismatch +between library and application compiles, links and then corrupts memory. +Include `` before any other wolfSSL header, or with +`user_settings.h`, define `WOLFSSL_USER_SETTINGS` for both and share one copy +of the file. + +## Defaults Differ + +A default `./configure` build is lean. Several features Mbed TLS enables by +default need an explicit option, among them SNI on embedded targets, +Curve25519, ALPN, session tickets, DTLS, DTLS Connection ID, PSK, AES-CCM (for +the CoAP and LwM2M `_CCM_8` suites) and Max Fragment Length. If a call returns +`NOT_COMPILED_IN` or does not exist, [Configuration Equivalents](chapter09.md) +has the option. + +## Peer Verification Is On, and Should Stay On + +In a default build, a wolfSSL client verifies the server, like Mbed TLS. +Builds with OpenSSL-compatible defaults, such as `--enable-all` or +`--enable-nginx`, start with `WOLFSSL_VERIFY_NONE` instead, so call +`wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL)` in every client. If +the CA is missing, the handshake fails with `ASN_NO_SIGNER_E` (-188); load the +right CA rather than turning verification off. On a server, add +`WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT` to match `MBEDTLS_SSL_VERIFY_REQUIRED`. +For `MBEDTLS_SSL_VERIFY_OPTIONAL`, use a verify callback that records the +error and returns 1. + +## Custom I/O Callbacks Use Different Return Codes + +Custom transport callbacks port almost one to one, with the signature +`int recv(WOLFSSL* ssl, char* buf, int sz, void* ctx)` and the matching send. +Return `WOLFSSL_CBIO_ERR_WANT_READ` or `WOLFSSL_CBIO_ERR_WANT_WRITE` instead of +the Mbed TLS codes, `WOLFSSL_CBIO_ERR_CONN_CLOSE` when the peer closed the +connection, and, for DTLS, `WOLFSSL_CBIO_ERR_TIMEOUT` when a timer expires. +wolfSSL treats an Mbed TLS code as a fatal error. + +## PEM and DER Buffers + +Mbed TLS expects a PEM buffer's length to include the terminating NUL byte. +The wolfSSL `*_buffer()` functions accept that length as well, so your buffers +work unchanged. The difference is the format: Mbed TLS detects PEM or DER from +the content, while wolfSSL takes `WOLFSSL_FILETYPE_PEM` or +`WOLFSSL_FILETYPE_ASN1` as an argument, and a DER buffer passed as PEM fails +with `ASN_NO_PEM_HEADER` (-162). + +## Certificate Dates on Boards Without a Clock + +Mbed TLS built without `MBEDTLS_HAVE_TIME_DATE` silently skips the validity +period check. wolfSSL always checks it, so a board with no clock fails the +handshake with `ASN_BEFORE_DATE_E` or `ASN_AFTER_DATE_E`. Provide the time with +`USER_TIME` or `TIME_OVERRIDES` (`XTIME()`), or define `NO_ASN_TIME` to skip the +check knowingly. `NO_ASN_TIME` also disables the session cache and session +tickets, so session resumption is gone too. diff --git a/MbedTLS-Migration/src/chapter05.md b/MbedTLS-Migration/src/chapter05.md new file mode 100644 index 00000000..20b6f12b --- /dev/null +++ b/MbedTLS-Migration/src/chapter05.md @@ -0,0 +1,94 @@ +# Hardware and Platforms + +## Hardware Acceleration + +wolfSSL ships more than 30 hardware and platform ports in `wolfcrypt/src/port/` +(NXP, ST, Renesas, Microchip, Cypress PSoC 6, Silicon Labs, Espressif, Xilinx, +Intel QuickAssist and more), plus hand-optimized assembly for Intel AES-NI/AVX, +ARMv8 and RISC-V. Check that directory for your part before writing a driver. + +## Crypto Callbacks + +For hardware without an in-tree port, the crypto callback interface +(`--enable-cryptocb`) is the one hook you implement. Compared with the +alternatives in Mbed TLS: + +- Crypto `_ALT` macros (3.6) replace a software implementation at compile + time, for every caller. They are gone in 4.x. +- PSA drivers (4.x) follow a specification still marked beta. Only part of the + dispatch layer is code-generated, and the rest is wired up by hand. +- wolfSSL crypto callbacks are registered at runtime under a device ID that an + object or a whole TLS context opts into. A callback returns + `CRYPTOCB_UNAVAILABLE` to fall back to software, and the interface covers + hashes, ciphers, MACs, RNG and the classic and post-quantum public-key + algorithms, so a secure element or HSM can take over ML-KEM or ML-DSA as + well. ML-KEM decapsulation with a key held only by the device needs a wolfSSL + release after 5.9.4. + +Offloading ECDSA signing for every TLS connection on a context looks like +this: + +```c +#include +#include +#include + +#define MY_HW_DEVID 0x48570001 + +int my_hw_ecdsa_sign(const byte* hash, word32 hashSz, byte* sig, + word32* sigSz, ecc_key* key); + +static int myHwCallback(int devId, wc_CryptoInfo* info, void* ctx) +{ + (void)devId; + (void)ctx; + if (info->algo_type == WC_ALGO_TYPE_PK && + info->pk.type == WC_PK_TYPE_ECDSA_SIGN) { + return my_hw_ecdsa_sign(info->pk.eccsign.in, info->pk.eccsign.inlen, + info->pk.eccsign.out, info->pk.eccsign.outlen, + info->pk.eccsign.key); + } + return CRYPTOCB_UNAVAILABLE; /* everything else stays in software */ +} + +int use_hw(WOLFSSL_CTX* ctx) +{ + if (wc_CryptoCb_RegisterDevice(MY_HW_DEVID, myHwCallback, NULL) != 0) + return -1; + return wolfSSL_CTX_SetDevId(ctx, MY_HW_DEVID) == WOLFSSL_SUCCESS ? 0 : -1; +} +``` + +`sig` receives a DER signature; convert raw r and s with +`wc_ecc_rs_raw_to_sig()`. To keep the private key in the secure element, load +it with `wolfSSL_CTX_use_PrivateKey_Id()` and the same device ID. The same +mechanism powers wolfHSM, wolfTPM and PKCS#11, and PK callbacks +(`--enable-pkcallbacks`) offer a TLS-level alternative. + +Call `use_hw()` before `wolfSSL_new()`: each `WOLFSSL` takes the context's +device ID when it is created. For a session that already exists, set it with +`wolfSSL_SetDevId()`. + +## Zephyr + +Zephyr's TLS sockets (`SOL_TLS`) are built on Mbed TLS. wolfSSL ships a +[Zephyr module](https://github.com/wolfSSL/wolfssl/tree/master/zephyr), and the +[wolfSSL OSP repository](https://github.com/wolfSSL/osp/tree/master/zephyr) has +a patch for each supported Zephyr release that switches the TLS sockets to +wolfSSL; re-apply it when you move to a new release. Subsystems that use the +PSA Crypto API, such as Bluetooth, run on wolfCrypt unchanged with +[wolfPSA](https://github.com/wolfSSL/wolfPSA) as Zephyr's PSA crypto provider. + +## ESP-IDF + +wolfSSL is available as a managed component in the Espressif Component +Registry. Build instructions and examples are in +[IDE/Espressif](https://github.com/wolfSSL/wolfssl/tree/master/IDE/Espressif) +in the wolfSSL repository. + +## Other Platforms + +wolfSSL has projects for more than 60 IDEs and platforms in its `IDE/` +directory, plus Arduino and PlatformIO packages and Linux and BSD kernel +modules. Builds without a configure step use `user_settings.h`, with templates +in `examples/configs/`. diff --git a/MbedTLS-Migration/src/chapter06.md b/MbedTLS-Migration/src/chapter06.md new file mode 100644 index 00000000..42f9b935 --- /dev/null +++ b/MbedTLS-Migration/src/chapter06.md @@ -0,0 +1,81 @@ +# Features Beyond Mbed TLS + +| Feature | Mbed TLS 3.6 / 4.x | wolfSSL | +| ---------------------------------- | ------------------------------------ | ------------------------------ | +| TLS 1.3 | Yes | Yes | +| DTLS 1.3 (RFC 9147) | No, DTLS 1.2 only | Yes | +| DTLS Connection ID (RFC 9146) | Yes | Yes, DTLS 1.2 and 1.3 | +| ML-KEM hybrid key exchange | No | Yes, on by default | +| ML-DSA, SLH-DSA certificates in TLS 1.3 | No | Yes | +| LMS, XMSS | LMS verify, experimental LMS signing, no XMSS | Sign and verify | +| Ed25519, Ed448 | No | Yes | +| QUIC | No | Yes | +| Encrypted Client Hello | No | Yes | +| OCSP stapling | No | Yes, v1 and v2 | +| TLS 1.3 post-handshake auth | No | Yes | +| Raw public keys (RFC 7250) | No | Yes | +| FIPS 140-3 validated crypto | No | Yes, through a separately validated wolfCrypt module | +| Hardware offload | `_ALT` or PSA drivers | Crypto callbacks plus more than 30 in-tree ports | + +## DTLS 1.3 + +Mbed TLS supports DTLS 1.2 only. wolfSSL adds DTLS 1.3 (RFC 9147), with +Connection ID in both versions, bringing the TLS 1.3 handshake to datagram +transports such as CoAP, LwM2M and cellular IoT. Moving is a method change: +in a build with `--enable-dtls13`, `wolfDTLS_client_method()` negotiates DTLS +1.3 where the server supports it and falls back to DTLS 1.2. + +## Post-Quantum Cryptography + +The Mbed TLS roadmap lists ML-KEM as future work, and its only ML-DSA code is +an experimental ML-DSA-87 driver on the development branch. wolfCrypt ships +the complete NIST set, with its own implementations and assembly +optimizations for Intel and ARM: + +- ML-KEM (FIPS 203), used in TLS 1.3 as pure ML-KEM or as hybrid groups such + as X25519MLKEM768, SecP256r1MLKEM768 and SecP384r1MLKEM1024. +- ML-DSA (FIPS 204) for certificates, TLS 1.3 authentication, CMS and + certificate generation, and SLH-DSA (FIPS 205) for certificates and TLS 1.3 + authentication. +- LMS/HSS and XMSS/XMSS^MT stateful hash-based signatures for firmware + signing. +- Falcon for applications that want compact lattice signatures + (experimental: `--enable-falcon --enable-experimental`). + +ML-KEM and the hybrid groups are on by default; ML-DSA and SLH-DSA need +`--enable-mldsa` and `--enable-slhdsa`. The sample client in +[Porting a TLS Client](chapter03.md), with no PQC-specific code, negotiates +SecP256r1MLKEM768 against a default wolfSSL server. With +`--enable-curve25519` the preferred group becomes X25519MLKEM768, the hybrid +that browsers deploy today. + +## FIPS 140-3 + +wolfCrypt holds FIPS 140-3 validations, and Mbed TLS has none. Contact wolfSSL +to find out which certificate fits your platform. + +## Keeping the PSA Crypto API + +[wolfPSA](https://github.com/wolfSSL/wolfPSA) implements the PSA Crypto API on +wolfCrypt, so most code already ported to PSA for Mbed TLS 4.x runs on +wolfCrypt without API changes. The PAKE functions, and with them EC J-PAKE, are +not implemented. + +## The wolfSSL Product Family + +wolfCrypt is also the crypto core for the rest of the wolfSSL products: +[wolfCert](https://github.com/wolfSSL/wolfCert) for EST and SCEP enrollment, +[wolfMQTT](https://github.com/wolfSSL/wolfMQTT), +[wolfSSH](https://github.com/wolfSSL/wolfssh), +[wolfTPM](https://github.com/wolfSSL/wolfTPM), +[wolfBoot](https://github.com/wolfSSL/wolfBoot) for secure boot, +[wolfHSM](https://github.com/wolfSSL/wolfHSM), +[wolfPKCS11](https://github.com/wolfSSL/wolfPKCS11), +[wolfPSA](https://github.com/wolfSSL/wolfPSA), +[wolfProvider](https://github.com/wolfSSL/wolfProvider) for OpenSSL 3, +[wolfIP](https://github.com/wolfSSL/wolfip), +[wolfSentry](https://github.com/wolfSSL/wolfsentry) and +[wolfCOSE](https://github.com/wolfSSL/wolfCOSE). Language bindings exist for +Python, Rust, C#, Java (JSSE and JCE) and Ada, and the +[wolfSSL OSP repository](https://github.com/wolfSSL/osp) carries ports of +projects such as curl, nginx and OpenSSH. diff --git a/MbedTLS-Migration/src/chapter07.md b/MbedTLS-Migration/src/chapter07.md new file mode 100644 index 00000000..cd3cf506 --- /dev/null +++ b/MbedTLS-Migration/src/chapter07.md @@ -0,0 +1,41 @@ +# Getting Started + +Follow the steps in How to Use This Guide in chapter 1, then test against your +existing Mbed TLS peers. Once the port works, turn on what you gain: DTLS 1.3 +and crypto callbacks for your hardware. The ML-KEM hybrid groups are on by +default; for `user_settings.h` builds, see +[Configuration Equivalents](chapter09.md). + +## Interoperability Testing + +wolfSSL's CI runs interoperability tests against Mbed TLS 3.6 for TLS, DTLS +and DTLS Connection ID. The samples in this guide were also tested against +Mbed TLS 4.1. + +For quick tests on a host, the wolfSSL example client and server pair with the +Mbed TLS `ssl_client2` and `ssl_server2` programs: + +```sh +# wolfSSL client against an Mbed TLS server; -g sends an HTTP GET +./examples/client/client -h -p -A -g + +# wolfSSL server for an Mbed TLS client; -d skips the client certificate request +./examples/server/server -p -d + +# Mbed TLS client against that server, trusting the wolfSSL test CA +ssl_client2 server_port= ca_file=/certs/ca-cert.pem server_name=example.com +``` + +`test-ca.crt` from the Mbed TLS test data signs the RSA certificate that +`ssl_server2` uses by default for TLS 1.2. For TLS 1.3 it presents an ECDSA +certificate whose CA, `test-ca2.crt`, carries a NULL signature parameter that +wolfSSL rejects, so start it with `crt_file=server2-sha256.crt +key_file=server2.key` instead. Run the wolfSSL examples with `-?` for the full +list of options. + +## Source and Releases + +The wolfSSL source is at +[github.com/wolfSSL/wolfssl](https://github.com/wolfSSL/wolfssl), and release +archives are available from +[wolfssl.com/download](https://www.wolfssl.com/download/). diff --git a/MbedTLS-Migration/src/chapter08.md b/MbedTLS-Migration/src/chapter08.md new file mode 100644 index 00000000..56b6f799 --- /dev/null +++ b/MbedTLS-Migration/src/chapter08.md @@ -0,0 +1,86 @@ +# API Mapping + +Mbed TLS names apply to 3.6 and 4.x unless the notes say otherwise. Two Mbed +TLS key exchanges have no wolfSSL equivalent: the EC J-PAKE cipher suites +(`MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED`) that OpenThread uses for Thread +commissioning, and the 3.6 RSA-PSK suites +(`MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED`). + +## Setup and Teardown + +| Mbed TLS | wolfSSL | Notes | +| ------------------------------------- | ------------------------------------- | -------------------------- | +| `psa_crypto_init()` | `wolfSSL_Init()` | Required in 4.x, and in 3.6 with `MBEDTLS_USE_PSA_CRYPTO`; `wolfSSL_CTX_new()` calls `wolfSSL_Init()` if needed | +| `mbedtls_ssl_config_init()` + `mbedtls_ssl_config_defaults()` | `wolfSSL_CTX_new(method)` | Role, transport and version come from the method | +| `mbedtls_ssl_conf_min_tls_version()` | `wolfSSL_CTX_SetMinVersion()` | Or a version-specific method such as `wolfTLSv1_3_client_method()` | +| `mbedtls_ssl_conf_rng()` | Not needed | 3.6 only, removed in 4.x | +| `mbedtls_ssl_init()` + `mbedtls_ssl_setup()` | `wolfSSL_new(ctx)` | | +| `mbedtls_ssl_session_reset()` | `wolfSSL_clear()` | | +| `mbedtls_ssl_free()`, `mbedtls_ssl_config_free()` | `wolfSSL_free()`, `wolfSSL_CTX_free()` | | +| `mbedtls_psa_crypto_free()` | `wolfSSL_Cleanup()` | | + +## Certificates, Keys and Verification + +| Mbed TLS | wolfSSL | Notes | +| ------------------------------------- | ------------------------------------- | -------------------------- | +| `mbedtls_x509_crt_parse_file()` + `mbedtls_ssl_conf_ca_chain()` | `wolfSSL_CTX_load_verify_locations()` | | +| `mbedtls_x509_crt_parse()` + `mbedtls_ssl_conf_ca_chain()` | `wolfSSL_CTX_load_verify_buffer()` | Same buffer and length as with Mbed TLS; pass the format explicitly | +| `mbedtls_x509_crt_parse_file()` + `mbedtls_pk_parse_keyfile()` + `mbedtls_ssl_conf_own_cert()` | `wolfSSL_CTX_use_certificate_chain_file()` + `wolfSSL_CTX_use_PrivateKey_file()` | PEM only; for a DER certificate use `wolfSSL_CTX_use_certificate_file()` with `WOLFSSL_FILETYPE_ASN1`. `mbedtls_pk_parse_keyfile()` takes RNG arguments in 3.6, none in 4.x | +| Buffer variants of the above | `wolfSSL_CTX_use_certificate_chain_buffer()` + `wolfSSL_CTX_use_PrivateKey_buffer()` | PEM only; for DER use `wolfSSL_CTX_use_certificate_buffer()` with `WOLFSSL_FILETYPE_ASN1` | +| `mbedtls_ssl_conf_authmode()` | `wolfSSL_CTX_set_verify()` | REQUIRED: `WOLFSSL_VERIFY_PEER` (plus `WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT` on a server). OPTIONAL: `WOLFSSL_VERIFY_PEER` with a callback that returns 1. NONE: `WOLFSSL_VERIFY_NONE` | +| `mbedtls_ssl_conf_verify()` | Callback argument of `wolfSSL_CTX_set_verify()` | The chain arrives as DER in `store->certs[]`; parse it with `wc_InitDecodedCert()` + `wc_ParseCert()`. `store->current_cert` needs `--enable-opensslextra`. By default the callback runs only for certificates that fail verification. `WOLFSSL_ALWAYS_VERIFY_CB` also runs it on success and `WOLFSSL_VERIFY_CB_ALL_CERTS` for every intermediate; `--enable-opensslextra` sets both | +| `mbedtls_ssl_set_hostname()` | `wolfSSL_UseSNI()` + `wolfSSL_check_domain_name()` | `wolfSSL_check_ip_address()` for IP addresses; see [Common Pitfalls](chapter04.md) | +| `mbedtls_ssl_conf_sni()` (server) | `wolfSSL_CTX_set_servername_callback()` + `wolfSSL_SNI_GetRequest()` | Needs SNI | +| Opaque or secure-element key in `mbedtls_ssl_conf_own_cert()` | `wolfSSL_CTX_use_PrivateKey_Id()` / `wolfSSL_CTX_use_PrivateKey_Label()` with a device ID | Needs `--enable-cryptocb` or `--enable-pkcs11` | +| `mbedtls_ssl_get_verify_result()` | `wolfSSL_get_verify_result()` | Needs `--enable-opensslextra`; a failed check already fails the handshake | +| `mbedtls_ssl_get_peer_cert()` | `wolfSSL_get_peer_certificate()` | Returns a copy; free it with `wolfSSL_X509_free()`. Needs `--enable-opensslextra`; without it, `wolfSSL_get_peer_chain()` + `wolfSSL_get_chain_cert()` with `--enable-sessioncerts` | + +## Connection and I/O + +| Mbed TLS | wolfSSL | Notes | +| ------------------------------------- | ------------------------------------- | -------------------------- | +| `mbedtls_net_connect()`, `mbedtls_net_bind()`, `mbedtls_net_accept()` | Your socket code | wolfSSL has no socket helper API | +| `mbedtls_ssl_set_bio()` with `mbedtls_net_send()` / `mbedtls_net_recv()` | `wolfSSL_set_fd()` | | +| `mbedtls_ssl_set_bio()` with custom callbacks | `wolfSSL_CTX_SetIOSend()` / `wolfSSL_CTX_SetIORecv()` + `wolfSSL_SetIOWriteCtx()` / `wolfSSL_SetIOReadCtx()` | Per session: `wolfSSL_SSLSetIOSend()` / `wolfSSL_SSLSetIORecv()` | +| `mbedtls_ssl_handshake()` | `wolfSSL_connect()` / `wolfSSL_accept()` | Or `wolfSSL_negotiate()` for either role | +| `mbedtls_ssl_read()`, `mbedtls_ssl_write()` | `wolfSSL_read()`, `wolfSSL_write()` | | +| `mbedtls_ssl_get_bytes_avail()` | `wolfSSL_pending()` | | +| `mbedtls_ssl_close_notify()` | `wolfSSL_shutdown()` | | + +## Errors and Debugging + +| Mbed TLS | wolfSSL | Notes | +| ------------------------------------- | ------------------------------------- | -------------------------- | +| `MBEDTLS_ERR_SSL_WANT_READ` / `_WANT_WRITE` returned directly | `wolfSSL_get_error()` returns `WOLFSSL_ERROR_WANT_READ` / `_WANT_WRITE` | | +| `MBEDTLS_ERR_SSL_WANT_READ` from a custom receive callback | `WOLFSSL_CBIO_ERR_WANT_READ` | See [Common Pitfalls](chapter04.md) | +| `MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY` | `WOLFSSL_ERROR_ZERO_RETURN` | | +| `MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET` | Not needed | Tickets are handled internally | +| `mbedtls_strerror()` | `wolfSSL_ERR_error_string_n()`, `wc_GetErrorString()` | | +| `mbedtls_ssl_conf_dbg()` + `mbedtls_debug_set_threshold()` | `wolfSSL_SetLoggingCb()` + `wolfSSL_Debugging_ON()` | Needs `--enable-debug` | + +## Sessions, PSK and Extensions + +| Mbed TLS | wolfSSL | Notes | +| ------------------------------------- | ------------------------------------- | -------------------------- | +| `mbedtls_ssl_get_session()` | `wolfSSL_get1_session()` | Free with `wolfSSL_SESSION_free()`; the pointer from `wolfSSL_get_session()` is freed with the `WOLFSSL` | +| `mbedtls_ssl_set_session()` | `wolfSSL_set_session()` | | +| `mbedtls_ssl_cache_*` + `mbedtls_ssl_conf_session_cache()` | Built-in session cache | | +| `mbedtls_ssl_ticket_setup()` + `mbedtls_ssl_conf_session_tickets_cb()` | `--enable-session-ticket`, optional `wolfSSL_CTX_set_TicketEncCb()` | `mbedtls_ssl_ticket_setup()` changed its arguments in 4.x | +| `mbedtls_ssl_conf_psk()` | `wolfSSL_CTX_set_psk_client_callback()` / `wolfSSL_CTX_set_psk_server_callback()` | TLS 1.3 variants add `_tls13_` | +| `mbedtls_ssl_conf_alpn_protocols()` + `mbedtls_ssl_get_alpn_protocol()` | `wolfSSL_UseALPN()` + `wolfSSL_ALPN_GetProtocol()` | Per session; takes a comma-separated string plus `WOLFSSL_ALPN_FAILED_ON_MISMATCH` or `WOLFSSL_ALPN_CONTINUE_ON_MISMATCH`. 4.x changed the Mbed TLS list type to `const char *const *` | +| `mbedtls_ssl_conf_ciphersuites()` | `wolfSSL_CTX_set_cipher_list()` | Takes a colon-separated string | +| `mbedtls_ssl_conf_groups()` | `wolfSSL_CTX_set_groups()` or `wolfSSL_set_groups()` | Add `wolfSSL_UseKeyShare()` to choose the key share sent in the ClientHello; on its own it does not restrict the groups a HelloRetryRequest can negotiate | +| `mbedtls_ssl_conf_max_frag_len()` | `wolfSSL_UseMaxFragment()` | | + +## DTLS + +| Mbed TLS | wolfSSL | Notes | +| ------------------------------------- | ------------------------------------- | -------------------------- | +| `MBEDTLS_SSL_TRANSPORT_DATAGRAM` in `mbedtls_ssl_config_defaults()` | `wolfDTLS_client_method()`, `wolfDTLSv1_3_client_method()` and server equivalents | | +| `mbedtls_ssl_set_timer_cb()` | `wolfSSL_dtls_get_current_timeout()` + `wolfSSL_dtls_got_timeout()` | Only needed with non-blocking sockets or a custom receive callback, which should wait at most `wolfSSL_dtls_get_current_timeout()` seconds | +| `mbedtls_ssl_conf_handshake_timeout()` | `wolfSSL_dtls_set_timeout_init()` + `wolfSSL_dtls_set_timeout_max()` | Per session: call after `wolfSSL_new()`. Values are seconds, not milliseconds, and init must not exceed max (default 64) | +| `mbedtls_ssl_cookie_setup()` + `mbedtls_ssl_conf_dtls_cookies()` | Built in | | +| Cookie exchange on one shared UDP socket | `wolfDTLS_accept_stateless()` | Server side | +| `mbedtls_ssl_set_client_transport_id()` | `wolfSSL_dtls_set_peer()` | | +| `mbedtls_ssl_set_cid()` | `wolfSSL_dtls_cid_use()` + `wolfSSL_dtls_cid_set()` | Needs `--enable-dtlscid` | +| `mbedtls_ssl_set_mtu()` | `wolfSSL_dtls_set_mtu()` | Needs `--enable-dtls-mtu` | diff --git a/MbedTLS-Migration/src/chapter09.md b/MbedTLS-Migration/src/chapter09.md new file mode 100644 index 00000000..e2144b96 --- /dev/null +++ b/MbedTLS-Migration/src/chapter09.md @@ -0,0 +1,38 @@ +# Configuration Equivalents + +| Mbed TLS option | wolfSSL configure option | `user_settings.h` macro | +| -------------------------------------- | -------------------------------------- | ------------------------ | +| `MBEDTLS_SSL_PROTO_TLS1_3` | On by default (`--enable-tls13`) | `WOLFSSL_TLS13` | +| `MBEDTLS_SSL_PROTO_DTLS` | `--enable-dtls` (add `--enable-dtls13` for DTLS 1.3) | `WOLFSSL_DTLS`, `WOLFSSL_DTLS13` | +| `MBEDTLS_SSL_DTLS_CONNECTION_ID` | `--enable-dtlscid` | `WOLFSSL_DTLS_CID` | +| `MBEDTLS_SSL_DTLS_SRTP` | `--enable-srtp` | `WOLFSSL_SRTP` | +| `MBEDTLS_SSL_SERVER_NAME_INDICATION` | `--enable-sni` (on by default only on x86 and aarch64 hosts) | `HAVE_SNI` | +| `MBEDTLS_SSL_ALPN` | `--enable-alpn` | `HAVE_ALPN` | +| `MBEDTLS_SSL_SESSION_TICKETS` | `--enable-session-ticket`; with wolfSSL 5.9.4 and earlier, a client that talks to Mbed TLS TLS 1.3 servers also needs `--enable-ticket-nonce-malloc` | `HAVE_SESSION_TICKET`, `WOLFSSL_TICKET_NONCE_MALLOC` | +| `MBEDTLS_SSL_EARLY_DATA` | `--enable-earlydata` plus `--enable-session-ticket` or `--enable-psk` | `WOLFSSL_EARLY_DATA` | +| `MBEDTLS_SSL_MAX_FRAGMENT_LENGTH` | `--enable-maxfragment` | `HAVE_MAX_FRAGMENT` | +| `MBEDTLS_SSL_RENEGOTIATION` | `--enable-secure-renegotiation`, only if the application enables renegotiation with `mbedtls_ssl_conf_renegotiation()` | `HAVE_SECURE_RENEGOTIATION` | +| `MBEDTLS_KEY_EXCHANGE_*PSK*` | `--enable-psk` (no RSA-PSK suites) | Leave `NO_PSK` undefined | +| `MBEDTLS_KEY_EXCHANGE_RSA_ENABLED` (3.6) | `CFLAGS=-DWOLFSSL_STATIC_RSA`; static RSA has no forward secrecy and is gone in 4.x | `WOLFSSL_STATIC_RSA` | +| `MBEDTLS_CCM_C` / `PSA_WANT_ALG_CCM` | `--enable-aesccm` | `HAVE_AESCCM` | +| `PSA_WANT_ECC_MONTGOMERY_255` / `MBEDTLS_ECP_DP_CURVE25519_ENABLED` | `--enable-curve25519` | `HAVE_CURVE25519` | +| `MBEDTLS_LMS_C` | `--enable-lms` | `WOLFSSL_HAVE_LMS` | +| No equivalent (ML-KEM) | On by default (`--enable-mlkem`); pure ML-KEM key exchange needs `--enable-tls-mlkem-standalone` | `WOLFSSL_HAVE_MLKEM` (with `WOLFSSL_SHA3`, `WOLFSSL_SHAKE128`, `WOLFSSL_SHAKE256`), `WOLFSSL_PQC_HYBRIDS` and `WOLFSSL_TLS_NO_MLKEM_STANDALONE` to match the configure default | +| Experimental ML-DSA-87 (development branch only) | `--enable-mldsa`, `--enable-slhdsa` | `WOLFSSL_HAVE_MLDSA`, `WOLFSSL_HAVE_SLHDSA` (with `WOLFSSL_SHA3`, `WOLFSSL_SHAKE128`, `WOLFSSL_SHAKE256`) | +| `MBEDTLS_MEMORY_BUFFER_ALLOC_C` | `--enable-staticmemory` | `WOLFSSL_STATIC_MEMORY` | +| `MBEDTLS_THREADING_C` | On by default (`--enable-singlethreaded` to remove) | Define `SINGLE_THREADED` to remove | +| `MBEDTLS_DEBUG_C` | `--enable-debug` | `DEBUG_WOLFSSL` | +| Crypto `MBEDTLS_*_ALT`, PSA drivers | `--enable-cryptocb` | `WOLF_CRYPTO_CB` | + +The defaults in this table apply to `./configure` and CMake. In a +`user_settings.h` build, features such as TLS 1.3, ML-KEM, the hybrid groups +and SNI are on only if you define them, so start from +`examples/configs/user_settings_tls13.h` (or `user_settings_dtls13.h`, +`user_settings_pq.h`) rather than an empty file. None of these templates +enables the hybrid groups. Add `WOLFSSL_PQC_HYBRIDS` and +`WOLFSSL_TLS_NO_MLKEM_STANDALONE` to `user_settings_pq.h`; the TLS 1.3 and +DTLS 1.3 templates also need `WOLFSSL_HAVE_MLKEM`, `WOLFSSL_SHA3`, +`WOLFSSL_SHAKE128` and `WOLFSSL_SHAKE256`, and the DTLS 1.3 template needs +`HAVE_SNI` and `WOLFSSL_DTLS_CH_FRAG`. A DTLS 1.3 server must also call +`wolfSSL_dtls13_allow_ch_frag()` to accept a fragmented ClientHello. Only the +second ClientHello, which carries the cookie, may be fragmented. diff --git a/MbedTLS-Migration/src/chapter10.md b/MbedTLS-Migration/src/chapter10.md new file mode 100644 index 00000000..96363868 --- /dev/null +++ b/MbedTLS-Migration/src/chapter10.md @@ -0,0 +1,40 @@ +# Support + +wolfSSL offers several support channels for users migrating from Mbed TLS. + +## Commercial Support + +wolfSSL Inc. provides commercial support packages that include direct access +to the wolfSSL engineering team. Commercial support is available for: + +- Migration assistance and consulting +- FIPS 140-3 deployment guidance +- Custom feature development +- Platform porting and integration + +Contact wolfSSL for commercial support and licensing inquiries: + +- Email: [facts@wolfssl.com](mailto:facts@wolfssl.com) +- Web: [https://www.wolfssl.com/contact/](https://www.wolfssl.com/contact/) + +wolfSSL offers free presales support too! Contact our support team directly +with any questions or problems: + +- Email: [support@wolfssl.com](mailto:support@wolfssl.com) + +## Community Resources + +- **wolfSSL GitHub** - [https://github.com/wolfSSL](https://github.com/wolfSSL) +- **wolfSSL Forums** - [https://www.wolfssl.com/forums/](https://www.wolfssl.com/forums/) + +## Related Documentation + +- [wolfSSL Manual](https://www.wolfssl.com/documentation/manuals/wolfssl/) +- [wolfSSL Porting Guide](https://www.wolfssl.com/documentation/manuals/wolfssl-porting-guide/) +- [wolfSSL Tuning Guide](https://www.wolfssl.com/documentation/manuals/wolfssl-tuning-guide/) +- [wolfSSL FIPS FAQ](https://www.wolfssl.com/documentation/manuals/wolfssl-fips-faq/) + +## Reporting Issues + +For bugs or issues with wolfSSL, please report them on the +[wolfSSL GitHub repository](https://github.com/wolfSSL/wolfssl/issues). diff --git a/MbedTLS-Migration/test/linkcheck.json b/MbedTLS-Migration/test/linkcheck.json new file mode 100644 index 00000000..28ad1ab6 --- /dev/null +++ b/MbedTLS-Migration/test/linkcheck.json @@ -0,0 +1,7 @@ +{ + "timeout": "20s", + "retryOn429": true, + "retryCount": 5, + "fallbackRetryDelay": "30s", + "aliveStatusCodes": [200, 206] +} diff --git a/MbedTLS-Migration/test/lintcheck.json b/MbedTLS-Migration/test/lintcheck.json new file mode 100644 index 00000000..5a48a0b8 --- /dev/null +++ b/MbedTLS-Migration/test/lintcheck.json @@ -0,0 +1,4 @@ +{ + "MD013": false, + "MD026": false +} diff --git a/README.md b/README.md index a5b898c7..4cae27bc 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ To build the documentation you will need Docker running on your system. In this * `make porting` * `make fips-ready` * `make bc-migration` +* `make mbedtls-migration` The wolfCOSE target reads manual pages from `wolfSSL/wolfCOSE` `main` by default and prints the source commit used. Edit those pages in wolfCOSE; this