wolfCrypt in TrustZone-M

Using wolfBoot as PKCS#11 secure supervisor

Today, we’re introducing an exciting feature from wolfBoot that makes use of TrustZone-M technology to enhance safe and monitored access to cryptographic operations. By exposing a complete set of standard cryptographic APIs to the application, wolfBoot provides controlled access to the wolfCrypt crypto engine running in the secure domain.

TrustZone-M and domain separation

TrustZone-M essentially creates a secure memory and IO domain within your microcontroller , where system supervision software can execute and provide controlled access to resources to its non-secure counterpart. The secure domain in TrustZone-M is similar to a controlled-access area where only trusted software can be executed. Software running in this domain is usually responsible for enforcing the separation of access permissions for all memory areas and peripherals. It may then optionally assume the role of a passive supervisor by providing special cross-domain API functions (non-secure callables), for a supervised and controlled access to specific functionality otherwise only available in the secure world. This hardware assisted feature is available on most microcontrollers in the ARMv8-M family.

Built-in, hardware assisted security module

Combining this feature with a cryptography engine running in secure mode is an ideal way to create a hardware-assisted separation for secrets and private keys from the application software. It is like having an advanced HSM that can perform crypto operations and store secrets in a security vault, where sensitive information is kept protected. This feature ensures that even if the rest of the system is compromised, the critical information stored in the vault remains secure based on hardware-enforced techniques.

Bootloader supervision

To ensure a trusted boot sequence, the requisite place to set up TrustZone-M, define the separation between the domains, and start the non-secure code execution is, of course, the bootloader. Older versions of wolfBoot were already capable of providing this type of isolation between the two domains, by using a tightly tailored wolfCrypt to verify the authenticity of the application code before staging into non-secure execution mode. We decided to further explore the potential of this integration by adding a fully-equipped wolfCrypt library to wolfBoot, running as a bootloader in the secure domain, and providing a standard way to access cryptographic functions and secure vault to the non-secure application.

The wolfCrypt library is embedded in the bootloader code, and can be used by both the applications/OS, through non-secure callable functions, as well as by wolfBoot itself for its everyday tasks of firmware authentication and integrity verification for securing the boot process.

Resources separation

The first important task to fulfill when preparing a system with TrustZone-M to run non-secure software is to set up and associate each memory segment and peripheral to either domain.
wolfBoot provides configuration options to delimit the areas in the internal flash memory of the microcontroller and separate its own non-volatile memory space from the one dedicated to running the application and receiving the updates in non-secure domain. The example configuration shown in the picture below demonstrates a possible way to divide the internal flash space. The initialization routines in wolfBoot ensure that such a segmentation is enforced through the TrustZone manager embedded in the chip. This configuration implies that the secure and non-secure flash space are logically mapped to different memory locations. A special section is reserved for non-secure callable objects exporting the API for applications to call exposed API functions from the secure domain.

Example flash memory segmentation in an embedded system using wolfBoot as TrustZone-M supervisor

RAM can also be separated by the global trustzone controller (GTZC) in the MCU. This is also enforced at runtime by the microcontroller once the zones have been set up by wolfBoot. The picture below shows an example separation between secure and non-secure RAM sections on a STM32L552 microcontroller, offering a total of 256KB of SRAM in two separate but contiguous banks. In this configuration, half of the total SRAM is dedicated to cryptographic and vault operations in the secure domain. Also in this case, once the GTZC is configured, the RAM is mapped into two separate virtual addresses, starting at 0x3000 0000 and 0x2000 0000 for secure and non-secure domain access, respectively.

Example segmentation of RAM in an embedded system using wolfBoot as TrustZone-M supervisor

PKCS#11

What has been described so far is the infrastructure that wolfBoot is capable of supporting when running on microcontrollers supporting TrustZone-M. All we need at this point is a valid API to access the cryptographic resources offered by wolfBoot running as a TrustZone-M supervisor.

Introduced by RSA laboratories in 2004, PKCS#11 sets the path for vendor-neutral cryptographic token interface (CTI). The standard consists of a well-defined and widely accepted API for the interaction between software and hardware components accessing cryptographic functionality. The use of PKCS#11 for interactions among components in a security infrastructure simplifies the development process, as engineers can rely on standardized interfaces, ultimately reducing development time and risk.

wolfSSL products already support both endpoints for PKCS#11 interoperability. wolfCrypt can be compiled on any platform with built-in support to access a PKCS#11 engine, using the compile time flag –enable-pkcs11, or the equivalent preprocessor definition HAVE_PKCS11. The other side of the communication is provided via a separate library, wolfPKCS11. This module provides the implementation of the API using wolfCrypt as its crypto engine.

