This document describes how parts of the Mbed TLS functionality can be replaced at compile time to integrate the library on a platform.
This document is an overview. It is not exhaustive. Please consult the documentation of individual modules and read the library header files for more details.
Mbed TLS works out of the box on Unix/Linux/POSIX-like systems and on Windows. On embedded platforms, you may need to customize some aspects of how Mbed TLS interacts with the underlying platform. This section discusses the main areas that can be configured.
The platform module (
include/mbedtls/platform.h) controls how Mbed TLS accesses standard library features such as memory management (
exit. You can define custom functions instead of the ones from the C standard library through
MBEDTLS_PLATFORM_XXX options in the configuration file. Many options have two mechanisms: either define
MBEDTLS_PLATFORM_XXX_MACRO to the name of a function to call instead of the standard function
xxx, or define
MBEDTLS_PLATFORM_XXX_ALT and register an alternative implementation during the platform setup.
The storage of the non-volatile seed for random generation, enabled with
MBEDTLS_ENTROPY_NV_SEED, is also controlled via the platform module.
For timing functions, you can declare an alternative implementation of the timing module.
On multithreaded platforms, declare an alternative implementation of the threading module.
To configure entropy sources (hardware random generators), see the
MBEDTLS_ENTROPY_XXX options in the configuration file.
For networking, the
net_sockets module does not currently support alternative implementations. If this module does not work on your platform, disable
MBEDTLS_NET_C and use custom functions for TLS.
If your platform has a cryptographic accelerator, you can use it via a PSA driver or declare an alternative implementation of the corresponding module(s) or of specific functions. PSA drivers will ultimately replace the alternative implementation mechanism, but alternative implementation will remain supported in at least all Mbed TLS versions of the form 3.x. The interface of PSA drivers is currently still experimental and subject to change.
On platforms where a hardware cryptographic engine is present, you can implement a driver for this engine in the PSA interface. Drivers are supported for cryptographic operations with transparent keys (keys available in cleartext), for cryptographic operations with opaque keys (keys that are only available inside the cryptographic engine), and for random generation. Calls to
psa_xxx functions that perform cryptographic operations are directed to drivers instead of the built-in code as applicable. See the PSA cryptography driver interface specification, the Mbed TLS PSA driver developer guide and the Mbed TLS PSA driver integration guide for more information.
As of Mbed TLS 3.0, this interface is still experimental and subject to change, and not all operations support drivers yet. The configuration option
MBEDTLS_USE_PSA_CRYPTO causes parts of the
mbedtls_xxx API to use PSA crypto and therefore to support drivers, however it is not yet compatible with all drivers.
You can replace the code of some modules of Mbed TLS at compile time by a custom implementation. This is possible for low-level cryptography modules (symmetric algorithms, DHM, RSA, ECP, ECJPAKE) and for some platform-related modules (threading, timing). Such custom implementations are called “alternative implementations”, or “ALT implementations” for short.
The general principle of an alternative implementation is:
MBEDTLS_XXX_ALTin the compile-time configuration where XXX is the module name. For example,
MBEDTLS_AES_ALTfor an implementation of the AES module. This is in addition to enabling
xxx_alt.hthat defines the context type(s) used by the module. For example,
See https://tls.mbed.org/kb/development/hw_acc_guidelines for a more detailed guide.
Generally, alternative implementations can define their context types to any C type except incomplete and array types (although they would normally be
struct types). This section lists some known limitations where the context type needs to be a structure with certain fields.
Where a context type needs to have a certain field, the field must have the same type and semantics as in the built-in implementation, but does not need to be at the same position in the structure. Furthermore, unless otherwise indicated, only read access is necessary: the field can be
const, and modifications to it do not need to be supported. For example, if an alternative implementation of asymmetric cryptography uses a different representation of large integers, it is sufficient to provide a read-only copy of the fields listed here of type
mbedtls_aes_contextmust have the fields
mbedtls_dhm_contextmust have the fields
mbedtls_ecp_groupmust have the fields
MBEDTLS_PK_PARSE_EC_EXTENDEDis enabled, those fields must be writable, and
mbedtls_ecp_point_read_binary()must support a group structure where only
It must be possible to move a context object in memory (except during the execution of a library function that takes this context as an argument). (This is necessary, for example, to support applications that populate a context on the stack of an inner function and then copy the context upwards through the call chain, or applications written in a language with automatic memory management that can move objects on the heap.) That is, call sequences like the following must work:
mbedtls_xxx_context ctx1, ctx2; mbedtls_xxx_init(&ctx1); mbedtls_xxx_setup(&ctx1, …); ctx2 = ctx1; memset(&ctx1, 0, sizeof(ctx1)); mbedtls_xxx_do_stuff(&ctx2, …); mbedtls_xxx_free(&ctx2);
In practice, this means that a pointer to a context or to a part of a context does not remain valid across function calls. Alternative implementations do not need to support copying of contexts: contexts can only be cloned through explicit
In some cases, it is possible to replace a single function or a small set of functions instead of providing an alternative implementation of the whole module.
Options to replace individual functions of cryptographic modules generally have a name obtained by upper-casing the function name and appending
_ALT. If the function name contains
_ret, this is removed in the
_ALT symbol. When the corresponding option is enabled, the built-in implementation of the function will not be compiled, and you must provide an alternative implementation at link time.
For example, enable
MBEDTLS_AES_ENCRYPT_ALT at compile time and provide your own implementation of
mbedtls_aes_encrypt() to provide an accelerated implementation of AES encryption that is compatible with the built-in key schedule. If you wish to implement key schedule differently, you can also enable
MBEDTLS_AES_SETKEY_ENC_ALT and implement
Another example: enable
MBEDTLS_SHA256_PROCESS_ALT and implement
mbedtls_internal_sha256_process() to provide an accelerated implementation of SHA-256 and SHA-224.
Note that since alternative implementations of individual functions cooperate with the built-in implementation of other functions, you must use the same layout for context objects as the built-in implementation. If you want to use different context types, you need to provide an alternative implementation of the whole module.
Several platform functions can be reconfigured dynamically by following the process described here. To reconfigure how Mbed TLS calls the standard library function
MBEDTLS_PLATFORM_XXX_ALTat compile time.
mbedtls_xxxto an alternative implementation of
For example, to provide a custom
printf function at run time, enable
MBEDTLS_PLATFORM_PRINTF_ALT at compile time and assign to
mbedtls_printf during the initialization of your application.
MBEDTLS_PLATFORM_XXX_ALT does not change the behavior: by default,
mbedtls_xxx points to the standard function
Note that there are variations on the naming pattern. For example, some configurable functions are activated in pairs, such as
MBEDTLS_PLATFORM_MEMORY. Consult the documentation of individual configuration options and of the platform module for details.