TF-M Crypto Service design

Author:

Antonio de Angelis

Organization:

Arm Limited

Contact:

Antonio de Angelis <antonio.deangelis@arm.com>

Abstract

This document describes the design of the TF-M Cryptographic Secure Service (in short, TF-M Crypto service).

Introduction

The TF-M Crypto service provides an implementation of the PSA Certified Crypto APIs in a PSA RoT secure partition in TF-M. It is based on the Mbed TLS project, which provides a reference implementation of the PSA Crypto APIs as a C software library. For more details on the PSA Crypto APIs refer to [1], while for the Mbed TLS reference software refer to [2] and [3]

The service can be requested by other services running in the SPE, or by applications running in the NSPE, and its aim is to provide cryptographic primitives in a secure and efficient way, either via software or by routing the calls to any underlying crypto hardware accelerator or secure element that the platform might provide.

Components

The TF-M Crypto service is implemented by a number of different firmware components residing in the Crypto partition, which are listed below:

Table 44 Components table

Component name

Description

Location

Client API interface

This module exports the PSA Crypto API to be callable from the users, which are called also clients. They could be either other secure partitions or Non Secure world based callers.

interface/src/tfm_crypto_api.c

Mbed TLS libmbedcrypto.a

The Mbed TLS libmbedcrypto.a library is used in the service as a cryptographic backend library which provides the APIs to implement a PSA Crypto core, SW based crypto primitives and wrappers for HW crypto accelerators and Secure Elements. It exposes those through the PSA Crypto APIs

Needed as dependency specified by the MBEDCRYPTO_PATH CMake configuration option

Init module

This module handles the initialisation of the service objects during TF-M boot and provides the infrastructure to service requests when TF-M is built for IPC or SFN model. The dispatching mechanism of IPC requests is based on a look up table of function pointers. This design allows for better scalability and support of a higher number of Secure functions with minimal overhead and duplication of code. This module is in charge of providing an ID of the caller of each API in the backend, allowing to enforce key ownership policies.

secure_fw/partitions/crypto/crypto_init.c

Alloc module

This module handles the allocation of contexts for multipart operations in the Secure world. This is required because the caller view of contexts, i.e. clients, does not contain any sensible information but just a number handle which is then used by the service itself to match the context to the actual context information which will be stored securely in the TF-M crypto partition private memory. This is enabled by setting MBEDTLS_PSA_CRYPTO_CLIENT option on the caller side. Note that setting this option on the client side is a hard requirement in order for the clients to work correctly

secure_fw/partitions/crypto/crypto_alloc.c

Service modules

These modules (AEAD, Asymmetric, Cipher, Hash, Key Derivation, Key Management, MAC, Random Number Generation) represent a thin layer which is in charge of servicing the calls from the clients. They provide parameter sanitization and context retrieval for multipart operations, and dispatching to the corresponding backend library function exposed by the underlying library.

secure_fw/partitions/crypto/crypto_aead.c secure_fw/partitions/crypto/crypto_asymmetric.c secure_fw/partitions/crypto/crypto_cipher.c secure_fw/partitions/crypto/crypto_hash.c secure_fw/partitions/crypto/crypto_key_derivation.c secure_fw/partitions/crypto/crypto_key_management.c secure_fw/partitions/crypto/crypto_mac.c secure_fw/partitions/crypto/crypto_rng.c

Backend library abstraction

This module contains several APIs to abstract the interface towards the backend library, which must provide the PSA Crypto core layer, key management, SW based crypto and possibly interfaces for HW crypto accelerators and Secure Elements

secure_fw/partitions/crypto/crypto_library.*

Manifest

The manifest file is a description of the service components.

secure_fw/partitions/crypto/tfm_crypto.yaml

CMake, Kconfig and headers

