PSA Cryptograpy API implementation and PSA driver interface

Introduction

The PSA Cryptography API specification defines an interface to cryptographic operations for which the Mbed TLS library provides a reference implementation. The PSA Cryptography API specification is complemented by the PSA driver interface specification which defines an interface for cryptoprocessor drivers.

This document describes the high level organization of the Mbed TLS PSA Cryptography API implementation which is tightly related to the PSA driver interface.

High level organization of the Mbed TLS PSA Cryptography API implementation

In one sentence, the Mbed TLS PSA Cryptography API implementation is made of a core and PSA drivers as defined in the PSA driver interface. The key point is that software cryptographic operations are organized as PSA drivers: they interact with the core through the PSA driver interface.

Rationale

  • Addressing software and hardware cryptographic implementations through the same C interface reduces the core code size and its call graph complexity. The core and its dispatching to software and hardware implementations are consequently easier to test and validate.
  • The organization of the software cryptographic implementations in drivers promotes modularization of those implementations.
  • As hardware capabilities, software cryptographic functionalities can be described by a JSON driver description file as defined in the PSA driver interface.
  • Along with JSON driver description files, the PSA driver specification defines the deliverables for a driver to be included into the Mbed TLS PSA Cryptography implementation. This provides a natural framework to integrate third party or alternative software implementations of cryptographic operations.

The Mbed TLS PSA Cryptography API implementation core

The core implements all the APIs as defined in the PSA Cryptography API specification but does not perform on its own any cryptographic operation. The core relies on PSA drivers to actually perform the cryptographic operations. The core is responsible for:

  • the key store.
  • checking PSA API arguments and translating them into valid arguments for the necessary calls to the PSA driver interface.
  • dispatching the cryptographic operations to the appropriate PSA drivers.

The sketch of an Mbed TLS PSA cryptographic API implementation is thus:

psa_status_t psa_api( ... )
{
    psa_status_t status;

    /* Pre driver interface call processing: validation of arguments, building
     * of arguments for the call to the driver interface, ... */

    ...

    /* Call to the driver interface */
    status = psa_driver_wrapper_<entry_point>( ... );
    if( status != PSA_SUCCESS )
        return( status );

    /* Post driver interface call processing: validation of the values returned
     * by the driver, finalization of the values to return to the caller,
     * clean-up in case of error ... */
}

The code of most PSA APIs is expected to match precisely the above layout. However, it is likely that the code structure of some APIs will be more complicated with several calls to the driver interface, mainly to encompass a larger variety of hardware designs. For example, to encompass hardware accelerators that are capable of verifying a MAC and those that are only capable of computing a MAC, the psa_mac_verify() API could call first psa_driver_wrapper_mac_verify() and then fallback to psa_driver_wrapper_mac_compute().

The implementations of psa_driver_wrapper_<entry_point> functions are generated by the build system based on the JSON driver description files of the various PSA drivers making up the Mbed TLS PSA Cryptography API implementation. The implementations are generated in a psa_crypto_driver_wrappers.c C file and the function prototypes declared in a psa_crypto_driver_wrappers.h header file.

The psa_driver_wrapper_<entry_point>() functions dispatch cryptographic operations to accelerator drivers, secure element drivers as well as to the software implementations of cryptographic operations.

Note that the implementation allows to build the library with only a C compiler by shipping a generated file corresponding to a pure software implementation. The driver entry points and their code in this generated file are guarded by pre-processor directives based on PSA_WANT_xyz macros (see Conditional inclusion of cryptographic mechanism through the PSA API in Mbed TLS. That way, it is possible to compile and include in the library only the desired cryptographic operations.

Key creation

Key creation implementation in Mbed TLS PSA core is articulated around three internal functions: psa_start_key_creation(), psa_finish_key_creation() and psa_fail_key_creation(). Implementations of key creation PSA APIs, namely psa_import_key(), psa_generate_key(), psa_key_derivation_output_key() and psa_copy_key() go by the following sequence: 1. Check the input parameters. 2. Call psa_start_key_creation() that allocates a key slot, prepares it with the specified key attributes, and in case of a volatile key assign it a volatile key identifier. 3. Generate or copy the key material into the key slot. This entails the allocation of the buffer to store the key material. 4. Call psa_finish_key_creation() that mostly saves persistent keys into persistent storage.

In case of any error occuring at step 3 or 4, psa_fail_key_creation() is called. It wipes and cleans the slot especially the key material: reset to zero of the RAM memory that contained the key material, free the allocated buffer.

Mbed TLS PSA Cryptography API implementation drivers

A driver of the Mbed TLS PSA Cryptography API implementation (Mbed TLS PSA driver in the following) is a driver in the sense that it is compliant with the PSA driver interface specification. But it is not an actual driver that drives some hardware. It implements cryptographic operations purely in software.

An Mbed TLS PSA driver C file is named psa_crypto_<driver_name>.c and its associated header file psa_crypto_<driver_name>.h. The functions implementing a driver entry point as defined in the PSA driver interface specification are named as mbedtls_psa__(). As an example, the psa_crypto_rsa.c and psa_crypto_rsa.h are the files containing the Mbed TLS PSA driver implementing RSA cryptographic operations. This RSA driver implements among other entry points the “import_key” entry point. The function implementing this entry point is named mbedtls_psa_rsa_import_key().