Mistake on this page?
Report an issue in GitHub or email us

Using PSA-enabled Mbed TLS

Building PSA-enabled Mbed TLS from Git

The version of Mbed TLS shipped in Mbed OS builds with PSA enabled by default. However, you can build a PSA-enabled version of Mbed TLS from our Git repository:

  1. Clone the repository and switch to the master branch.
  2. Enable the MBEDTLS_USE_PSA_CRYPTO build-time configuration option in include/mbedtls/config.h, either by editing the file manually, or using the config script: scripts/config.py set MBEDTLS_USE_PSA_CRYPTO.
  3. Build normally, for example (with GNU Make) make lib or (with CMake) mkdir build && cd build && cmake .. && make lib.

Using PSA-enabled Mbed TLS

You can use PSA and non-PSA Mbed TLS interchangeably, but you must recompile your application every time you change. This is because PSA-enabled and non-PSA-enabled Mbed TLS are fully API compatible, but are not ABI compatible.

Please note that this is likely to change at a later date though, as existing interfaces are likely to be deprecated in favor of the new, PSA-based APIs - if, when and how it happens is outside the scope of this document.

PSA-based APIs in Mbed TLS

As mentioned in the previous section, you can use PSA-neabled Mbed TLS to build applications that are not PSA enabled. Doing so is enough to benefit from PSA in some areas (for example, some PSA-based hardware acceleration, depending on platform support), but in other areas, changes in the application source code are necessary. This mainly means replacing calls to pre-PSA APIs with calls to their PSA-based versions.

The new APIs allow using PSA-managed keys for a few purposes, such as TLS client authentication, CSR generation and TLS PSK connections. Letting the key be managed by PSA is good for security because PSA can isolate the keys from the rest of the applications (referred to below as "opaque keys"). To use such PSA-managed keys, you need to modify your code to use the new APIs as described below.

Using opaque ECDSA keys for TLS client authentication

This mainly involves using the new API function mbedtls_pk_setup_opaque() to wrap a PSA-managed key into a PK context, then using that context with the usual TLS APIs.

Application flow without PSA

  1. At application startup, make sure mbedtls_platform_setup() is called if relevant.
  2. Declare (and allocate) an object of type mbedtls_pk_context.
  3. Load a key into that PK context, presumably using mbedtls_pk_parse_key() (or mbedtls_pk_parse_keyfile()).
  4. Configure the key for use in client authentication with a matching certificate by calling mbedtls_ssl_conf_own_cert() on the PK context.
  5. Use the resulting SSL configuration for TLS connections as usual.
  6. When you're done using TLS connections based on that configuration, and no longer want to use that key for anything else, free the PK context using mbedtls_pk_free().

Application flow with PSA

  1. At application startup, make sure mbedtls_platform_setup() is called if relevant, and make sure psa_crypto_init() is called, too.
  2. Declare (and allocate) an object of type mbedtls_pk_context and an object of type psa_key_handle_t.
  3. Allocate and load the key you want to use through the handle object. (For information on how to do this, please refer to the PSA Crypto documentation.)
  4. Set up the PK context to wrap that handle by calling mbedtls_pk_setup_opaque().
  5. Configure the key for use in client authentication with a matching certificate by calling mbedtls_ssl_conf_own_cert() on the PK context.
  6. Use the resulting SSL configuration for TLS connections as usual.
  7. When you're done using TLS connections based on that configuration, free the PK context using mbedtls_pk_free(). This only frees the PK context itself and leaves the key handle untouched. You can either keep using the key handle or call psa_destroy_key() on it depending on your application flow.

Using opaque ECDSA keys to generate certificate signing requests (CSRs)

This mainly involves using the API function mbedtls_pk_setup_opaque() to wrap a PSA-managed key into a PK context, then using that context with the usual TLS APIs.

Application flow without PSA

  1. At application startup, make sure mbedtls_platform_setup() is called if relevant.
  2. Declare (and allocate) an object of type mbedtls_pk_context
  3. Load a key into that PK context, presumably using mbedtls_pk_parse_key(), or by generating a fresh key.
  4. Configure the pending CSR object to use that key by calling mbedtls_x509write_csr_set_key() on that PK context.
  5. Call any other function you need to configure and generate the CSR.
  6. When you're done generating the CSR, and no longer want to use that key for anything else, free the PK context using mbedtls_pk_free().

Application flow with PSA

  1. At application startup, make sure mbedtls_platform_setup() is called if relevant, and make sure psa_crypto_init() is called, too.
  2. Declare (and allocate) an object of type mbedtls_pk_context and an object of type psa_key_handle_t.
  3. Allocate and load the key you want to use through the handle object. (For information about how to do this, please refer to the PSA Crypto documentation.)
  4. Set up the PK context to wrap that handle by calling mbedtls_pk_setup_opaque().
  5. Configure the pending CSR object to use that key by calling mbedtls_x509write_csr_set_key() on that PK context.
  6. Call any other function that you need to configure and generate the CSR.
  7. When you're done generating the CSR, free the PK context using mbedtls_pk_free(). This only frees the PK context itself and leaves the key handle untouched. You can either keep using the key handle or call psa_destroy_key() on it, depending on your application flow.

Using opaque pre-shared keys with TLS PSK ciphersuites

This mainly involves using the API function mbedtls_ssl_conf_psk_opaque() in place of mbedtls_ssl_conf_psk() client-side or, server-side using mbedtls_ssl_set_hs_psk_opaque() instead of mbedtls_ssl_set_hs_psk() in the PSK callback.

Application flow without PSA

  1. At application startup, make sure mbedtls_platform_setup() is called if relevant.
  2. Set up an unsigned char * to point to a memory area holding your pre-shared key.
  3. Call mbedtls_ssl_conf_psk() on the SSL configuration object.
  4. Use that configuration object in TLS connections.

Application flow with PSA

  1. At application startup, make sure mbedtls_platform_setup() is called if relevant, and make sure psa_crypto_init() is called, too.
  2. Set up a psa_key_handle_t to point to a configured slot holding your pre-shared key.
  3. Call mbedtls_ssl_conf_psk_opaque() on the SSL configuration object.
  4. Use that configuration object in TLS connections.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.