The CMake files are used by the TF-M CMake build system to build the service as part of the Secure FW build. The service is built as a static library (libtfm_psa_rot_partition_crypto.a). The service itself depends on the build of the underlying backend library, by default the libmbedcrypto.a target, a static library built by the Mbed TLS build system. The tfm_crypto_api.h header contains public service APIs, which expose each module’s interface. The header available in the interface, tfm_crypto_defs.h, contains types and definitions to build the client interface of the service, i.e. towards other services or NS world. Finally, the crypto_spe.h header is used during the build of the Mbed TLS library, when the configuration option MBEDTLS_PSA_CRYPTO_SPM is defined, to add a custom prefix to the PSA API symbols so that duplication of symbol names is avoided. The prefix used for the symbols of the library is chosen to be mbedcrypto__.

secure_fw/partitions/crypto/CMakeLists.txt secure_fw/partitions/crypto/Kconfig secure_fw/partitions/crypto/Kconfig.comp secure_fw/partitions/crypto/config_crypto_check.h secure_fw/partitions/crypto/config_engine_buf.h secure_fw/partitions/crypto/tfm_crypto_api.h secure_fw/partitions/crypto/crypto_spe.h interface/include/tfm_crypto_defs.h

TF-M Crypto key abstraction

The TF-M Crypto service has its own type definition to be able to identify a key ID with its own owner. The definition of an owner is provided by the TF-M Firmware Framework and is out of the scope of the service itself and the PSA Crypto APIs spec. The underlying library in practice must provide the same functionality, i.e handle key IDs with associated owner info. For Mbed TLS, this is accomplished by the type mbedtls_svc_key_id_t when the config option of Mbed TLS MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER is defined. Note that setting this option in Mbed TLS is a hard requirement for when the library is built on the service side, while it shall never be set when the headers are included for client side components (i.e. other partitions or NS interface).

secure_fw/partitions/crypto/tfm_crypto_key.h

Documentation

The integration guide contains the description of the TF-M Crypto service modules and interfaces.

docs/integration_guide/services/tfm_crypto_integration_guide.rst

The interaction between the different components is described by the block diagram in Fig. 12

../../_images/psa_rot_crypto_service_architecture.png

Fig. 12 Block diagram of the firmware architecture of the TF-M Crypto service. Dotted lines between services represent isolation boundaries once runtime firmware is initialized, i.e. TF-M init phase has completed. The diagram is simplified and shows only the major functional blocks, for a more detailed libmbedcrypto.a architecture please refer to [3].

Relationship between Mbed TLS and the TF-M Crypto service

TF-M Crypto as a particular configuration of Mbed TLS

Up until TF-Mv2.0, the TF-M Crypto service used to provide its own separate implementation of the PSA Certified Crypto APIs, i.e. it provided its own version of the implementation defined aspects of the specifications. Starting from TF-Mv2.1, the TF-M Crypto service fully aligns to the implementation defined by the Mbed TLS project, i.e. its implementation defined aspects are the same as the ones defined by Mbed TLS.

As a consequence, starting from TF-Mv2.1 the PSA Crypto headers available in TF-M are a copy of those distributed by the Mbed TLS project. TF-M just uses them and won’t accept any contribution to them, as those need to be discussed in the scope of the Mbed TLS project.

TF-M then represents just a configuration of the Mbed TLS reference implementation where the TF-M Crypto APIs are provided as a remote call across a transport channel, which might be represented by a TrustZone boundary (in Armv8.x-M systems), by a mailbox channel in heterogeneous systems, e.g. Cortex-A + Cortex-M systems, by an SPM mediated interface, e.g. partition to partition calls or, in general, through a mechanism which provides process separation between the client and the service sides of the API. In this context, the client must always define the Mbed TLS config option MBEDTLS_PSA_CRYPTO_CLIENT, while the service must always have MBEDTLS_PSA_CRYPTO_SPM, mainly to avoid symbol clashing at link time between the library interface and the tfm_crypto_api.c interface. When there is a component on the service side which is able to identify the client through an ID, it is recommended to also define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER option in order to provide separation in the key space.

Usage of Mbed TLS configuration headers