When wolfBoot is installed as TrustZone-M secure supervisor, it integrates wolfPKCS11 in its secure domain executable code, which can be accessed by any application in the non-secure domain by calling the corresponding NSC wrappers.

Securing the embedded system architecture

Thanks to the separation between the domains and the integration of a PKCS#11 engine in the secure world, applications can not directly access sensitive cryptographic information such as private keys any more, and rely on the crypto engine under the hood to use these keys when needed. For example, a TLS connection may require the endpoint running on the microcontroller to authenticate itself using a public key mechanism. The private key to generate the signature can be pre-provisioned in the secure vault and used by the TLS to confirm the identity of its local endpoint. Applications already using wolfCrypt APIs to secure data at rest don’t need any adaptations to fit in this new model, because wolfCrypt calls will be translated internally through the wolfCrypt PKCS#11 connector in the non-secure area before calling the actual algorithm implementation in the secure domain, through the NSC API. Finally, any third party application or RTOS integrating a generic PKCS#11 connector can be linked to the NSC API layer and start using the secure, supervised crypto engine right away.
By default all the cryptography functions are implemented in software by wolfCrypt. However, wolfCrypt is very versatile and can make use of hardware security modules or external secure components. This makes this design extendable when more hardware components are in the picture. Compliant usage of some of the functions in wolfCrypt requires a good quality entropy source, which is why we also introduced a secure-world driver for the TRNG of the microcontroller to feed wolfCrypt PRNGs.

Software architecture of an embedded system using wolfBoot as TrustZone-M supervisor. Applications access wolfCrypt in secure world through the PKCS#11 NSC interface

Common use cases

There may be several reasons for a system architect to consider the adoption of wolfBoot as TrustZone-M supervisor in their projects. Some projects rely on two different layers of distribution for the software that eventually runs on target. The owner of the system, who controls the execution of secure and non-secure software on board, may decide to export a SDK to allow customization of the applications. Applications running in the non-secure domain can be mistrusted and sandboxed thanks to the flexibility of the wolfBoot interface to exclude memory sections and peripherals from the non-secure world visibility. In other cases, designers may just be searching for a stable, certified, rock-solid security engine for diverse applications, to facilitate monitoring, updating and managing vulnerabilities through a centralized point. Other scenarios may be simply looking for strong separation of key management, enforced provisioning and avoiding direct interaction between non-secure software and sensitive information, achieved thanks to the policies in place in PKCS#11 for accessing the same tokens with different capabilities and permission masks.

Example on Cortex-M33

As usual, wolfBoot is distributed with example applications to demonstrate the features through real-life porting for evaluation boards for the relevant CPU or microcontrollers in play. For this development, we focused on the STM32L552-Nucleo (Nucleo-L552ZE-Q) board, where all the features needed are accurately documented, which resulted in a smooth integration. A command line tool provided by STMicroelectronics allows users to check and modify the non-volatile registers containing the options for activating and using the TrustZone feature at hardware level. Once the option bytes are correctly configured on the board, wolfBoot can be built using the options WOLFCRYPT_TZ=1 and WOLFCRYPT_TZ_PKCS11=1 to enable wolfCrypt in TrustZone-M with its PKCS#11 interface. The test application that runs in this case initializes a token by creating a new ECC keypair and storing it in the vault. The application then uses the keypair to sign and verify a payload, checking the functionality through the validation of the signature obtained. The file docs/STM32-TZ.md included in wolfBoot provides detailed information on how to build and run the example on the target.

Further research

At wolfSSL we are committed to implement the best solutions for securing your embedded systems. The new wolfBoot feature introduced here is already being expanded to support more hardware platforms, also across different architectures providing hardware-assisted trusted execution environments. Cryptographic APIs between isolated domains can be customized and extended to integrate different interaction models. Moreover, we are looking for the best strategies to extend the wolfCrypt in trustZone-M support with post-quantum cryptography algorithms available in wolfCrypt.

Resources

wolfBoot is available in source code format. The features described in this post will be included in the upcoming version distributed through our download page (https://www.wolfssl.com/download/), and they are already available in the upstream version on our github repository (https://github.com/wolfssl/wolfboot).

If you want to receive more information on wolfBoot running in TrustZone, or if you want to chat with us about secure boot and trusted execution on embedded systems, please contact us at facts@wolfSSL.com or call us at +1 425 245 8247.

Download wolfSSL Now