### 4.0 Migration Guide # Migrating from Mbed TLS 3.x to Mbed TLS 4.0 This guide details the steps required to migrate from Mbed TLS version 3.x to Mbed TLS version 4.0 or greater. Unlike normal releases, Mbed TLS 4.0 breaks compatibility with previous versions, so users, integrators and package maintainers might need to change their own code in order to make it work with Mbed TLS 4.0. Here's the list of breaking changes; each entry should help you answer these two questions: (1) am I affected? (2) if yes, what's my migration path? The changes are detailed below. Here is a summary of the main points: - Mbed TLS has been split between two products: TF-PSA-Crypto for cryptography, and Mbed TLS for X.509 and (D)TLS. - CMake is now the only supported build system. - The cryptography API is now mostly the PSA API: most legacy cryptography APIs have been removed. This has led to adaptations in some X.509 and TLS APIs, notably because the library always uses the PSA random generator. - Various deprecated or minor functionality has been removed. Please consult the [TF-PSA-Crypto migration guide](https://github.com/Mbed-TLS/TF-PSA-Crypto/blob/development/docs/1.0-migration-guide.md) for all information related to the crytography part of the library. ## CMake as the only build system Mbed TLS now uses CMake exclusively to configure and drive its build process. Support for the GNU Make and Microsoft Visual Studio project-based build systems has been removed. The previous `.sln` and `.vcxproj` files are no longer distributed or generated. See the `Compiling` section in README.md for instructions on building the Mbed TLS libraries and tests with CMake. If you develop in Microsoft Visual Studio, you could either generate a Visual Studio solution using a CMake generator, or open the CMake project directly in Visual Studio. ### Translating Make commands to CMake With the removal of GNU Make support, all build, test, and installation operations must now be performed using CMake. This section provides a quick reference for translating common `make` commands into their CMake equivalents. #### Basic build workflow Run `cmake -S . -B build` once before building to configure the build and generate native build files (e.g., Makefiles) in the `build` directory. This sets up an out-of-tree build, which is recommended. | Make command | CMake equivalent | Description | |----------------|------------------------------------------------|--------------------------------------------------------------------| | `make` | `cmake --build build` | Build the libraries, programs, and tests in the `build` directory. | | `make test` | `ctest --test-dir build` | Run the tests produced by the previous build. | | `make clean` | `cmake --build build --target clean` | Remove build artifacts produced by the previous build. | | `make install` | `cmake --install build --prefix build/install` | Install the built libraries, headers, and tests to `build/install`. | #### Building specific targets Unless otherwise specified, the CMake command in the table below should be preceded by a `cmake -S . -B build` call to configure the build and generate build files in the `build` directory. | Make command | CMake equivalent | Description | |-----------------|---------------------------------------------------------------------|---------------------------| | `make lib` | `cmake --build build --target lib` | Build only the libraries. | | `make tests` | `cmake -S . -B build -DENABLE_PROGRAMS=Off && cmake --build build` | Build test suites. | | `make programs` | `cmake --build build --target programs` | Build example programs. | | `make apidoc` | `cmake --build build --target mbedtls-apidoc` | Build documentation. | Target names may differ slightly; use `cmake --build build --target help` to list all available CMake targets. There is no CMake equivalent for `make generated_files` or `make neat`. Generated files are automatically created in the build tree with `cmake --build build` and removed with `cmake --build build --target clean`. If you need to build the generated files in the source tree without involving CMake, you can call `framework/scripts/make_generated_files.py`. There is currently no equivalent for `make uninstall` in the Mbed TLS CMake build system. #### Common build options The following table illustrates the approximate CMake equivalents of common make commands. Most CMake examples show only the configuration step, others (like installation) correspond to different stages of the build process. | Make usage | CMake usage | Description | |----------------------------|-------------------------------------------------------|----------------------| | `make DEBUG=1` | `cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug` | Build in debug mode. | | `make SHARED=1` | `cmake -S . -B build -DUSE_SHARED_MBEDTLS_LIBRARY=On` | Also build shared libraries. | | `make GEN_FILES=""` | `cmake -S . -B build -DGEN_FILES=OFF` | Skip generating files (not a strict equivalent). | | `make DESTDIR=install_dir` | `cmake --install build --prefix install_dir` | Specify installation path. | | `make CC=clang` | `cmake -S . -B build -DCMAKE_C_COMPILER=clang` | Set the compiler. | | `make CFLAGS='-O2 -Wall'` | `cmake -S . -B build -DCMAKE_C_FLAGS="-O2 -Wall"` | Set compiler flags. | ## Repository split In Mbed TLS 4.0, the project was split into two repositories: - [Mbed TLS](https://github.com/Mbed-TLS/mbedtls): provides TLS and X.509 functionality. - [TF-PSA-Crypto](https://github.com/Mbed-TLS/TF-PSA-Crypto): provides the standalone cryptography library, implementing the PSA Cryptography API. Mbed TLS consumes TF-PSA-Crypto as a submodule. You should stay with Mbed TLS if you use TLS or X.509 functionality. You still have direct access to the cryptography library. ### File and directory relocations The following table summarizes the file and directory relocations resulting from the repository split between Mbed TLS and TF-PSA-Crypto. These changes reflect the move of cryptographic, cryptographic-adjacent, and platform components from Mbed TLS into the new TF-PSA-Crypto repository. | Original location | New location(s) | Notes | |-----------------------------------------|--------------------------------------------------------------------------------------|-------| | `library/*` () | `tf-psa-crypto/core/`
`tf-psa-crypto/drivers/builtin/src/` | Contains cryptographic, cryptographic-adjacent (e.g., ASN.1, Base64), and platform C modules and headers. | | `include/mbedtls/*` () | `tf-psa-crypto/include/mbedtls/`
`tf-psa-crypto/drivers/builtin/include/private/` | Public headers moved to `include/mbedtls`; now internal headers moved to `include/private`. | | `include/psa` | `tf-psa-crypto/include/psa` | All PSA headers consolidated here. | | `3rdparty/everest`
`3rdparty/p256-m` | `tf-psa-crypto/drivers/everest`
`tf-psa-crypto/drivers/p256-m` | Third-party crypto driver implementations. | () The `library` and `include/mbedtls` directories still exist in Mbed TLS, but now contain only TLS and X.509 components. ### Configuration file split Cryptography and platform configuration options have been moved from `include/mbedtls/mbedtls_config.h` to `tf-psa-crypto/include/psa/crypto_config.h`, which is now mandatory. See [Compile-time configuration](#compile-time-configuration). The header `include/mbedtls/mbedtls_config.h` still exists and now contains only the TLS and X.509 configuration options. If you use the Python script `scripts/config.py` to adjust your configuration, you do not need to modify your scripts to specify which configuration file to edit, the script automatically updates the correct file. There have been significant changes in the configuration options, primarily affecting cryptography. #### Cryptography configuration - See [psa-transition.md](https://github.com/Mbed-TLS/TF-PSA-Crypto/blob/development/docs/psa-transition.md#compile-time-configuration). - See also the following sections in the TF-PSA-Crypto 1.0 migration guide: - *PSA as the Only Cryptography API* and its sub-section *Impact on the Library Configuration* - *Random Number Generation Configuration* #### TLS configuration For details about TLS-related changes, see [Changes to TLS options](#changes-to-tls-options). ### Impact on some usages of the library #### Checking out a branch or a tag After checking out a branch or tag of the Mbed TLS repository, you must now recursively update the submodules, as TF-PSA-Crypto contains itself a nested submodule: ``` git submodule update --init --recursive ``` #### Linking directly to a built library The Mbed TLS CMake build system still provides the cryptography libraries under their legacy name, `libmbedcrypto.`, so you can continue linking against them. These libraries are still located in the `library` directory within the build tree. The cryptography libraries are also now provided as `libtfpsacrypto.`, consistent with the naming used in the TF-PSA-Crypto repository. You may need to update include paths to the public header files, see [File and Directory Relocations](#file-and-directory-relocations) for details. #### Using Mbed TLS as a CMake subproject The base name of the libraries are now `tfpsacrypto` (formely `mbedcrypto`), `mbedx509` and `mbedtls`. As before, these base names are also the names of CMake targets to build each library. If your CMake scripts reference a cryptography library target, you need to update its name accordingly. For example, the following CMake code: ``` target_link_libraries(mytarget PRIVATE mbedcrypto) ``` should be updated to: ``` target_link_libraries(mytarget PRIVATE tfpsacrypto) ``` You can refer to the following example demonstrating how to consume Mbed TLS as a CMake subproject: - `programs/test/cmake_subproject` #### Using Mbed TLS as a CMake package The same renaming applies to the cryptography library targets declared as part of the Mbed TLS CMake package, use `MbedTLS::tfpsacrypto` instead of `MbedTLS::mbedcrypto`. For example, the following CMake code: ``` find_package(MbedTLS REQUIRED) target_link_libraries(myapp PRIVATE MbedTLS::mbedcrypto) ``` should be updated to: ``` find_package(MbedTLS REQUIRED) target_link_libraries(myapp PRIVATE MbedTLS::tfpsacrypto) ``` You can also refer to the following example programs demonstrating how to consume Mbed TLS as a CMake package: - `programs/test/cmake_package` - `programs/test/cmake_package_install` #### Using the Mbed TLS Crypto pkg-config file The Mbed TLS CMake build system still provides the pkg-config file mbedcrypto.pc, so you can continue using it. Internally, it now references the tfpsacrypto library. A new pkg-config file, `tfpsacrypto.pc`, is also provided. Both `mbedcrypto.pc` and `tfpsacrypto.pc` are functionally equivalent, providing the same compiler and linker flags. #### Using Mbed TLS as an installed library The Mbed TLS CMake build system still installs the cryptography libraries under their legacy name, `libmbedcrypto.`, so you can continue linking against them. The cryptography library is also now provided as `libtfpsacrypto.`. Regarding the headers, the main change is the relocation of some headers to subdirectories called `private`. These headers are installed primarily to satisfy compiler dependencies. Others remain for historical reasons and may be cleaned up in later versions of the library. We strongly recommend not relying on the declarations in these headers, as they may be removed or modified without notice. See the section Private Declarations in the TF-PSA-Crypto 1.0 migration guide for more information. Finally, note the new `include/tf-psa-crypto` directory, which contains the TF-PSA-Crypto version and build-time configuration headers. ### Audience-Specific Notes #### Application Developers using a distribution package - See [Impact on usages of the library](#impact-on-some-usages-of-the-library) for the possible impacts on: - Linking against the cryptography library or CMake targets. - Using the Mbed TLS Crypto pkg-config file. - Using Mbed TLS as an installed library ### Developer or package maintainers If you build or distribute Mbed TLS: - The build system is now CMake only, Makefiles and Visual Studio projects are removed. - You may need to adapt packaging scripts to handle the TF-PSA-Crypto submodule. - You should update submodules recursively after checkout. - Review [File and directory relocations](#file-and-directory-relocations) for updated paths. - See [Impact on usages of the library](#impact-on-some-usages-of-the-library) for the possible impacts on: - Linking against the cryptography library or CMake targets. - Using the Mbed TLS Crypto pkg-config file (`mbedcrypto.pc` or `tfpsacrypto.pc`). - Using Mbed TLS as an installed library - Configuration note: cryptography and platform options are now in `crypto_config.h` (see [Configuration file split](#configuration-file-split)). ### Platform Integrators If you integrate Mbed TLS with a platform or hardware drivers: - TF-PSA-Crypto is now a submodule, update integration scripts to initialize submodules recursively. - The PSA driver wrapper is now generated in TF-PSA-Crypto. - Platform-specific configuration are now handled in `crypto_config.h`. - See [Repository split](#repository-split) for how platform components moved to TF-PSA-Crypto. ## Compile-time configuration ### Configuration file split All configuration options that are relevant to TF-PSA-Crypto must now be configured in one of its configuration files, namely: * `TF_PSA_CRYPTO_CONFIG_FILE`, if set on the preprocessor command line; * otherwise ``; * additionally `TF_PSA_CRYPTO_USER_CONFIG_FILE`, if set. Configuration options that are relevant to X.509 or TLS should still be set in the Mbed TLS configuration file (`MBEDTLS_CONFIG_FILE` or ``, plus `MBEDTLS_USER_CONFIG_FILE` if it is set). However, you can define all options in the crypto configuration, and Mbed TLS will pick them up. Generally speaking, the options that must be configured in TF-PSA-Crypto are: * options related to platform settings; * options related to the choice of cryptographic mechanisms included in the build; * options related to the inner workings of cryptographic mechanisms, such as size/memory/performance compromises; * options related to crypto-adjacent features, such as ASN.1 and Base64. See `include/psa/crypto_config.h` in TF-PSA-Crypto and `include/mbedtls/mbedtls_config.h` in Mbed TLS for details. Notably, `` is no longer limited to `PSA_WANT_xxx` options. Note that many options related to cryptography have changed; see the TF-PSA-Crypto migration guide for details. ### Split of `build_info.h` and `version.h` The header file ``, which includes the configuration file and provides the adjusted configuration macros, now has an similar file `` in TF-PSA-Crypto. The Mbed TLS header includes the TF-PSA-Crypto header, so including `` remains sufficient to obtain information about the crypto configuration. TF-PSA-Crypto exposes its version through ``, similar to `` in Mbed TLS. ### Removal of `check_config.h` The header `mbedtls/check_config.h` is no longer present. Including it from user configuration files was already obsolete in Mbed TLS 3.x, since it enforces properties the configuration as adjusted by `mbedtls/build_info.h`, not properties that the user configuration is expected to meet. ### Changes to TLS options #### Enabling null cipher suites The option to enable null cipher suites in TLS 1.2 has been renamed from `MBEDTLS_CIPHER_NULL_CIPHER` to `MBEDTLS_SSL_NULL_CIPHERSUITES`. It remains disabled in the default configuration. #### Removal of backward compatibility options The option `MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT` has been removed. Only the version standardized in RFC 9146 is supported now. ## PSA as the only cryptography API The PSA API is now the only API for cryptographic primitives. ### Impact on application code The X.509, PKCS7 and SSL modules always use PSA for cryptography, with a few exceptions documented in the [PSA limitations](architecture/psa-migration/psa-limitations.md) document. (These limitations are mostly transparent unless you want to leverage PSA accelerator drivers.) This corresponds to the behavior of Mbed TLS 3.x when `MBEDTLS_USE_PSA_CRYPTO` is enabled. In effect, `MBEDTLS_USE_PSA_CRYPTO` is now always enabled. `psa_crypto_init()` must be called before performing any cryptographic operation, including indirect requests such as parsing a key or certificate or starting a TLS handshake. A few functions take different parameters to migrate them to the PSA API. See “[Function prototype changes](#function-prototype-changes)”. ### No random generator instantiation Formerly, applications using TLS, asymmetric cryptography operations involving a private key, or other features needing random numbers, needed to provide a random generator, generally by instantiating an entropy context (`mbedtls_entropy_context`) and a DRBG context (`mbedtls_ctr_drbg_context` or `mbedtls_hmac_drbg_context`). This is no longer necessary, or possible. All features that require a random generator (RNG) now use the one provided by the PSA subsystem. Instead, applications that use random generators or keys (even public keys) need to call `psa_crypto_init()` before any cryptographic operation or key management operation. See also [function prototype changes](#function-prototype-changes), many of which are related to the move from RNG callbacks to a global RNG. ### Impact on the library configuration Mbed TLS follows the configuration of TF-PSA-Crypto with respect to cryptographic mechanisms. They are now based on `PSA_WANT_xxx` macros instead of legacy configuration macros such as `MBEDTLS_RSA_C`, `MBEDTLS_PKCS1_V15`, etc. The configuration of X.509 and TLS is not directly affected by the configuration. However, applications and middleware that rely on these configuration symbols to know which cryptographic mechanisms to support will need to migrate to `PSA_WANT_xxx` macros. For more information, consult the PSA transition guide in TF-PSA-Crypto. ## Private declarations Since Mbed TLS 3.0, some things that are declared in a public header are not part of the stable application programming interface (API), but instead are considered private. Private elements may be removed or may have their semantics changed in a future minor release without notice. ### Understanding private declarations in public headers In Mbed TLS 4.x, private elements in header files include: * Anything appearing in a header file whose path contains `/private` (unless re-exported and documented in another non-private header). * Structure and union fields declared with `MBEDTLS_PRIVATE(field_name)` in the source code, and appearing as `private_field_name` in the rendered documentation. (This was already the case since Mbed TLS 3.0.) * Any preprocessor macro that is not documented with a Doxygen comment. In the source code, Doxygen comments start with `/**` or `/*!`. If a macro only has a comment above that starts with `/*`, the macro is considered private. In the rendered documentation, private macros appear with only an automatically rendered parameter list, value and location, but no custom text. * Any declaration that is guarded by the preprocessor macro `MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS`. ### Usage of private declarations Some private declarations are present in public headers for technical reasons, because they need to be visible to the compiler. Others are present for historical reasons and may be cleaned up in later versions of the library. We strongly recommend against relying on these declarations, since they may be removed or may have their semantics changed without notice. Note that Mbed TLS 4.0 still relies on some private interfaces of TF-PSA-Crypto 1.0. We expect to remove this reliance gradually in future minor releases. Sample programs have not been fully updated yet and some of them might still use APIs that are no longer public. You can recognize them by the fact that they define the macro `MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS` (or `MBEDTLS_ALLOW_PRIVATE_ACCESS`) at the very top (before including headers). When you see one of these two macros in a sample program, be aware it has not been updated and parts of it do not demonstrate current practice. We strongly recommend against defining `MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS` or `MBEDTLS_ALLOW_PRIVATE_ACCESS` in your own application. If you do so, your code may not compile or work with future minor releases. If there's something you want to do that you feel can only be achieved by using one of these two macros, please reach out on github or the mailing list. ## Error codes ### Unified error code space The convention still applies that functions return 0 for success and a negative value between -32767 and -1 on error. PSA functions (`psa_xxx()` or `mbedtls_psa_xxx()`) still return a `PSA_ERROR_xxx` error codes. Non-PSA functions (`mbedtls_xxx()` excluding `mbedtls_psa_xxx()`) can return either `PSA_ERROR_xxx` or `MBEDTLS_ERR_xxx` error codes. There may be cases where an `MBEDTLS_ERR_xxx` constant has the same numerical value as a `PSA_ERROR_xxx`. In such cases, they have the same meaning: they are different names for the same error condition. ### Simplified legacy error codes All values returned by a function to indicate an error now have a defined constant named `MBEDTLS_ERR_xxx` or `PSA_ERROR_xxx`. Functions no longer return the sum of a “low-level” and a “high-level” error code. Generally, functions that used to return the sum of two error codes now return the low-level code. However, as before, the exact error code returned in a given scenario can change without notice unless the condition is specifically described in the function's documentation and no other condition is applicable. As a consequence, the functions `mbedtls_low_level_strerr()` and `mbedtls_high_level_strerr()` no longer exist. ### Removed error code names Many legacy error codes have been removed in favor of PSA error codes. Generally, functions that returned a legacy error code in the table below in Mbed TLS 3.6 now return the PSA error code listed on the same row. Similarly, callbacks should apply the same changes to error code, unless there has been a relevant change to the callback's interface. | Legacy constant (Mbed TLS 3.6) | PSA constant (Mbed TLS 4.0) | |-----------------------------------------|---------------------------------| | `MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED` | `PSA_ERROR_CORRUPTION_DETECTED` | | `MBEDTLS_ERR_ERROR_GENERIC_ERROR` | `PSA_ERROR_GENERIC_ERROR` | | `MBEDTLS_ERR_NET_BUFFER_TOO_SMALL` | `PSA_ERROR_BUFFER_TOO_SMALL` | | `MBEDTLS_ERR_OID_BUF_TOO_SMALL` | `PSA_ERROR_BUFFER_TOO_SMALL` | | `MBEDTLS_ERR_OID_NOT_FOUND` | `PSA_ERROR_NOT_SUPPORTED` | | `MBEDTLS_ERR_PKCS7_ALLOC_FAILED` | `PSA_ERROR_INSUFFICIENT_MEMORY` | | `MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA` | `PSA_ERROR_INVALID_ARGUMENT` | | `MBEDTLS_ERR_PKCS7_VERIFY_FAIL` | `PSA_ERROR_INVALID_SIGNATURE` | | `MBEDTLS_ERR_SSL_ALLOC_FAILED` | `PSA_ERROR_INSUFFICIENT_MEMORY` | | `MBEDTLS_ERR_SSL_BAD_INPUT_DATA` | `PSA_ERROR_INVALID_ARGUMENT` | | `MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL` | `PSA_ERROR_BUFFER_TOO_SMALL` | | `MBEDTLS_ERR_X509_ALLOC_FAILED` | `PSA_ERROR_INSUFFICIENT_MEMORY` | | `MBEDTLS_ERR_X509_BUFFER_TOO_SMALL` | `PSA_ERROR_BUFFER_TOO_SMALL` | See also the corresponding section in the TF-PSA-Crypto migration guide, which lists error codes from cryptography modules. ## Removal of deprecated functions ### Removal of deprecated X.509 functions The deprecated function `mbedtls_x509write_crt_set_serial()` has been removed. The function was superseded by `mbedtls_x509write_crt_set_serial_raw()`. ### Removal of deprecated SSL functions The deprecated function `mbedtls_ssl_conf_curves()` has been removed. The function was superseded by `mbedtls_ssl_conf_groups()`. ### Removal of `compat-2.x.h` The header `compat-2.x.h`, containing some definitions for backward compatibility with Mbed TLS 2.x, has been removed. ## Removed features ### Removal of obsolete key exchanges methods in (D)TLS 1.2 Mbed TLS 4.0 no longer supports key exchange methods that rely on finite-field Diffie-Hellman (DHE) in TLS 1.2 and DTLS 1.2. (Only ephemeral Diffie-Hellman was ever supported, Mbed TLS 3.x already did not support static Diffie-Hellman.) Finite-field Diffie-Hellman remains supported in TLS 1.3. Mbed TLS 4.0 no longer supports key exchange methods that rely on RSA decryption (without forward secrecy). RSA signatures remain supported. This affects TLS 1.2 and DTLS 1.2 (TLS 1.3 does not have key exchanges using RSA decryption). That is, the following key exchange types are no longer supported: * RSA-PSK; * RSA (i.e. cipher suites using only RSA decryption: cipher suites using RSA signatures remain supported); * DHE-PSK (except in TLS 1.3); * DHE-RSA (except in TLS 1.3). * static ECDH (ECDH-RSA and ECDH-ECDSA, as opposed to ephemeral ECDH (ECDHE) which remains supported). The full list of removed cipher suites is: ``` /* Detailed source-code truncated for AI context efficiency. */ ``` As a consequence of the removal of support for DHE in (D)TLS 1.2, the following functions are no longer useful and have been removed: ``` mbedtls_ssl_conf_dh_param_bin() mbedtls_ssl_conf_dh_param_ctx() mbedtls_ssl_conf_dhm_min_bitlen() ``` ### Removal of elliptic curves Following their removal from the crypto library, elliptic curves of less than 250 bits (secp192r1, secp192k1, secp224r1, secp224k1) are no longer supported in certificates and in TLS. ### Removal of deprecated functions The deprecated functions `mbedtls_ssl_conf_min_version()` and `mbedtls_ssl_conf_max_version()`, and the associated constants `MBEDTLS_SSL_MAJOR_VERSION_3`, `MBEDTLS_SSL_MINOR_VERSION_3` and `MBEDTLS_SSL_MINOR_VERSION_4` have been removed. Use `mbedtls_ssl_conf_min_tls_version()` and `mbedtls_ssl_conf_max_tls_version()` with `MBEDTLS_SSL_VERSION_TLS1_2` or `MBEDTLS_SSL_VERSION_TLS1_3` instead. The deprecated function `mbedtls_ssl_conf_sig_hashes()` has been removed. Use `mbedtls_ssl_conf_sig_algs()` instead. ## Function prototype changes A number of existing functions now take a different list of arguments, mostly to migrate them to the PSA API. ### Public functions no longer take a RNG callback Functions that need randomness no longer take an RNG callback in the form of `f_rng, p_rng` arguments. Instead, they use the PSA Crypto random generator (accessible as `psa_generate_random()`). All software using the X.509 or SSL modules must call `psa_crypto_init()` before calling any of the functions listed here. ### RNG removal in X.509 The following function prototypes have been changed in `mbedtls/x509_crt.h`: ```c int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); int mbedtls_x509write_crt_pem(mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); ``` to ```c int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size); int mbedtls_x509write_crt_pem(mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size); ``` The following function prototypes have been changed in `mbedtls/x509_csr.h`: ```c int mbedtls_x509write_csr_der(mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); int mbedtls_x509write_csr_pem(mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); ``` to ```c int mbedtls_x509write_csr_der(mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size); int mbedtls_x509write_csr_pem(mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size); ``` ### RNG removal in SSL The following function prototype has been changed in `mbedtls/ssl_cookie.h`: ```c int mbedtls_ssl_cookie_setup(mbedtls_ssl_cookie_ctx *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); ``` to ```c int mbedtls_ssl_cookie_setup(mbedtls_ssl_cookie_ctx *ctx); ``` ### Removal of `mbedtls_ssl_conf_rng` `mbedtls_ssl_conf_rng()` has been removed from the library. Its sole purpose was to configure the RNG used for TLS, but now the PSA Crypto random generator is used throughout the library. ### Changes to mbedtls_ssl_ticket_setup In the arguments of the function `mbedtls_ssl_ticket_setup()`, the `mbedtls_cipher_type_t` argument specifying the AEAD mechanism for ticket protection has been replaced by an equivalent PSA description consisting of a key type, a size and an algorithm. Also, the function no longer takes RNG arguments. The prototype in `mbedtls/ssl_ticket.h` has changed from ```c int mbedtls_ssl_ticket_setup(mbedtls_ssl_ticket_context *ctx, mbedtls_f_rng_t *f_rng, void *p_rng, mbedtls_cipher_type_t cipher, uint32_t lifetime); ``` to ```c int mbedtls_ssl_ticket_setup(mbedtls_ssl_ticket_context *ctx, psa_algorithm_t alg, psa_key_type_t key_type, psa_key_bits_t key_bits, uint32_t lifetime); ``` ## OID module The compilation option `MBEDTLS_OID_C` no longer exists. OID tables are included in the build automatically as needed for parsing and writing X.509 data. Mbed TLS no longer offers interfaces to look up values by OID or OID by enum values (`mbedtls_oid_get_()` and `mbedtls_oid_get_oid_by_()`). The header `` now only provides functions to convert between binary and dotted string OID representations. These functions are now part of `libmbedx509` rather than the crypto library. The function `mbedtls_oid_get_numeric_string()` is guarded by `MBEDTLS_X509_USE_C`, and `mbedtls_oid_from_numeric_string()` by `MBEDTLS_X509_CREATE_C`. The header also still defines macros for OID strings that are relevant to X.509. --- ### Index .. Mbed TLS Versioned documentation master file, created by sphinx-quickstart on Thu Feb 23 18:13:44 2023. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. Mbed TLS API documentation ========================== .. doxygenpage:: index :project: mbedtls-versioned .. toctree:: :caption: Contents :maxdepth: 1 Home api/grouplist.rst api/filelist.rst api/structlist.rst api/unionlist.rst --- ### Tls13 Early Data Writing early data ------------------ An application function to write and send a buffer of data to a server through TLS may plausibly look like: ``` int write_data(mbedtls_ssl_context *ssl, const unsigned char *data_to_write, size_t data_to_write_len, size_t *data_written) { int ret; *data_written = 0; while (*data_written < data_to_write_len) { ret = mbedtls_ssl_write(ssl, data_to_write + *data_written, data_to_write_len - *data_written); if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { return ret; } *data_written += ret; } return 0; } ``` where ssl is the SSL context to use, data_to_write the address of the data buffer and data_to_write_len the number of data bytes. The handshake may not be completed, not even started for the SSL context ssl when the function is called and in that case the mbedtls_ssl_write() API takes care transparently of completing the handshake before to write and send data to the server. The mbedtls_ssl_write() may not be able to write and send all data in one go thus the need for a loop calling it as long as there are still data to write and send. An application function to write and send early data and only early data, data sent during the first flight of client messages while the handshake is in its initial phase, would look completely similar but the call to mbedtls_ssl_write_early_data() instead of mbedtls_ssl_write(). ``` int write_early_data(mbedtls_ssl_context *ssl, const unsigned char *data_to_write, size_t data_to_write_len, size_t *data_written) { int ret; *data_written = 0; while (*data_written < data_to_write_len) { ret = mbedtls_ssl_write_early_data(ssl, data_to_write + *data_written, data_to_write_len - *data_written); if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { return ret; } *data_written += ret; } return 0; } ``` Note that compared to write_data(), write_early_data() can also return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA and that should be handled specifically by the user of write_early_data(). A fresh SSL context (typically just after a call to mbedtls_ssl_setup() or mbedtls_ssl_session_reset()) would be expected when calling `write_early_data`. All together, code to write and send a buffer of data as long as possible as early data and then as standard post-handshake application data could plausibly look like: ``` ret = write_early_data(ssl, data_to_write, data_to_write_len, &early_data_written); if (ret < 0 && ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA) { goto error; } ret = write_data(ssl, data_to_write + early_data_written, data_to_write_len - early_data_written, &data_written); if (ret < 0) { goto error; } data_written += early_data_written; ``` Finally, taking into account that the server may reject early data, application code to write and send a buffer of data could plausibly look like: ``` ret = write_early_data(ssl, data_to_write, data_to_write_len, &early_data_written); if (ret < 0 && ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA) { goto error; } /* * Make sure the handshake is completed as it is a requisite of * mbedtls_ssl_get_early_data_status(). */ while (!mbedtls_ssl_is_handshake_over(ssl)) { ret = mbedtls_ssl_handshake(ssl); if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { goto error; } } ret = mbedtls_ssl_get_early_data_status(ssl); if (ret < 0) { goto error; } if (ret == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) { early_data_written = 0; } ret = write_data(ssl, data_to_write + early_data_written, data_to_write_len - early_data_written, &data_written); if (ret < 0) { goto error; } data_written += early_data_written; ``` Reading early data ------------------ Mbed TLS provides the mbedtls_ssl_read_early_data() API to read the early data that a TLS 1.3 server might receive during the TLS 1.3 handshake. While establishing a TLS 1.3 connection with a client using a combination of the mbedtls_ssl_handshake(), mbedtls_ssl_read() and mbedtls_ssl_write() APIs, the reception of early data is signaled by an API returning the MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA error code. Early data can then be read with the mbedtls_ssl_read_early_data() API. For example, a typical code to establish a TLS connection, where ssl is the SSL context to use: ``` while ((int ret = mbedtls_ssl_handshake(&ssl)) != 0) { if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { break; } } ``` could be adapted to handle early data in the following way: ``` size_t data_read_len = 0; while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) { if (ret == MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA) { ret = mbedtls_ssl_read_early_data(&ssl, buffer + data_read_len, sizeof(buffer) - data_read_len); if (ret < 0) { break; } data_read_len += ret; continue; } if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { break; } } ``` --- ### CONTRIBUTING Contributing ============ We gratefully accept bug reports and contributions from the community. All PRs are reviewed by the project team / community, and may need some modifications to be accepted. Quick Checklist for PR contributors ----------------------------------- More details on all of these points may be found in the sections below. - [Sign-off](#license-and-copyright): all commits must be signed off. - [Tests](#tests): please ensure the PR includes adequate tests. - [Changelog](#documentation): if needed, please provide a changelog entry. - [Backports](#long-term-support-branches): provide a backport if needed (it's fine to wait until the main PR is accepted). Coding Standards ---------------- - Contributions should include tests, as mentioned in the [Tests](#tests) and [Continuous Integration](#continuous-integration-tests) sections. Please check that your contribution passes basic tests before submission, and check the CI results after making a pull request. - The code should be written in a clean and readable style, and must follow [our coding standards](https://mbed-tls.readthedocs.io/en/latest/kb/development/mbedtls-coding-standards/). - The code should be written in a portable generic way, that will benefit the whole community, and not only your own needs. - The code should be secure, and will be reviewed from a security point of view as well. Making a Contribution --------------------- 1. [Check for open issues](https://github.com/Mbed-TLS/mbedtls/issues) or [start a discussion](https://lists.trustedfirmware.org/mailman3/lists/mbed-tls.lists.trustedfirmware.org) around a feature idea or a bug. 1. Fork the [Mbed TLS repository on GitHub](https://github.com/Mbed-TLS/mbedtls) to start making your changes. As a general rule, you should use the ["development" branch](https://github.com/Mbed-TLS/mbedtls/tree/development) as a basis. 1. Write a test which shows that the bug was fixed or that the feature works as expected. 1. Send a pull request (PR) and work with us until it gets merged and published. Contributions may need some modifications, so a few rounds of review and fixing may be necessary. See our [review process guidelines](https://mbed-tls.readthedocs.io/en/latest/reviews/review-for-contributors/). 1. For quick merging, the contribution should be short, and concentrated on a single feature or topic. The larger the contribution is, the longer it would take to review it and merge it. Backwards Compatibility ----------------------- The project aims to minimise the impact on users upgrading to newer versions of the library and it should not be necessary for a user to make any changes to their own code to work with a newer version of the library. Unless the user has made an active decision to use newer features, a newer generation of the library or a change has been necessary due to a security issue or other significant software defect, no modifications to their own code should be necessary. To achieve this, API compatibility is maintained between different versions of Mbed TLS on the main development branch and in LTS (Long Term Support) branches, as described in [BRANCHES.md](BRANCHES.md). To minimise such disruption to users, where a change to the interface is required, all changes to the ABI or API, even on the main development branch where new features are added, need to be justifiable by either being a significant enhancement, new feature or bug fix which is best resolved by an interface change. If there is an API change, the contribution, if accepted, will be merged only when there is a major release. No changes are permitted to the definition of functions in the public interface which will change the API. Instead the interface can only be changed by its extension. Where changes to an existing interface are necessary, functions in the public interface which need to be changed are marked as 'deprecated'. If there is a strong reason to replace an existing function with one that has a slightly different interface (different prototype, or different documented behavior), create a new function with a new name with the desired interface. Keep the old function, but mark it as deprecated. Periodically, the library will remove deprecated functions from the library which will be a breaking change in the API, but such changes will be made only in a planned, structured way that gives sufficient notice to users of the library. Long Term Support Branches -------------------------- Mbed TLS maintains several LTS (Long Term Support) branches, which are maintained continuously for a given period. The LTS branches are provided to allow users of the library to have a maintained, stable version of the library which contains only security fixes and fixes for other defects, without encountering additional features or API extensions which may introduce issues or change the code size or RAM usage, which can be significant considerations on some platforms. To allow users to take advantage of the LTS branches, these branches maintain backwards compatibility for both the public API and ABI. When backporting to these branches please observe the following rules: 1. Any change to the library which changes the API or ABI cannot be backported. 1. All bug fixes that correct a defect that is also present in an LTS branch must be backported to that LTS branch. If a bug fix introduces a change to the API such as a new function, the fix should be reworked to avoid the API change. API changes without very strong justification are unlikely to be accepted. 1. If a contribution is a new feature or enhancement, no backporting is required. Exceptions to this may be additional test cases or quality improvements such as changes to build or test scripts. It would be highly appreciated if contributions are backported to LTS branches in addition to the [development branch](https://github.com/Mbed-TLS/mbedtls/tree/development) by contributors. The list of maintained branches can be found in the [Current Branches section of BRANCHES.md](BRANCHES.md#current-branches). Tests ----- As mentioned, tests that show the correctness of the feature or bug fix should be added to the pull request, if no such tests exist. Mbed TLS includes a comprehensive set of test suites in the `tests/` directory that are dynamically generated to produce the actual test source files (e.g. `test_suite_ssl.c`). These files are generated from a `function file` (e.g. `suites/test_suite_ssl.function`) and a `data file` (e.g. `suites/test_suite_ssl.data`). The function file contains the test functions. The data file contains the test cases, specified as parameters that will be passed to the test function. [A Knowledge Base article describing how to add additional tests is available on the Mbed TLS website](https://mbed-tls.readthedocs.io/en/latest/kb/development/test_suites/). A test script `tests/scripts/basic-build-test.sh` is available to show test coverage of the library. New code contributions should provide a similar level of code coverage to that which already exists for the library. Sample applications, if needed, should be modified as well. Continuous Integration Tests ---------------------------- Once a PR has been made, the Continuous Integration (CI) tests are triggered and run. You should follow the result of the CI tests, and fix failures. It is advised to enable the [githooks scripts](https://github.com/Mbed-TLS/mbedtls/tree/development/tests/git-scripts) prior to pushing your changes, for catching some of the issues as early as possible. Documentation ------------- Mbed TLS is well documented, but if you think documentation is needed, speak out! 1. All interfaces should be documented through Doxygen. New APIs should introduce Doxygen documentation. 1. Complex parts in the code should include comments. 1. If needed, a Readme file is advised. 1. If a [Knowledge Base (KB)](https://mbed-tls.readthedocs.io/en/latest/kb/) article should be added, write this as a comment in the PR description. 1. A [ChangeLog](https://github.com/Mbed-TLS/mbedtls/blob/development/ChangeLog.d/00README.md) entry should be added for this contribution. License and Copyright --------------------- Unless specifically indicated otherwise in a file, Mbed TLS files are provided under a dual [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) OR [GPL-2.0-or-later](https://spdx.org/licenses/GPL-2.0-or-later.html) license. See the [LICENSE](LICENSE) file for the full text of these licenses. This means that users may choose which of these licenses they take the code under. Contributors must accept that their contributions are made under both the Apache-2.0 AND [GPL-2.0-or-later](https://spdx.org/licenses/GPL-2.0-or-later.html) licenses. All new files should include the standard SPDX license identifier where possible, i.e. "SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later". The copyright on contributions is retained by the original authors of the code. Where possible for new files, this should be noted in a comment at the top of the file in the form: "Copyright The Mbed TLS Contributors". When contributing code to us, the committer and all authors are required to make the submission under the terms of the [Developer Certificate of Origin](dco.txt), confirming that the code submitted can (legally) become part of the project, and is submitted under both the Apache-2.0 AND GPL-2.0-or-later licenses. This is done by including the standard Git `Signed-off-by:` line in every commit message. If more than one person contributed to the commit, they should also add their own `Signed-off-by:` line. --- ### SECURITY ## Reporting Vulnerabilities If you think you have found an Mbed TLS security vulnerability, then please send an email to the security team at . ## Security Incident Handling Process Our security process is detailed in our [security center](https://developer.trustedfirmware.org/w/mbed-tls/security-center/). Its primary goal is to ensure fixes are ready to be deployed when the issue goes public. ## Maintained branches Only the maintained branches, as listed in [`BRANCHES.md`](BRANCHES.md), get security fixes. Users are urged to always use the latest version of a maintained branch. ## Use of TF-PSA-Crypto Note that Mbed TLS uses the cryptography API provided by TF-PSA-Crypto. Its [threat model](https://github.com/Mbed-TLS/TF-PSA-Crypto/blob/development/SECURITY.md#threat-model) applies to all cryptographic operations performed by Mbed TLS. In particular, users of Mbed TLS should note the considerations around [block ciphers](https://github.com/Mbed-TLS/TF-PSA-Crypto/blob/development/SECURITY.md#block-ciphers) since they apply to the block ciphers used in TLS. ## Threat model We classify attacks based on the capabilities of the attacker. ### Remote attacks In this section, we consider an attacker who can observe and modify data sent over the network. This includes observing the content and timing of individual packets, as well as suppressing or delaying legitimate messages, and injecting messages. Mbed TLS aims to fully protect against remote attacks and to enable the user application in providing full protection against remote attacks. Said protection is limited to providing security guarantees offered by the protocol being implemented. (For example Mbed TLS alone won't guarantee that the messages will arrive without delay, as the TLS protocol doesn't guarantee that either.) ### Local attacks In this section, we consider an attacker who can run software on the same machine. The attacker has insufficient privileges to directly access Mbed TLS assets such as memory and files. #### Timing attacks The attacker is able to observe the timing of instructions executed by Mbed TLS by leveraging shared hardware that both Mbed TLS and the attacker have access to. Typical attack vectors include cache timings, memory bus contention and branch prediction. Mbed TLS provides limited protection against timing attacks. The cost of protecting against timing attacks widely varies depending on the granularity of the measurements and the noise present. Therefore the protection in Mbed TLS is limited. We are only aiming to provide protection against **publicly documented attack techniques**. As attacks keep improving, so does Mbed TLS's protection. Mbed TLS is moving towards a model of fully timing-invariant code, but has not reached this point yet. **Remark:** Timing information can be observed over the network or through physical side channels as well. Remote and physical timing attacks are covered in the [Remote attacks](remote-attacks) and [Physical attacks](physical-attacks) sections respectively. #### Local non-timing side channels The attacker code running on the platform has access to some sensor capable of picking up information on the physical state of the hardware while Mbed TLS is running. This could for example be an analogue-to-digital converter on the platform that is located unfortunately enough to pick up the CPU noise. Mbed TLS doesn't make any security guarantees against local non-timing-based side channel attacks. If local non-timing attacks are present in a use case or a user application's threat model, they need to be mitigated by the platform. #### Local fault injection attacks Software running on the same hardware can affect the physical state of the device and introduce faults. Mbed TLS doesn't make any security guarantees against local fault injection attacks. If local fault injection attacks are present in a use case or a user application's threat model, they need to be mitigated by the platform. ### Physical attacks In this section, we consider an attacker who has access to physical information about the hardware Mbed TLS is running on and/or can alter the physical state of the hardware (e.g. power analysis, radio emissions or fault injection). Mbed TLS doesn't make any security guarantees against physical attacks. If physical attacks are present in a use case or a user application's threat model, they need to be mitigated by physical countermeasures. ### Caveats #### Out-of-scope countermeasures Mbed TLS has evolved organically and a well defined threat model hasn't always been present. Therefore, Mbed TLS might have countermeasures against attacks outside the above defined threat model. The presence of such countermeasures don't mean that Mbed TLS provides protection against a class of attacks outside of the above described threat model. Neither does it mean that the failure of such a countermeasure is considered a vulnerability. #### Formatting of X509 data This section discusses limitations in how X.509 objects are processed. This applies to certificates, certificate signing requests (CSRs) and certificate revocation lists (CRLs). Mbed TLS does not check that they are strictly compliant with X.509 and other relevant standards. In the case of signed certificates and signed CRLs, the signing party is assumed to have performed this validation (and the certificate or CRL is trusted to be correctly formatted as long as the signature is correct). Similarly, CSRs are implicitly trusted by Mbed TLS to be standards-compliant. **Warning!** Mbed TLS must not be used to sign untrusted CSRs or CRLs unless extra validation is performed separately to ensure that they are compliant to the relevant specifications. This makes Mbed TLS on its own unsuitable for use in a Certificate Authority (CA). However, Mbed TLS aims to protect against memory corruption and other undefined behavior when parsing certificates, CSRs and CRLs. If a CSR or signed certificate causes undefined behavior when it is parsed by Mbed TLS, that is considered a security vulnerability. ---