Mbed TLS uses two different configuration headers, specified through the setting of the MBEDTLS_CONFIG_FILE, i.e. Mbed TLS config, and the setting of MBEDTLS_PSA_CRYPTO_CONFIG_FILE, i.e. the PSA configuration. In order to be able to perform header inclusion for psa/crypto.h, the configuration files must be visible to the compilation unit through the include hierarchy. If none of the macros are defined, the fall back strategy is to include the default config files available in the Mbed TLS repo, i.e. include/mbedtls/mbedtls_config.h and include/psa/crypto_config.h, which contain a set of default values for the macros.

Usage of the default header config when using the TF-M Crypto service is highly discouraged, mainly because both on the client side and on the service side a set of options must always be defined (or undefined), as described in the previous section. TF-M provides example _profiles_ which show the options and how they should be used on both client and service side of the integration. Note that to avoid falling back to the default PSA configuration, the Mbed TLS config file must always define the symbol MBEDTLS_PSA_CRYPTO_CONFIG. The symbol to enable the Mbed TLS config MBEDTLS_CONFIG_FILE instead must be available to the unit being compiled which is including psa/crypto.h, i.e. passed by the build system config stage.

Hardware acceleration

The TF-M Crypto partition must handle all HW related crypto tasks, if the platform is capable of offering hardware acceleration or if a complete Secure Element is present. The main difference between the two is that a hardware accelerator does not store keys but just accelerates operations, while a Secure Element is capable of storing keys and the PSA Crypto core running on the host must interface with it to store, retrieve or use them for crypto tasks, etc.

There are currently two methods to interface an accelerator into the Crypto service, and both rely on the Crypto partition fully owning the Crypto hardware, i.e. the memory mapped IO space must be bound the Crypto partition only. Both methods are implemented through the capability of the _backend_ library to either:

  1. Provide a link time mechanism to replace pure SW implementations for algorithms with HW assisted implementations. In this case, the TF-M platform provides some additional HW abstraction through the usage of crypto_hw_accelerator_*() APIs. This is dubbed the _ALT approach and will be soon to be deprecated potentially starting from the release of Mbed TLS 4.0

  2. Provide a cleanly defined interface specification [4] to describe the APIs that a driver must expose to the PSA Crypto core in order for the core to be able to offload operations to hardware. This is the preferred method for interfacing with HW.

Both solutions are currently handled at build time (either compilation or linking) by Mbed TLS. For details on how to integrate a driver please refer directly to the documentation referenced above and to the Mbed TLS repo.

Builtin keys

A particular driver using the interface described in [4] is the TF-M Builtin Key Loader driver [5]. The goal of the driver is to make Mbed TLS aware of transparent builtin keys, i.e. keys which can be read from the core (i.e. not fully opaque keys), but that are normally bound to the platform and provisioned in it, for which it would be more appropriate to treat them as standard transparent keys. The concept of transparent builtin keys is not defined in the spec so it is specifically a non standard extension added by TF-M to the Mbed TLS implementation, which might be changed between releases until a standard solution is adopted. TF-M patches Mbed TLS on the fly to enable such behaviour using patches available in lib/ext/mbedcrypto. Implementations might disable the tfm_builtin_key_loader and then must provide their own alternative storage location for all of the TF-M required builtin keys, e.g. by having them stored in a Secure Element with a corresponding opaque driver.

Service API description

The Alloc and Init modules implement public APIs which are specific to the TF-M Crypto service, and are available only internally to other components of the TF-M Crypto partition. For a detailed description of the prototypes please refer to the tfm_crypto_api.h header.

Table 45 Init and Alloc modules APIs

Function

Module

Caller

Scope

tfm_crypto_init()

Init

SPM

Called during TF-M boot for initialisation. It does modules initialisation (it initializes the Alloc module) and initializes the backend library. Being the partition enabled for the SFN model, it does not implement any IPC specific message handler, instead it relies on the SPM being able to schedule SFN partitions using the SFN dispatcher with little overhead

tfm_crypto_sfn()

