66 KiB
Migrating from Mbed TLS 3.x to TF-PSA-Crypto 1.0
This guide details the steps required to migrate from Mbed TLS version 3.x to TF-PSA-Crypto version 1.0 or greater. TF-PSA-Crypto 1.0 introduces a new major version of the cryptography part of Mbed TLS, going together with Mbed TLS 4.0. Many interfaces have changed, so users and integrators might need to change their own code in order to make it work with TF-PSA-Crypto.
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. Some non-PSA APIs remain for features that PSA does not cover.
- In the same vein, third-party implementations of cryptographic mechanisms must be provided as PSA drivers: ALT implementations are no longer supported.
- In the same vein, the random generator configuration has been adapted and simplified.
- Some obsolete cryptographic mechanisms are no longer supported.
- The PSA PAKE interface has been updated to follow the final PSA specification.
CMake as the only build system
TF-PSA-Crypto uses CMake exclusively to configure and drive its build process. There is no support for the GNU Make and Microsoft Visual Studio project-based build systems as there is in Mbed TLS 3.x.
See the Compiling section in README.md for instructions on building the TF-PSA-Crypto library and tests with CMake.
Translating Make commands to CMake
With no GNU Make support, all build, test, and installation operations must 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 library, 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 library, 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 tfpsacrypto |
Build only the library. |
make tests |
cmake -S . -B build -DENABLE_PROGRAMS=Off && cmake --build build |
Build test suites. |
make programs |
cmake --build build --target tfpsacrypto-programs |
Build example programs. |
make apidoc |
cmake --build build --target tfpsacrypto-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 TF-PSA-Crypto 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_TF_PSA_CRYPTO_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 Mbed TLS project was split into two repositories:
- Mbed TLS: provides TLS and X.509 functionality.
- TF-PSA-Crypto: provides the standalone cryptography library, notably including the PSA Cryptography API.
If you use only the cryptography part, you should consider migrating to TF-PSA-Crypto.
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 present TF-PSA-Crypto repository.
| Original location in Mbed TLS tree | New location(s) | Notes |
|---|---|---|
library/* |
core/drivers/builtin/src/ |
Contains cryptographic, cryptographic-adjacent (e.g., ASN.1, Base64), and platform C modules and headers. |
include/mbedtls/* |
include/mbedtls/drivers/builtin/include/private/ |
Public headers moved to include/mbedtls; now internal headers moved to include/private. |
include/psa |
include/psa |
All PSA headers consolidated here. |
3rdparty/everest3rdparty/p256-m |
drivers/everestdrivers/p256-m |
Third-party crypto driver implementations. |
Configuration file split
All cryptography and platform configuration options have been moved from the Mbed TLS configuration file to include/psa/crypto_config.h, which is the configuration file of TF-PSA-Crypto. See Compile-time configuration for more details.
TF-PSA-Crypto also provides the scripts/config.py Python script to adjust your configuration. This script updates include/psa/crypto_config.h.
There have been significant changes in the cryptography configuration options:
- See psa-transition.md.
- See also the following sections:
Impact on some usages of the library
Linking directly to a built library
The TF-PSA-Crypto CMake build system provides the cryptography libraries under the name, libtfpsacrypto.<ext> in the core directory.
Thus both the name of the libraries and their location have changed compared to Mbed TLS.
You may also need to update include paths to the public header files, see File and Directory Relocations for details.
Using TF-PSA-Crypto as a CMake subproject
The base name of the static and shared cryptography libraries is now tfpsacrypto, formerly mbedcrypto.
As before, this base name is also the base name of CMake targets to build the libraries.
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 TF-PSA-Crypto as a CMake subproject:
programs/test/cmake_subproject
Using TF-PSA-Crypto as a CMake package
The same renaming applies to the cryptography library targets provided by the TF-PSA-Crypto CMake package.
The CMake package name has also changed from MbedTLS to TF-PSA-Crypto.
For example, the following CMake code:
find_package(MbedTLS REQUIRED)
target_link_libraries(myapp PRIVATE MbedTLS::mbedcrypto)
should be updated to:
find_package(TF-PSA-Crypto REQUIRED)
target_link_libraries(myapp PRIVATE TF-PSA-Crypto::tfpsacrypto)
You can also refer to the following example programs demonstrating how to consume TF-PSA-Crypto as a CMake package:
programs/test/cmake_packageprograms/test/cmake_package_install
Using the TF-PSA-Crypto pkg-config file
The TF-PSA-Crypto CMake build system provides the pkg-config file tfpsacrypto.pc, formerly mbedcrypto.pc. You will need to update the file name in your scripts.
Using TF-PSA-Crypto as an installed library
The TF-PSA-Crypto CMake build system installs the cryptography libraries libtfpsacrypto.<ext>, formerly libmbedcrypto.<ext>.
Thus, you will need to link against libtfpsacrypto.<ext> instead of libmbedcrypto.<ext>.
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 Private Declarations.
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 for the possible impacts on:
- Linking against the cryptography library or CMake targets.
- Using the TF-PSA-Crypto pkg-config file.
- Using TF-PSA-Crypto as an installed library.
Developer or package maintainers
If you build or distribute TF-PSA-Crypto:
- The build system is CMake. Makefiles and Visual Studio projects are not supported.
- Review File and directory relocations for updated paths.
- See Impact on usages of the library for the possible impacts on:
- Linking against the cryptography library or CMake targets.
- Using the TF-PSA-Crypto pkg-config file.
- Using TF-PSA-Crypto as an installed library.
- The configuration file is
include/psa/crypto_config.h(see Configuration file split). - If you want to distribute both the cryptography and the X.509 and/or TLS components, you need to package Mbed TLS together with its bundled TF-PSA-Crypto.
Platform Integrators
If you integrate TF-PSA-Crypto with a platform or hardware drivers:
- Platform-specific configuration options are now handled in
include/psa/crypto_config.h. - Review File and directory relocations for the location of platform components in TF-PSA-Crypto.
Compile-time configuration
Configuration file split
Whether you are using TF-PSA-Crypto as a standalone project or as part of Mbed TLS, all the configuration options that are relevant to TF-PSA-Crypto must be configured in one of its configuration files, namely:
TF_PSA_CRYPTO_CONFIG_FILE, if set on the preprocessor command line;- otherwise
<psa/crypto_config.h>; - additionally
TF_PSA_CRYPTO_USER_CONFIG_FILE, if set.
The macros MBEDTLS_PSA_CRYPTO_CONFIG_FILE and MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE are no longer recognized. Use TF_PSA_CRYPTO_CONFIG_FILE and TF_PSA_CRYPTO_USER_CONFIG_FILE instead.
Configuration options that are relevant to X.509 or TLS should still be set in the Mbed TLS configuration file (MBEDTLS_CONFIG_FILE or <mbedtls/mbedtls_config.h>, plus MBEDTLS_USER_CONFIG_FILE if it is set). However, you can define all the 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, <psa/crypto_config.h> is no longer limited to PSA_WANT_xxx options.
Note that many options related to cryptography have changed; this is covered in other sections of this document.
Split of build_info.h and version.h
TF-PSA-Crypto has a header file <tf-psa-crypto/build_info.h> which includes the configuration file and provides the adjusted configuration macros, similar to <mbedtls/build_info.h> in Mbed TLS.
TF-PSA-Crypto exposes its version through <tf-psa-crypto/version.h>, similar to <mbedtls/version.h> 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 of the configuration as adjusted by mbedtls/build_info.h, not properties that the user configuration is expected to meet.
PSA as the only cryptography API
The PSA Crypto API is now the only API for cryptographic primitives.
For general guidance on migrating to the PSA Crypto API, consult the
PSA transition guide. Note that most of the suggested migrations also work in the Mbed TLS 3.6 long-time support branch, provided that the library is configured suitably (MBEDTLS_USE_PSA_CRYPTO and MBEDTLS_PSA_CRYPTO_CONFIG enabled).
Impact on application code
The PK module uses PSA for cryptographic operations. 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.
A few functions take different parameters to migrate them to the PSA API. See “Function prototype changes”.
No random generator instantiation
Formerly, applications using various cryptographic features 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, many of which are related to the move from RNG callbacks to a global RNG.
Impact on the library configuration
The choice of supported cryptographic mechanisms is now based on PSA_WANT_xxx macros instead of legacy configuration macros such as MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, etc. This corresponds to the behavior of Mbed TLS 3.x when MBEDTLS_PSA_CRYPTO_CONFIG is enabled. In effect, MBEDTLS_PSA_CRYPTO_CONFIG is now always enabled.
For information on which configuration macros are affected and their new PSA equivalent, consult the PSA transition guide.
See also the section “Random number generation configuration”.
No direct access to specific algorithms
All modules that are specific to a particular cryptographic mechanism have been removed from the API. There are a few exceptions, for some mechanisms that are not yet present in the PSA API: mbedtls/lms.h and mbedtls/nist_kw.h remain part of the API.
The high-level legacy module mbedtls/cipher.h has also been removed. The high-level legacy modules mbedtls/md.h and mbedtls/pk.h remain present with reduced functionality (see “Reduced md.h” and “PK module”). TF-PSA-Crypto also retains non-PSA interfaces for data formats, platform support and miscellaneous utility functions.
In full detail, the following header files, and their former content, are no longer available.
everest/Hacl_Curve25519.h
everest/everest.h
everest/kremlib.h
everest/kremlib/*.h
everest/kremlin/*.h
everest/kremlin/internal/*.h
everest/vs2013/*.h
everest/x25519.h
mbedtls/aes.h
mbedtls/aria.h
mbedtls/bignum.h
mbedtls/block_cipher.h
mbedtls/camellia.h
mbedtls/ccm.h
mbedtls/chacha20.h
mbedtls/chachapoly.h
mbedtls/cipher.h
mbedtls/cmac.h
mbedtls/ctr_drbg.h
mbedtls/des.h
mbedtls/dhm.h
mbedtls/ecdh.h
mbedtls/ecdsa.h
mbedtls/ecjpake.h
mbedtls/ecp.h
mbedtls/entropy.h
mbedtls/gcm.h
mbedtls/hkdf.h
mbedtls/hmac_drbg.h
mbedtls/md5.h
mbedtls/pkcs12.h
mbedtls/pkcs5.h
mbedtls/poly1305.h
mbedtls/ripemd160.h
mbedtls/rsa.h
mbedtls/sha1.h
mbedtls/sha256.h
mbedtls/sha3.h
mbedtls/sha512.h
If your application was using functions from these headers, please see
docs/psa-transition.md for ways to migrate to
the PSA API instead.
Some of the associated types still need to be visible to the compiler. For example, mbedtls_aes_context is used to define psa_cipher_operation_t. These types are still available when building application code, but we recommend that you no longer use them directly. The structure, the semantics and even the existence of these types may change without notice.
Other removed functions related to low-level cryptography APIs
The functions mbedtls_ecc_group_to_psa() and mbedtls_ecc_group_from_psa() have been removed. They are no longer meaningful since the low-level representation of elliptic curve groups is no longer part of the API.
Removal of alternative cryptographic module implementations
TF-PSA-Crypto no longer supports replacing a whole cryptographic module or an individual cryptographic function by defining a macro MBEDTLS_xxx_ALT and providing a custom implementation of the same interface. Instead, use PSA transparent drivers (i.e. accelerator drivers).
The PK module no longer supports MBEDTLS_PK_RSA_ALT. Instead, for opaque keys (RSA or otherwise), use PSA opaque drivers.
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 TF-PSA-Crypto 1.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 asprivate_field_namein 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 English error messages
TF-PSA-Crypto does not provide English text corresponding to error codes. The functionality provided by mbedtls_strerror() in mbedtls/error.h is still present in Mbed TLS.
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 (TF-PSA-Crypto 1.0) |
|---|---|
MBEDTLS_ERR_AES_BAD_INPUT_DATA |
PSA_ERROR_INVALID_ARGUMENT |
MBEDTLS_ERR_ARIA_BAD_INPUT_DATA |
PSA_ERROR_INVALID_ARGUMENT |
MBEDTLS_ERR_ASN1_ALLOC_FAILED |
PSA_ERROR_INSUFFICIENT_MEMORY |
MBEDTLS_ERR_ASN1_BUF_TOO_SMALL |
PSA_ERROR_BUFFER_TOO_SMALL |
MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL |
PSA_ERROR_BUFFER_TOO_SMALL |
MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA |
PSA_ERROR_INVALID_ARGUMENT |
MBEDTLS_ERR_CCM_AUTH_FAILED |
PSA_ERROR_INVALID_SIGNATURE |
MBEDTLS_ERR_CCM_BAD_INPUT_DATA |
PSA_ERROR_INVALID_ARGUMENT |
MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA |
PSA_ERROR_INVALID_ARGUMENT |
MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED |
PSA_ERROR_INVALID_SIGNATURE |
MBEDTLS_ERR_CIPHER_ALLOC_FAILED |
PSA_ERROR_INSUFFICIENT_MEMORY |
MBEDTLS_ERR_CIPHER_AUTH_FAILED |
PSA_ERROR_INVALID_SIGNATURE |
MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA |
PSA_ERROR_INVALID_ARGUMENT |
MBEDTLS_ERR_CIPHER_INVALID_PADDING |
PSA_ERROR_INVALID_PADDING |
MBEDTLS_ERR_ECP_ALLOC_FAILED |
PSA_ERROR_INSUFFICIENT_MEMORY |
MBEDTLS_ERR_ECP_BAD_INPUT_DATA |
PSA_ERROR_INVALID_ARGUMENT |
MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL |
PSA_ERROR_BUFFER_TOO_SMALL |
MBEDTLS_ERR_ECP_IN_PROGRESS |
PSA_OPERATION_INCOMPLETE |
MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH |
PSA_ERROR_INVALID_SIGNATURE |
MBEDTLS_ERR_ECP_VERIFY_FAILED |
PSA_ERROR_INVALID_SIGNATURE |
MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED |
PSA_ERROR_CORRUPTION_DETECTED |
MBEDTLS_ERR_ERROR_GENERIC_ERROR |
PSA_ERROR_GENERIC_ERROR |
MBEDTLS_ERR_GCM_AUTH_FAILED |
PSA_ERROR_INVALID_SIGNATURE |
MBEDTLS_ERR_GCM_BAD_INPUT |
PSA_ERROR_INVALID_ARGUMENT |
MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL |
PSA_ERROR_BUFFER_TOO_SMALL |
MBEDTLS_ERR_LMS_ALLOC_FAILED |
PSA_ERROR_INSUFFICIENT_MEMORY |
MBEDTLS_ERR_LMS_BAD_INPUT_DATA |
PSA_ERROR_INVALID_ARGUMENT |
MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL |
PSA_ERROR_BUFFER_TOO_SMALL |
MBEDTLS_ERR_MD_ALLOC_FAILED |
PSA_ERROR_INSUFFICIENT_MEMORY |
MBEDTLS_ERR_MD_BAD_INPUT_DATA |
PSA_ERROR_INVALID_ARGUMENT |
MBEDTLS_ERR_MPI_ALLOC_FAILED |
PSA_ERROR_INSUFFICIENT_MEMORY |
MBEDTLS_ERR_MPI_BAD_INPUT_DATA |
PSA_ERROR_INVALID_ARGUMENT |
MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL |
PSA_ERROR_BUFFER_TOO_SMALL |
MBEDTLS_ERR_OID_NOT_FOUND |
PSA_ERROR_NOT_SUPPORTED |
MBEDTLS_ERR_PEM_ALLOC_FAILED |
PSA_ERROR_INSUFFICIENT_MEMORY |
MBEDTLS_ERR_PEM_BAD_INPUT_DATA |
PSA_ERROR_INVALID_ARGUMENT |
MBEDTLS_ERR_PK_ALLOC_FAILED |
PSA_ERROR_INSUFFICIENT_MEMORY |
MBEDTLS_ERR_PK_BAD_INPUT_DATA |
PSA_ERROR_INVALID_ARGUMENT |
MBEDTLS_ERR_PK_BUFFER_TOO_SMALL |
PSA_ERROR_BUFFER_TOO_SMALL |
MBEDTLS_ERR_PK_SIG_LEN_MISMATCH |
PSA_ERROR_INVALID_SIGNATURE |
MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA |
PSA_ERROR_INVALID_ARGUMENT |
MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED |
PSA_ERROR_NOT_SUPPORTED |
MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED |
PSA_ERROR_HARDWARE_FAILURE |
MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA |
PSA_ERROR_INVALID_ARGUMENT |
MBEDTLS_ERR_RSA_BAD_INPUT_DATA |
PSA_ERROR_INVALID_ARGUMENT |
MBEDTLS_ERR_RSA_INVALID_PADDING |
PSA_ERROR_INVALID_PADDING |
MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE |
PSA_ERROR_BUFFER_TOO_SMALL |
MBEDTLS_ERR_SHA1_BAD_INPUT_DATA |
PSA_ERROR_INVALID_ARGUMENT |
MBEDTLS_ERR_SHA256_BAD_INPUT_DATA |
PSA_ERROR_INVALID_ARGUMENT |
MBEDTLS_ERR_SHA3_BAD_INPUT_DATA |
PSA_ERROR_INVALID_ARGUMENT |
MBEDTLS_ERR_SHA512_BAD_INPUT_DATA |
PSA_ERROR_INVALID_ARGUMENT |
Feature removals
Removal of self-test interfaces
TF-PSA-Crypto 1.0 does not provide a ready-made self-test interface; one may be added in a future version of the library.
If you need self-tests for compliance, you may perform them by invoking normal API functions with sample data.
As a consequence, the compilation option MBEDTLS_SELF_TEST does not provide direct benefits in TF-PSA-Crypto 1.0. However, it allows the sample program programs/test/selftest.c in Mbed TLS to run self tests of cryptographic mechanisms.
Removed hardware support
Acceleration for VIA Padlock (MBEDTLS_PADLOCK_C) is no longer provided.
The deprecated and incomplete support for dynamic registration of secure element drivers (MBEDTLS_PSA_CRYPTO_SE_C) has been removed. Use compile-time secure element drivers instead.
See also the removal of ALT interfaces.
Removed obsolete cryptographic mechanisms
Some obsolescent cryptographic mechanisms have been removed:
- The library no longer supports DES (including 3DES). All supported block ciphers now have 128-bit blocks. As a consequence, the PKCS12 module, which provided the obsolete PBE mode for private key encryption that does not support stronger ciphers, has been removed.
- The library no longer supports elliptic curves whose size is 224 bits or less. The following curves are no longer supported: secp192r1, secp192k1, secp224k1, secp224r1. Use larger curves such as secp256r1.
Removed obsolete PSA functions
Some PSA Crypto API functions dating back from before the 1.0 version of the API, or that were experimental, have been removed:
psa_open_key(),psa_close_key(), and auxiliary functions and macros related to handles. Persistent keys are opened implicitly since Mbed TLS 2.25.psa_set_key_domain_parameters(),psa_get_key_domain_parameters()and related macros. This feature was primarily intended to support custom finite-field Diffie-Hellman (FFDH) groups, but this was never implemented. To generate an RSA key with a custom public exponent, usepsa_generate_key_custom(), introduced in Mbed TLS 3.6.1.psa_generate_key_ext(),psa_key_derivation_output_key_extand related types and macros. Usepsa_generate_key_custom()orpsa_key_derivation_output_key_custom()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 LMS or PK modules must call psa_crypto_init() before calling any of the functions listed here.
RNG removal in LMS
The following function prototypes have been changed in mbedtls/lms.h:
int mbedtls_lms_generate_private_key(mbedtls_lms_private_t *ctx, mbedtls_lms_algorithm_type_t type, mbedtls_lmots_algorithm_type_t otstype,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
const unsigned char *seed, size_t seed_size);
int mbedtls_lms_sign(mbedtls_lms_private_t *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
const unsigned char *msg, unsigned int msg_size, unsigned char *sig, size_t sig_size, size_t *sig_len);
to
int mbedtls_lms_generate_private_key(mbedtls_lms_private_t *ctx, mbedtls_lms_algorithm_type_t type, mbedtls_lmots_algorithm_type_t otstype,
const unsigned char *seed, size_t seed_size);
int mbedtls_lms_sign(mbedtls_lms_private_t *ctx,
const unsigned char *msg, unsigned int msg_size, unsigned char *sig, size_t sig_size, size_t *sig_len);
RNG removal in PK
The following function prototypes have been changed in mbedtls/pk.h:
int mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, unsigned char *sig, size_t sig_size, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
mbedtls_pk_restart_ctx *rs_ctx);
int mbedtls_pk_check_pair(const mbedtls_pk_context *pub, const mbedtls_pk_context *prv,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng);
int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, unsigned char *sig, size_t sig_size, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type, mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, unsigned char *sig, size_t sig_size, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng);
int mbedtls_pk_parse_key(mbedtls_pk_context *ctx, const unsigned char *key, size_t keylen, const unsigned char *pwd, size_t pwdlen,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
int mbedtls_pk_parse_keyfile(mbedtls_pk_context *ctx, const char *path, const char *password,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
typedef int (*mbedtls_pk_rsa_alt_sign_func)(void *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, unsigned char *sig);
to
int mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, unsigned char *sig, size_t sig_size, size_t *sig_len,
mbedtls_pk_restart_ctx *rs_ctx);
int mbedtls_pk_check_pair(const mbedtls_pk_context *pub, const mbedtls_pk_context *prv);
int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, unsigned char *sig, size_t sig_size, size_t *sig_len);
int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type, mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, unsigned char *sig, size_t sig_size, size_t *sig_len);
int mbedtls_pk_parse_key(mbedtls_pk_context *ctx, const unsigned char *key, size_t keylen, const unsigned char *pwd, size_t pwdlen);
int mbedtls_pk_parse_keyfile(mbedtls_pk_context *ctx, const char *path, const char *password);
typedef int (*mbedtls_pk_rsa_alt_sign_func)(void *ctx,
mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, unsigned char *sig);
Changes to NIST_KW
The NIST_KW module remains part of TF-PSA-Crypto, since it does not have a PSA equivalent yet. However, its interface has changed, to use PSA key identifiers instead of a plaintext key via a custom context.
The following function prototypes have been changed in mbedtls/nist_kw.h:
int mbedtls_nist_kw_wrap(mbedtls_nist_kw_context *ctx,
mbedtls_nist_kw_mode_t mode,
const unsigned char *input, size_t in_len,
unsigned char *output, size_t *out_len, size_t out_size);
int mbedtls_nist_kw_unwrap(mbedtls_nist_kw_context *ctx,
mbedtls_nist_kw_mode_t mode,
const unsigned char *input, size_t in_len,
unsigned char *output, size_t *out_len, size_t out_size);
to
psa_status_t mbedtls_nist_kw_wrap(mbedtls_svc_key_id_t key,
mbedtls_nist_kw_mode_t mode,
const unsigned char *input, size_t input_length,
unsigned char *output, size_t output_size,
size_t *output_length);
psa_status_t mbedtls_nist_kw_unwrap(mbedtls_svc_key_id_t key,
mbedtls_nist_kw_mode_t mode,
const unsigned char *input, size_t input_length,
unsigned char *output, size_t output_size,
size_t *output_length);
Note that in addition to the change to keys, the last two parameters for the output buffer size and the length of the actual output have been swapped, to align the order of parameters with PSA Crypto APIs.
The type mbedtls_nist_kw_context and the functions mbedtls_nist_kw_init(), mbedtls_nist_kw_free() and mbedtls_nist_kw_setkey() have been removed, since the interface no longer involves a specific context object for NIST_KW.
Also, the function mbedtls_nist_kw_self_test() has been removed. TF-PSA-Crypto 1.0 does not provide a ready-made self-test interface; one may be added in a future version of the library.
Changes to ASN.1 functions
As a consequence of the removal of the type mbedtls_mpi (provided by mbedtls/bignum.h) from public interfaces, the ASN.1 functions to parse and write integers have changed.
The following functions have been removed from the API:
// mbedtls/asn1.h
int mbedtls_asn1_get_mpi(unsigned char **p, const unsigned char *end,
mbedtls_mpi *X);
// mbedtls/asn1write.h
int mbedtls_asn1_write_mpi(unsigned char **p, const unsigned char *start,
const mbedtls_mpi *X);
You can use the following new functions instead:
// mbedtls/asn1.h
int mbedtls_asn1_get_integer(unsigned char **p, const unsigned char *end,
unsigned char **head, size_t *length);
// mbedtls/asn1write.h
int mbedtls_asn1_write_integer(unsigned char **p,
unsigned char *start,
const unsigned char *integer,
size_t integer_length);
Both new functions use a big-endian byte buffer as the representation.
Note some differences in the semantics of the new parsing function:
mbedtls_asn1_get_integer()rejects negative integers. (mbedtls_asn1_get_mpi()misparsed them, using the sign bit as a value bit).mbedtls_asn1_get_integer()does not allocate memory. It returns a pointer inside the ASN.1 representation.
Threading platform abstraction
Extension to condition variables
The threading abstraction now includes primitives for condition variables in addition to mutexes.
As before, implementations of MBEDTLS_THREADING_ALT need to provide a header file "threading_alt.h", and to call the function mbedtls_threading_set_alt() before any call to other TF-PSA-Crypto or Mbed TLS functions. The header file "threading_alt.h" now needs to define the following elements:
- The type
mbedtls_platform_mutex_t, which is the type of mutex arguments passed to the platform functions. This type is now distinct from the typembedtls_threading_mutex_twhich library code and applications use. - The type
mbedtls_platform_condition_variable_t, which is the type of condition variable arguments passed to the platform functions.
Changes to the mutex primitives
The type of mutex objects provided by the platform functions is now called mbedtls_platform_mutex_t, distinct from the API type mbedtls_threading_mutex_t.
The mutex_init primitive now returns a status code instead of void.
The documentation in include/mbedtls/threading.h now clarifies the expectations on mutex primitives. These expectations are somewhat relaxed from the mostly undocumented expectations in previous versions: mutex functions other than mutex_init can now assume that the mutex has been successfully initialized.
Platform threading primitives should now return the following error codes:
MBEDTLS_ERR_THREADING_USAGE_ERRORto report a runtime failure (renamed fromMBEDTLS_ERR_THREADING_MUTEX_ERROR, which is now an alias provided only for backward compatibility).PSA_ERROR_BAD_STATEonly to report a library state error. If an error is detected in the state of a synchronization object, please returnMBEDTLS_ERR_THREADING_USAGE_ERRORinstead.PSA_ERROR_INSUFFICIENT_MEMORYto report resource exhaustion.
Random number generation configuration
TF-PSA-Crypto no longer exposes the internals of the PSA random number generator. The entropy, CTR_DRBG, and HMAC_DRBG modules from Mbed TLS 3.6 are now for internal use only. As a result, their configuration has been updated, both to simplify them and to prepare for PSA entropy and random number generation drivers, which will be introduced in a future minor release.
The overall structure of the random number generator in TF-PSA-Crypto remains the same as in Mbed TLS 3.x. It consists of either:
- an external random number generator (when
MBEDTLS_PSA_CRYPTO_EXTERNAL_RNGis enabled), or - a deterministic random number generator (CTR_DRBG or HMAC_DRBG) seeded with entropy by the entropy module.
Entropy configuration
TF-PSA-Crypto does not expose an entropy interface to applications. The entropy module of Mbed TLS 3.6 is now for internal use only. As a consequence, its configuration has changed, both to simplify it and to prepare for PSA entropy drivers which will be added in a future minor release.
If you have a fast cryptographic-quality external random generator
If you have a fast, cryptographic-quality source of random data, enable MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG and provide the callback function mbedtls_psa_external_get_random(). This is unchanged since Mbed TLS 2.26.
If the built-in entropy source works for you
TF-PSA-Crypto, like Mbed TLS, recognizes the system entropy sources on some popular operating systems, and enables them by default. If you are writing your own configuration, you now need to define the option MBEDTLS_PSA_BUILTIN_GET_ENTROPY. (This is different from Mbed TLS 2.x and 3.x, where the built-in entropy sources were included unless the option MBEDTLS_NO_PLATFORM_ENTROPY was defined.)
If you have a custom entropy source
To provide a custom entropy source, disable MBEDTLS_PSA_BUILTIN_GET_ENTROPY and enable MBEDTLS_PSA_DRIVER_GET_ENTROPY. You will need to provide the callback function mbedtls_platform_get_entropy(). See “Custom entropy collector” below for more details.
If you have no entropy source
If your hardware does not have any entropy source, you can use a non-volatile RNG seed which is injected from a trusted external source during device manufacturing or provisioning. Enable the option MBEDTLS_ENTROPY_NV_SEED, which is unchanged from previous versions of the library.
In TF-PSA-Crypto, when the non-volatile seed is the only (pseudo) entropy source, you also need to enable the option MBEDTLS_ENTROPY_NO_SOURCES_OK.
Comparison of entropy source configurations
TF-PSA-Crypto 1.0 supports the same entropy sources as Mbed TLS 3.6, but the way to configure them has changed.
- The negative option
MBEDTLS_NO_PLATFORM_ENTROPYto disable the default entropy collector for Unix-like and Windows platforms no longer exists. It has been replaced by the positive optionMBEDTLS_PSA_BUILTIN_GET_ENTROPY, which is enabled by default. - The option
MBEDTLS_ENTROPY_HARDWARE_ALT, which allows you to provide a custom entropy collector, has been renamed toMBEDTLS_PSA_DRIVER_GET_ENTROPY. This replacesMBEDTLS_ENTROPY_HARDWARE_ALT. The callback has a different name and prototype as described in “Custom hardware collector”. - The option
MBEDTLS_ENTROPY_NV_SEEDto enable a non-volatile seed is unchanged. However, if this is your only entropy source, you must now enable the new optionMBEDTLS_ENTROPY_NO_SOURCES_OK.
The following table describes common configurations.
| Configuration | Mbed TLS 3.6 | TF-PSA-Crypto 1.0 |
|---|---|---|
| Unix, Linux, Windows | (default) | (default) |
| Embedded platform |
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_HARDWARE_ALT
|
#undef MBEDTLS_PSA_BUILTIN_GET_ENTROPY
#define MBEDTLS_PSA_DRIVER_GET_ENTROPY
|
| Fast external crypto RNG |
#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
#undef MBEDTLS_ENTROPY_C
#undef MBEDTLS_CTR_DRBG_C
|
#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
#undef MBEDTLS_ENTROPY_C
#undef MBEDTLS_CTR_DRBG_C
|
| NV seed only |
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_NV_SEED
|
#undef MBEDTLS_PSA_BUILTIN_GET_ENTROPY
#define MBEDTLS_ENTROPY_NV_SEED
#define MBEDTLS_ENTROPY_NO_SOURCES_OK
|
| No entropy at all |
#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
|
not supported |
Custom entropy collector
The custom entropy collector callback function has changed, to make it match the upcoming PSA entropy driver specification.
Formerly, the callback was enabled by MBEDTLS_ENTROPY_HARDWARE_ALT and had the following prototype:
// from <entropy_poll.h>
int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len,
size_t *olen);
The new callback is enabled by MBEDTLS_PSA_DRIVER_GET_ENTROPY and has the following prototype:
// from <mbedtls/platform.h>
int mbedtls_platform_get_entropy(psa_driver_get_entropy_flags_t flags,
size_t *estimate_bits,
unsigned char *output, size_t output_size);
The data parameter was previously always NULL, and has been removed.
The new parameter flags is a bit-mask of flags that allows the caller to request special behaviors, such as avoiding blocking. The callback should return PSA_ERROR_NOT_SUPPORTED if it sees a flag that it does not support. As of TF-PSA-Crypto 1.0, flags is always 0.
The former callback could return less entropy than expected by only filling part of the buffer, and setting *olen to a value that is less than output_size. The new callback does not have an olen parameter, and the caller now reads the whole buffer. The new parameter estimate_bits is intended to allow the callback to report that it has accumulated less entropy than expected. However, this is not supported yet in TF-PSA-Crypto 1.0.
The new output parameter estimate_bits is the amount of entropy that the callback has placed in the output buffer. As of TF-PSA-Crypto 1.0, the output must have full entropy, thus estimate_bits must be equal to 8 * output_size. A future version of TF-PSA-Crypto will allow entropy sources to report smaller amounts.
To indicate that entropy is not currently available, the legacy error code MBEDTLS_ERR_ENTROPY_SOURCE_FAILED has been replaced by PSA_ERROR_INSUFFICIENT_ENTROPY.
Removed entropy options
The option MBEDTLS_ENTROPY_MIN_HARDWARE has been removed. The entropy module requests the amount that it needs for the chosen security strength.
The option MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES has removed since it is no longer meaningful, now that the entropy module is private. TF-PSA-Crypto 1.0 does not support platforms without an entropy source. This ability will be reintroduced in a future minor release.
PSA entropy injection
The configuration option MBEDTLS_PSA_INJECT_ENTROPY has been removed. TF-PSA-Crypto 1.0 does not provide a way to store an entropy seed in the key store. This will be reimplemented in a future minor version.
Configuration of the DRBG
As in previous versions of Mbed TLS, the PSA random generator in TF-PSA-Crypto uses CTR_DRBG with AES if MBEDTLS_CTR_DRBG_C is enabled, and HMAC_DRBG otherwise (requiring MBEDTLS_HMAC_DRBG_C to be enabled).
The DRBG modules are not exposed directly, they are only used internally.
In addition to the choice of DRBG module and entropy sources, the built-in random number generator is now configured through only three options:
MBEDTLS_PSA_CRYPTO_RNG_HASH: Selects the hash algorithm used by the entropy and HMAC_DRBG modules. This option replaces bothMBEDTLS_PSA_HMAC_DRBG_MD_TYPEandMBEDTLS_ENTROPY_FORCE_SHA256.MBEDTLS_PSA_RNG_RESEED_INTERVAL: Sets the reseed interval for both CTR_DRBG and HMAC_DRBG. It replacesMBEDTLS_CTR_DRBG_RESEED_INTERVALandMBEDTLS_HMAC_DRBG_RESEED_INTERVAL.MBEDTLS_PSA_CRYPTO_RNG_STRENGTH: Specifies the security strength in bits. The default is 256 bits. If you previously enabledMBEDTLS_CTR_DRBG_USE_128_BIT_KEYin Mbed TLS 3.6, you should now setMBEDTLS_PSA_CRYPTO_RNG_STRENGTHto 128, although this is not recommended.
The option MBEDTLS_ENTROPY_C has been removed. The entropy module is now automatically enabled when MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is disabled.
The following Mbed TLS 3.6 configuration options have been removed without any counterpart in TF-PSA-Crypto. Their corresponding APIs were also removed, making these options no longer relevant:
MBEDTLS_ENTROPY_MAX_GATHER, MBEDTLS_ENTROPY_MAX_SOURCES, MBEDTLS_CTR_DRBG_ENTROPY_LEN, MBEDTLS_CTR_DRBG_MAX_INPUT, MBEDTLS_CTR_DRBG_MAX_REQUEST, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, MBEDTLS_HMAC_DRBG_MAX_INPUT, MBEDTLS_HMAC_DRBG_MAX_REQUEST, and MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT.
Reduced md.h
PSA is now the preferred interface for computing hashes and HMAC. See “Hashes and MAC” in the PSA transition guide for more information.
TF-PSA-Crypto 1.x still has a header file <mbedtls/md.h> to facilitate the transition. Its functionality is limited to calculating hashes:
mbedtls_md_setup()now requires thehmacparameter to be 0. Use the PSA API for HMAC calculations.- The HMAC functions
mbedtls_md_hmac_xxx()are no longer available. - The metadata functions
mbedtls_md_list(),mbedtls_md_info_from_string(),mbedtls_md_get_name()andmbedtls_md_info_from_ctx()have been removed. The library does not associate names to individual algorithms any longer. - The function
mbedtls_md_file()has been removed. To hash a file, load it into memory manually. Load it piecewise and callmbedtls_md_update()orpsa_hash_update()in a loop if the file may be large.
PK module
The PK module for asymmetric cryptography is still present in TF-PSA-Crypto 1.x, but with a somewhat reduced scope compared to Mbed TLS. The main goal of PK is now to parse and format key pairs and public keys. PK also retains signature functions, to facilitate the transition from previous versions. The main differences compared to Mbed TLS 3.6 and below are:
- PK objects no longer expose the underlying representation. It is now unspecified in most cases whether a PK object stores key material directly, or a PSA key identifier.
- PK objects no longer have any policy attached to them. This mostly affects RSA keys, which no longer “remember” whether they are meant to be used with PKCS#1v1.5 or PSS/OAEP.
Changes to PK metadata
The type mbedtls_pk_type_t has been removed from the API. This type could convey different kinds of information, depending on where it was used:
-
Information about the representation of a PK context (distinguishing between transparent and opaque objects containing the same type of key). This information is no longer exposed.
-
Which signature algorithm to use (distinguishing between PKCS#1v1.5 and PSS for RSA keys), mostly for the sake of X.509. This information is now represented as
mbedtls_pk_sigalg_t, using enum constants with tweaked names:Old mbedtls_pk_type_tnameNew mbedtls_pk_sigalg_tnameMBEDTLS_PK_NONEMBEDTLS_PK_SIGALG_NONEMBEDTLS_PK_RSAMBEDTLS_PK_SIGALG_RSA_PKCS1V15MBEDTLS_PK_RSASSA_PSSMBEDTLS_PK_SIGALG_RSA_PSSMBEDTLS_PK_ECDSAorMBEDTLS_PK_ECKEYMBEDTLS_PK_SIGALG_ECDSA -
Policy information after parsing a key (only relevant for ECC keys marked as ECDH-only). This is now tracked internally and reflected in rejecting the key for signature or verification in
mbedtls_pk_get_psa_attributes()and in operation functions.
As a consequence, the functions mbedtls_pk_get_type(), mbedtls_pk_get_name() and mbedtls_pk_info_from_type() and have been removed. The type mbedtls_pk_info_t is no longer part of the API.
The function mbedtls_pk_get_len() has also been removed. It was not very meaningful since it did not convey the length of the key representation, but the size in bytes of the representation of one number associated with the key. As before, you can use mbedtls_pk_get_bitlen() to get the key size in the usual cryptographic sense. The size of a formatted key representation depends on the format, and there is no API function to determine it. (For the short export formats of PSA, you can use macros such as PSA_EXPORT_KEY_OUTPUT_SIZE(), PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(), PSA_EXPORT_KEY_PAIR_MAX_SIZE, PSA_EXPORT_PUBLIC_KEY_MAX_SIZE.)
Checking the capabilities of a PK context
The function mbedtls_pk_can_do(), based on the polysemic mbedtls_pk_type_t, has been removed. The function mbedtls_pk_can_do_ext(), based on PSA metadata, has been renamed to mbedtls_pk_can_do_psa(). It now supports public-key operations as well as private-key operations.
Loss of policy information for RSA keys
The PK module no longer partially keeps track of whether an RSA key is intended for use with PKCS#1v1.5 or PKCS#1v2.1 (PSS or OAEP) algorithms. Functions that consume a PK object (mbedtls_pk_get_psa_attributes(), mbedtls_pk_sign(), mbedtls_pk_verify()) now always default to PKCS#1v1.5, except for PK contexts populated with mbedtls_pk_wrap_psa() where they use the primary algorithm in the key's policy.
Note in particular that the functions mbedtls_pk_copy_from_psa() and mbedtls_pk_copy_public_from_psa() are now equivalent to exporting and re-importing the key, losing all policy information. For example, calling mbedtls_pk_copy_from_psa() on a key whose policy specifies PSS as the single allowed algorithm, then calling mbedtls_pk_sign(), results in a PKCS#1v1.5 signature. Call mbedtls_pk_sign_ext() or mbedtls_pk_verify_ext() if you want to specify the signature algorithm explicitly.
Removal of transparent PK contexts
It is no longer possible to directly inspect a PK context to act on its underlying RSA or ECC context. The representation of a key in PK is now always an implementation detail.
As a consequence, the functions mbedtls_pk_setup(), mbedtls_pk_rsa() and mbedtls_pk_ec() have been removed.
Changes to opaque PK contexts
The library no longer supports an alternative representation of RSA keys in PK (MBEDTLS_PK_RSA_ALT_SUPPORT compilation option, PK context type MBEDTLS_PK_RSA_ALT). See “RSA-ALT interface” in the PSA transition guide.
A PK object can still wrap around an PSA key, which was formerly known as “opaque” PK objects of type MBEDTLS_PK_OPAQUE. The function mbedtls_pk_setup_opaque() has been renamed to mbedtls_pk_wrap_psa(), to reflect the fact that the PSA key is not necessarily “opaque” in PSA terminology. The PK module now hides the distinction between “wrapping” and “non-wrapping” PK contexts as much as possible, and in particular there is no simple metadata query to distinguish “wrapping” keys like the former mbedtls_pk_get_type().
Fewer operations in PK
The functions mbedtls_pk_encrypt() and mbedtls_pk_decrypt() have been removed. Use psa_asymmetric_encrypt() and psa_asymmetric_decrypt() instead. See “Asymmetric encryption and decryption” in the PSA transition guide for more information.
If you have a key as a PK context and you wish to use it with PSA operation functions, use the functions mbedtls_pk_get_psa_attributes() and mbedtls_pk_import_into_psa() to obtain a PSA key identifier. See the documentation of these functions or “Creating a PSA key via PK” in the PSA transition guide for more information.
Miscellaneous changes to PK signature and verification
The type argument to mbedtls_pk_sign_ext() and mbedtls_pk_verify_ext() now has the type mbedtls_pk_sigalg_t. See “Changes to PK metadata”.
The function mbedtls_pk_verify_ext() no longer supports a custom salt length for RSA-PSS. It always allows signatures with any salt length. The PSA API offers psa_verify_hash() with PSA_ALG_RSA_PSS to enforce the most commonly used salt length.
MBEDTLS_ERR_PK_SIG_LEN_MISMATCH is no longer a distinct error code. A valid signature with trailing garbage is now reported as an invalid signature with all algorithms.
The PK module continues to favor deterministic ECDSA over randomized ECDSA when both are possible. This may change in the future. The new macro MBEDTLS_PK_ALG_ECDSA(hash_alg) indicates which variant PK favors. It is equivalent to either PSA_ALG_DETERMINISTIC_ECDSA(hash_alg) or PSA_ALG_ECDSA(hash_alg).
Changes in resources consumed by PK objects
The implementation of the type mbedtls_pk_context has changed in ways that do not directly affect functionality, but affect resource consumption and memory partitioning.
Historically, at least in the default configuration, a PK context stored all the key material in a heap-allocated object. In TF-PSA-Crypto 1.0, a PK context now contains:
- the public key, in a fixed-size buffer that is directly in the
mbedtls_pk_contextstructure; - the private key (if available), in the PSA key store.
This may change in future minor versions of TF-PSA-Crypto.
Other miscellaneous changes in PK
Since PSA has a built-in random generator, all (f_rng, p_rng) arguments to PK functions have been removed.
mbedtls_pk_debug() and the associated types have been removed. This was intended solely for internal consumption by the debug module, and tied to internal details of the legacy representation of keys. If you need equivalent functionality in TF-PSA-Crypto, export the key.
The auxiliary functions mbedtls_pk_parse_subpubkey() and mbedtls_pk_write_pubkey() are no longer exposed. Use mbedtls_pk_parse_public_key() and mbedtls_pk_write_pubkey_der() instead.
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 keys and signatures.
TF-PSA-Crypto does not have interfaces to look up values by OID or OID by enum values.
Functions to convert between binary and dotted string OID representations (mbedtls_oid_get_numeric_string() and mbedtls_oid_from_numeric_string()) are still available, but they are now in the X.509 library in Mbed TLS. The header file <mbedtls/oid.h> is now in Mbed TLS, not in TF-PSA-Crypto.
TF-PSA-Crypto does not expose OID values through macros, the way Mbed TLS 3.x and earlier did.
Changes to the PAKE interface
The PAKE interface in TF-PSA-Crypto 1.0 has been updated to match PSA Crypto API 1.2 Final PAKE extension, which is the same version that has been integrated into the main specification of PSA Crypto version 1.3.
In Mbed TLS 3.6, the PAKE interface implemented version 1.1 Beta of the PAKE extension. There has been a number of changes between the beta and the final version of the API. The changes that require applications to update their code are detailed in the following subsections.
Note that TF-PSA-Crypto 1.0 still only implements PSA_ALG_JPAKE (and only on elliptic curves, specifically only on secp256r1). Support for SPAKE2+ is likely to be added in a future version but is not there yet.
Combine psa_pake_set_password_key() with psa_pake_setup()
The function psa_pake_set_password_key() has been removed. Its key argument is now passed to psa_pake_setup() which has gained a new key parameter.
Before:
status = psa_pake_setup(&operation, &cipher_suite);
if (status != PSA_SUCCESS) // error handling omitted for brevity
status = psa_pake_set_password_key(&operation, key);
if (status != PSA_SUCCESS) // error handling omitted for brevity
Now:
status = psa_pake_setup(&operation, key, &cipher_suite);
if (status != PSA_SUCCESS) // error handling omitted for brevity
Move the hash algorithm parameter into the algorithm identifier
The function psa_pake_cs_set_hash() has been removed. Its hash argument is now passed to PSA_ALG_JPAKE() which is now a function-like macro with one parameter.
Before:
psa_pake_cs_set_algorithm(&cipher_suite, PSA_ALG_JPAKE);
psa_pake_cs_set_hash(&cipher_suite, PSA_ALG_SHA_256);
Now:
psa_pake_cs_set_algorithm(&cipher_suite, PSA_ALG_JPAKE(PSA_ALG_SHA_256));
To check if a given algorithm is J-PAKE, the new PSA_ALG_IS_JPAKE() macro has been added.
Before: if (alg == PSA_ALG_JPAKE)
Now: if (PSA_ALG_IS_JPAKE(alg))
The function psa_pake_cs_get_hash() has also been removed.
Replace psa_pake_get_implicit_key() with psa_pake_get_shared_key()
The function psa_pake_get_implicit_key(), which injects the shared secret into a key derivation operation, has been removed. Its replacement is psa_pake_get_shared_key() which stores the shared secret in a new key. That new key can then be used as part of a key derivation operation.
Before:
// omitted: set up pake_op and do the PAKE key exchange
psa_algorithm_t alg = PSA_ALG_TLS12_ECJPAKE_TO_PMS; // for example
psa_key_derivation_operation_t derivation = PSA_KEY_DERIVATION_OPERATION_INIT;
status = psa_key_derivation_setup(&derivation, alg);
if (status != PSA_SUCCESS) // error handling omitted for brevity
status = psa_pake_get_implicit_key(&pake_op, &derivation);
if (status != PSA_SUCCESS) // error handling omitted for brevity
// omitted: finish key derivation (output/verify, then abort)
Now:
// omitted: set up pake_op and do the PAKE key exchange
psa_algorithm_t alg = PSA_ALG_TLS12_ECJPAKE_TO_PMS; // for example
psa_key_derivation_operation_t derivation = PSA_KEY_DERIVATION_OPERATION_INIT;
status = psa_key_derivation_setup(&derivation, alg);
if (status != PSA_SUCCESS) // error handling omitted for brevity
psa_key_id_t shared_key_id = (psa_key_id_t) 0;
psa_key_attributes_t shared_key_attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_usage_flags(&shared_key_attributes, PSA_KEY_USAGE_DERIVE);
psa_set_key_algorithm(&shared_key_attributes, alg); // same as derivation
psa_set_key_type(&shared_key_attributes, PSA_KEY_TYPE_DERIVE);
status = psa_pake_get_shared_key(&pake_op,
&shared_key_attributes,
&shared_key_id);
if (status != PSA_SUCCESS) // error handling omitted for brevity
psa_reset_key_attributes(&shared_key_attributes);
status = psa_key_derivation_input_key(&derivation_op,
PSA_KEY_DERIVATION_INPUT_SECRET,
shared_key_id);
if (status != PSA_SUCCESS) // error handling omitted for brevity
// omitted: finish key derivation (output/verify, then abort)
psa_destroy_key(shared_key_id); // after key derivation is complete
Note that the new function is more flexible: instead of using the shared secret only for key derivation, you can also directly use it as an HMAC key by setting the appropriate key type and policy, for example:
psa_key_id_t shared_key_id = (psa_key_id_t) 0;
psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256); // or other hash
psa_key_attributes_t shared_key_attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_usage_flags(&shared_key_attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
// or VERIFY_MESSAGE
psa_set_key_algorithm(&shared_key_attributes, alg);
psa_set_key_type(&shared_key_attributes, PSA_KEY_TYPE_HMAC);
status = psa_pake_get_shared_key(&pake_op,
&shared_key_attributes,
&shared_key_id);
if (status != PSA_SUCCESS) // error handling omitted for brevity
See the specification for details. Note that the J-PAKE shared secret is not uniformly pseudorandom, so it can only be used for key derivation and HMAC.
Persistent keys with a PAKE policy
TF-PSA-Crypto can read persistent keys created with an algorithm policy that specifies the Mbed TLS 3.x encoding of PSA_ALG_JPAKE. Such a policy now allows cipher suites with PSA_ALG_JPAKE(hash_alg) for any hash algorithm. It appears as PSA_ALG_JPAKE_BETA when querying the policy with psa_get_key_algorithm().
Remaining limitations to JPAKE in TF-PSA-Crypto 1.0.0
The following limitations apply to both Mbed TLS 3.x and TF-PSA-Crypto 1.0.0:
- The only supported primitive is ECC on the curve secp256r1, i.e.
PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256). - The only supported hash algorithm is SHA-256, i.e.
PSA_ALG_SHA_256. - When using the built-in implementation, the user ID and the peer ID must be
"client"(6-byte string) or"server"(6-byte string). Third-party drivers may or may not have this limitation.