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:
- Clone the repository and switch to the
master
branch. - Enable the
MBEDTLS_USE_PSA_CRYPTO
build-time configuration option ininclude/mbedtls/config.h
, either by editing the file manually, or using the config script:scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
. - 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
- At application startup, make sure
mbedtls_platform_setup()
is called if relevant. - Declare (and allocate) an object of type
mbedtls_pk_context
. - Load a key into that PK context, presumably using
mbedtls_pk_parse_key()
(ormbedtls_pk_parse_keyfile()
). - Configure the key for use in client authentication with a matching certificate by calling
mbedtls_ssl_conf_own_cert()
on the PK context. - Use the resulting SSL configuration for TLS connections as usual.
- 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
- At application startup, make sure
mbedtls_platform_setup()
is called if relevant, and make surepsa_crypto_init()
is called, too. - Declare (and allocate) an object of type
mbedtls_pk_context
and an object of typepsa_key_handle_t
. - 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.)
- Set up the PK context to wrap that handle by calling
mbedtls_pk_setup_opaque()
. - Configure the key for use in client authentication with a matching certificate by calling
mbedtls_ssl_conf_own_cert()
on the PK context. - Use the resulting SSL configuration for TLS connections as usual.
- 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 callpsa_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
- At application startup, make sure
mbedtls_platform_setup()
is called if relevant. - Declare (and allocate) an object of type
mbedtls_pk_context
- Load a key into that PK context, presumably using
mbedtls_pk_parse_key()
, or by generating a fresh key. - Configure the pending CSR object to use that key by calling
mbedtls_x509write_csr_set_key()
on that PK context. - Call any other function you need to configure and generate the CSR.
- 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
- At application startup, make sure
mbedtls_platform_setup()
is called if relevant, and make surepsa_crypto_init()
is called, too. - Declare (and allocate) an object of type
mbedtls_pk_context
and an object of typepsa_key_handle_t
. - 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.)
- Set up the PK context to wrap that handle by calling
mbedtls_pk_setup_opaque()
. - Configure the pending CSR object to use that key by calling
mbedtls_x509write_csr_set_key()
on that PK context. - Call any other function that you need to configure and generate the CSR.
- 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 callpsa_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
- At application startup, make sure
mbedtls_platform_setup()
is called if relevant. - Set up an
unsigned char *
to point to a memory area holding your pre-shared key. - Call
mbedtls_ssl_conf_psk()
on the SSL configuration object. - Use that configuration object in TLS connections.
Application flow with PSA
- At application startup, make sure
mbedtls_platform_setup()
is called if relevant, and make surepsa_crypto_init()
is called, too. - Set up a
psa_key_handle_t
to point to a configured slot holding your pre-shared key. - Call
mbedtls_ssl_conf_psk_opaque()
on the SSL configuration object. - Use that configuration object in TLS connections.