# 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](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, 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/`<br>`drivers/builtin/src/`                        | Contains cryptographic, cryptographic-adjacent (e.g., ASN.1, Base64), and platform C modules and headers. |
| `include/mbedtls/*`                     | `include/mbedtls/`<br>`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/everest`<br>`3rdparty/p256-m` | `drivers/everest`<br>`drivers/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](#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](psa-transition.md#compile-time-configuration).
- See also the following sections:
  - [PSA as the only cryptography API](#psa-as-the-only-cryptography-api) and its sub-section [Impact on the library Configuration](#impact-on-the-library-configuration)
  - [Random number generation configuration](#random-number-generation-configuration)

### 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](#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_package`
- `programs/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](#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](#impact-on-some-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](#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 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](#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](#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](psa-transition.md). 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](#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](#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](psa-transition.md).

See also the section [“Random number generation configuration”](#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`](#reduced-mdh)” and “[PK module](#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`](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 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 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](#removal-of-alternative-cryptographic-module-implementations).

### 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, use `psa_generate_key_custom()`, introduced in Mbed TLS 3.6.1.
* `psa_generate_key_ext()`, `psa_key_derivation_output_key_ext` and related types and macros. Use `psa_generate_key_custom()` or `psa_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`:

```c
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

```c
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`:

```c
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

```c
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`:

```c
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

```c
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:

```c
// 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:

```c
// 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 type `mbedtls_threading_mutex_t` which 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_ERROR` to report a runtime failure (renamed from `MBEDTLS_ERR_THREADING_MUTEX_ERROR`, which is now an alias provided only for backward compatibility).
* `PSA_ERROR_BAD_STATE` only to report a library state error. If an error is detected in the state of a synchronization object, please return `MBEDTLS_ERR_THREADING_USAGE_ERROR` instead.
* `PSA_ERROR_INSUFFICIENT_MEMORY` to 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_RNG` is 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”](#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_ENTROPY` to disable the default entropy collector for Unix-like and Windows platforms no longer exists. It has been replaced by the positive option `MBEDTLS_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 to `MBEDTLS_PSA_DRIVER_GET_ENTROPY`. This replaces `MBEDTLS_ENTROPY_HARDWARE_ALT`. The callback has a different name and prototype as described in “[Custom hardware collector](#custom-entropy-collector)”.
* The option `MBEDTLS_ENTROPY_NV_SEED` to enable a non-volatile seed is unchanged. However, if this is your only entropy source, you must now enable the new option `MBEDTLS_ENTROPY_NO_SOURCES_OK`.

The following table describes common configurations.

<table>
  <tr valign="top">
    <th align="left">Configuration</th>
    <th align="left">Mbed TLS 3.6</th>
    <th align="left">TF-PSA-Crypto 1.0</th>
  </tr>

  <tr valign="top">
    <td><strong>Unix, Linux, Windows</strong></td>
    <td>(default)</td>
    <td>(default)</td>
  </tr>

  <tr valign="top">
    <td><strong>Embedded platform</strong></td>
    <td>
      <pre>
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_HARDWARE_ALT
      </pre>
    </td>
    <td>
      <pre>
#undef MBEDTLS_PSA_BUILTIN_GET_ENTROPY
#define MBEDTLS_PSA_DRIVER_GET_ENTROPY
      </pre>
    </td>
  </tr>

  <tr valign="top">
    <td><strong>Fast external crypto RNG</strong></td>
    <td>
      <pre>
#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
#undef MBEDTLS_ENTROPY_C
#undef MBEDTLS_CTR_DRBG_C
      </pre>
    </td>
    <td>
      <pre>
#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
#undef MBEDTLS_ENTROPY_C
#undef MBEDTLS_CTR_DRBG_C
      </pre>
    </td>
  </tr>

  <tr valign="top">
    <td><strong>NV seed only</strong></td>
    <td>
      <pre>
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_NV_SEED
      </pre>
    </td>
    <td>
      <pre>
#undef MBEDTLS_PSA_BUILTIN_GET_ENTROPY
#define MBEDTLS_ENTROPY_NV_SEED
#define MBEDTLS_ENTROPY_NO_SOURCES_OK
      </pre>
    </td>
  </tr>

  <tr valign="top">
    <td><strong>No entropy at all</strong></td>
    <td>
      <pre>
#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
      </pre>
    </td>
    <td>
      <em>not supported</em>
    </td>
  </tr>
</table>

#### 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:
```c
// 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:
```c
// 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 both `MBEDTLS_PSA_HMAC_DRBG_MD_TYPE` and `MBEDTLS_ENTROPY_FORCE_SHA256`.
* `MBEDTLS_PSA_RNG_RESEED_INTERVAL`: Sets the reseed interval for both CTR_DRBG and HMAC_DRBG. It replaces `MBEDTLS_CTR_DRBG_RESEED_INTERVAL` and `MBEDTLS_HMAC_DRBG_RESEED_INTERVAL`.
* `MBEDTLS_PSA_CRYPTO_RNG_STRENGTH`: Specifies the security strength in bits. The default is 256 bits. If you previously enabled `MBEDTLS_CTR_DRBG_USE_128_BIT_KEY` in Mbed TLS 3.6, you should now set `MBEDTLS_PSA_CRYPTO_RNG_STRENGTH` to 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](psa-transition.md#hashes-and-mac) 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 the `hmac` parameter 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()` and `mbedtls_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 call `mbedtls_md_update()` or `psa_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_t` name | New `mbedtls_pk_sigalg_t` name |
    | ---------------------------- | ------------------------------ |
    | `MBEDTLS_PK_NONE` | `MBEDTLS_PK_SIGALG_NONE` |
    | `MBEDTLS_PK_RSA` | `MBEDTLS_PK_SIGALG_RSA_PKCS1V15` |
    | `MBEDTLS_PK_RSASSA_PSS` | `MBEDTLS_PK_SIGALG_RSA_PSS` |
    | `MBEDTLS_PK_ECDSA` or `MBEDTLS_PK_ECKEY` | `MBEDTLS_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.
  <!-- Untested, see https://github.com/Mbed-TLS/TF-PSA-Crypto/issues/206 -->

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](psa-transition.md#rsa-alt-interface).

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](psa-transition.md#rsa-alt-interface) 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](psa-transition.md#creating-a-psa-key-via-pk) 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”](#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_context` structure;
* 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](https://arm-software.github.io/psa-api/crypto/1.2/ext-pake/) PAKE extension, which is the same version that has been integrated into the main specification of PSA Crypto [version 1.3](https://arm-software.github.io/psa-api/crypto/1.3/).

In Mbed TLS 3.6, the PAKE interface implemented version [1.1 Beta](https://arm-software.github.io/psa-api/crypto/1.1/ext-pake/) of the PAKE extension. There has been a number of [changes between the beta and the final version](https://arm-software.github.io/psa-api/crypto/1.2/ext-pake/appendix/history.html#changes-between-beta-1-and-final) 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](https://arm-software.github.io/psa-api/crypto/1.3/api/ops/pake.html#c.psa_pake_get_shared_key) 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](https://github.com/Mbed-TLS/TF-PSA-Crypto/issues/503) 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](https://github.com/Mbed-TLS/TF-PSA-Crypto/issues/504) is SHA-256, i.e. `PSA_ALG_SHA_256`.
- When using the built-in implementation, [the user ID and the peer ID](https://github.com/Mbed-TLS/TF-PSA-Crypto/issues/502) must be `"client"` (6-byte string) or `"server"` (6-byte string).
  Third-party drivers may or may not have this limitation.