Init

SPM

Function to handle an SFN request or to interface with the message handler when running in IPC model

tfm_crypto_init_alloc()

Alloc

Init

Called by tfm_crypto_init(), it initialises the internal memory storage in the TF-M Crypto partition that the service uses to store multipart operation contexts as requested by clients.

tfm_crypto_operation_alloc()

Alloc

Service modules

It allocates a new operation context for a multipart operation. It returns an handle to the allocated context in secure memory.

tfm_crypto_operation_lookup()

Alloc

Service modules

It retrieves a previously allocated operation context of a multipart operation, based on the handle given as input.

tfm_crypto_operation_release()

Alloc

Service modules

It releases a previously allocated operation context of a multipart operation, based on the handle given as input.

tfm_crypto_*_interface()

*

Init

Interface functions called by the dispatcher to service PSA Crypto APIs requests

Configuration parameters

The TF-M Crypto service exposes some configuration parameters to tailor the service configuration in terms of supported functionalities and hence FLASH/RAM size to meet the requirements of different platforms and use cases. These parameters can be provided via CMake parameters during the CMake configuration step and as a configuration header to allow the configuration of the Mbed TLS library. When using Kconfig they are also exported in the Kconfig menus.

Table 46 Configuration parameters table

Parameter

Type

Description

Default

CRYPTO_ENGINE_BUF_SIZE

CMake build configuration parameter

Buffer used by Mbed TLS for its own allocations at runtime. This is a buffer allocated in static memory.

8096 (bytes)

CRYPTO_CONC_OPER_NUM

CMake build configuration parameter

This parameter defines the maximum number of possible concurrent operation contexts (cipher, MAC, hash and key deriv) for multi-part operations, that can be allocated simultaneously at any time.

8

CRYPTO_IOVEC_BUFFER_SIZE

CMake build configuration parameter

This parameter applies only to IPC model builds. In IPC model, during a Service call, input and outputs are allocated temporarily in an internal scratch buffer whose size is determined by this parameter.

5120 (bytes)

CRYPTO_STACK_SIZE

CMake build configuration parameter

Defines the stack size assigned to the crypto partition in higher level of isolation configurations (L1 isolation has a common stack shared by all partitions)

6912 (bytes)

CRYPTO_NV_SEED

CMake build configuration parameter

Uses the Mbed TLS Crypto NV seed feature to provide entropy in case there is no HW acceleration providing HW entropy

Defined for platforms which don’t have CRYPTO_HW_ACCELERATOR

CRYPTO_IOVEC_BUFFER_SIZE

CMake build configuration parameter

Defines the size of scratch buffers to handle input/outputs if the Memory Mapped IOVEC feature is not enabled

5120 (bytes)

CRYPTO_SINGLE_PART_FUNCS_DISABLED

CMake build configuration parameter

When enabled, only the multipart, i.e. non-integrated APIs will be available in the service

Not defined (Profile default)

CRYPTO_*_MODULE_ENABLED

CMake build configuration parameters

When enabled, the correspoding shim layer module and relative APIs are available in the service

Defined (Profile default)

MBEDTLS_CONFIG_FILE

Configuration header

The Mbed TLS library can be configured to support different algorithms through the usage of a configuration header file at build time. This allows for tailoring FLASH/RAM requirements for different platforms and use cases.

lib/ext/mbedcrypto/mbedcrypto_config/tfm_mbedcrypto_config_default.h (Profile default)

MBEDTLS_PSA_CRYPTO_CONFIG_FILE

Configuration header

This header file specifies which cryptographic mechanisms are available through the PSA API when MBEDTLS_PSA_CRYPTO_CONFIG is enabled, and is not used when MBEDTLS_PSA_CRYPTO_CONFIG is disabled. Configuring TF-M always involves having the define enabled.

lib/ext/mbedcrypto/mbedcrypto_config/crypto_config_default.h (Profile default)

References


Copyright (c) 2019-2024, Arm Limited. All rights reserved.