Running applications with Trusted Firmware-M
On nRF5340 and nRF91 Series devices, Trusted Firmware-M (TF-M) is used to configure and boot an application as non-secure.
Overview
TF-M is the reference implementation of Platform Security Architecture (PSA).
It provides a highly configurable set of software components to create a Trusted Execution Environment. This is achieved by a set of secure run time services such as Secure Storage, Cryptography, Audit Logs, and Attestation. Additionally, secure boot through MCUboot in TF-M ensures integrity of runtime software and supports firmware upgrade.
Note
Support for TF-M with minimal version disabled in nRF Connect SDK is currently experimental.
For official documentation, see the TF-M documentation.
The TF-M implementation in nRF Connect SDK is currently demonstrated in the following samples:
All Trusted Firmware-M (TF-M) samples in this SDK
All cryptography samples in this SDK
A series of TF-M integration samples available in Zephyr
The HTTPS Client sample for nRF91 Series devices in this SDK
The Thread samples that support the
nrf5340dk/nrf5340/cpuapp/ns
board target in this SDK
Building
TF-M is one of the images that are built as part of a multi-image application. For more information about multi-image builds, see Multi-image builds using child and parent images.
To add TF-M to your build, enable the CONFIG_BUILD_WITH_TFM
configuration option by adding it to your prj.conf
file.
Note
If you use menuconfig to enable CONFIG_BUILD_WITH_TFM
, you must also enable its dependencies.
By default, TF-M is configured to build the minimal version.
To use the full TF-M, you must disable the CONFIG_TFM_PROFILE_TYPE_MINIMAL
option.
You must build TF-M using a non-secure board target. The following platforms are currently supported:
nRF5340
nRF91 Series
TF-M uses UART1 for logging from the secure application.
To disable logging, enable the CONFIG_TFM_LOG_LEVEL_SILENCE
option.
When building TF-M with logging enabled, UART1 must be disabled in the non-secure application, otherwise the non-secure application will fail to run.
The recommended way to do this is to copy the .overlay file from the TF-M Hello World sample.
Enabling secure services
When using the nRF Security, if CONFIG_BUILD_WITH_TFM
is enabled together with CONFIG_NORDIC_SECURITY_BACKEND
, the TF-M secure image will enable the use of the hardware acceleration of Arm CryptoCell.
In such case, the Kconfig configurations in the Nordic Security Backend control the features enabled through TF-M.
You can configure what crypto modules to include in TF-M by using the CONFIG_TFM_CRYPTO_*
Kconfig options found in file zephyr/modules/trusted-firmware-m/Kconfig.tfm.crypto_modules
.
TF-M utilizes hardware unique keys when the PSA Crypto key derivation APIs are used, and psa_key_derivation_setup
is called with the algorithm TFM_CRYPTO_ALG_HUK_DERIVATION
.
For more information about the PSA cryptography and the API, see PSA Cryptography API 1.0.1.
Minimal build
The default configuration of TF-M has all supported features enabled, which results in a significant memory footprint. A minimal version of the TF-M secure application is provided in nRF Connect SDK to show how to configure a reduced version of TF-M.
The secure services supported by this minimal version allow for generating random numbers, and the platform services.
The minimal version of TF-M is disabled by setting the CONFIG_TFM_PROFILE_TYPE_NOT_SET
option or one of the other build profiles.
When CONFIG_TFM_PROFILE_TYPE_MINIMAL
is set, the configurability of TF-M is severely limited.
Hence, it is not possible to modify the TF-M minimal configuration to create your own variant of the minimal configuration.
Instead, the default configuration must be used as a starting point.
Encrypted ITS
TF-M implements a PSA internal trusted storage (ITS) with encryption and authentication. For more information about the general features of the TF-M ITS service, see TF-M ITS.
To enable TF-M ITS encryption, use the Kconfig option CONFIG_TFM_ITS_ENCRYPTED
.
The ITS encryption is transparent to the user as long as the Master Key Encryption Key (MKEK) is populated before use.
On Nordic Semiconductor devices, the hardware-accelerated AEAD scheme ChaChaPoly1305 is used with a 256 bits key. This key is derived with a key derivation function (KDF) based on NIST SP 800-108 CMAC. The input key of the KDF is the MKEK, a symmetric key stored in the Key Management Unit (KMU) of Nordic Semiconductor devices. The MKEK is protected by the KMU peripheral and its key material cannot be read by software. It can only be used by reference.
The file ID is used as a derivation label for the KDF. This means that each file ID uses a different AEAD key. As long as each file has a unique file ID, the key used for encryption and authentication is unique.
To strengthen data integrity, the metadata of the ITS file (creation flags/size) is used as authenticated data in the encryption process.
The nonce for the AEAD operation is generated by concatenating a random 8-byte seed and an increasing 4-byte counter. The random seed is generated once in the boot process and stays the same until reset.
Logging
TF-M employs two UART interfaces for logging: one for the secure part (MCUboot and TF-M), and one for the non-secure application. By default, the logs arrive on different COM ports on the host PC. See the Manual connection to Virtual COM ports on the nRF5340 DK for more details.
Alternatively, you can configure the TF-M to connect to the same UART as the application by using the CONFIG_TFM_SECURE_UART0
Kconfig option.
Setting this Kconfig option makes TF-M logs visible on the application’s VCOM, without manual connection.
The UART instance used by the application is 0
by default, and the TF-M UART instance is 1
.
By using the CONFIG_TFM_SECURE_UART0
. the TF-M UART instance becomes the same as that of the application’s.
Note
When the TF-M and application use the same UART, the TF-M will disable logging after it has booted and it will only re-enable it again to log a fatal error.
Manual connection to Virtual COM ports on the nRF5340 DK
By default, the nRF5340 DK v1.0.0 requires that you connect specific wires on the kit to receive secure logs on the host PC. Specifically, wire the pins P0.25 and P0.26 of the P2 connector to RxD and TxD of the P24 connector respectively. See Getting logging output with nRF5340 DK on the Working with nRF5340 DK page for more information.
On the nRF5340 DK v2.0.0, there are only two virtual COM ports available. By default, one of the ports is used by the non-secure UART0 peripheral from the application and the other by the UART1 peripheral from the network core.
There are several options to get UART output from the secure TF-M:
Disable the output for the network core and change the pins used by TF-M. The network core will usually have an nRF Connect SDK child image. To configure a child image, see Configuration of the child image section described in Multi-image builds on the nRF5340 DK using child and parent images. To configure logging in an nRF Connect SDK image, see Logging in nRF Connect SDK. To change the pins used by TF-M, the RXD (
CONFIG_TFM_UART1_RXD_PIN
) and TXD (CONFIG_TFM_UART1_TXD_PIN
) Kconfig options in the application image can be set to P1.00 (32) and P1.01 (33).The secure and non-secure UART peripherals can be wired to the same pins. Specifically, physically wire together the pins P0.25 and P0.26 to P0.20 and P0.22, respectively.
If the non-secure application, network core and TF-M outputs are all needed simultaneously, additional UART <-> USB hardware is needed. A second nRF DK can be used if available. Pin P0.25 needs to be wired to the TXD pin, and P0.26 to the RXD pin of the external hardware. These pins will provide the secure TF-M output, while the two native COM ports of the DK will be used for the non-secure application and the network core output.
Limitations
The following limitations apply to TF-M and its usage:
Firmware Update service is not supported.
The following crypto modules or ciphers are not supported:
AES output feedback (AES-OFB) mode.
AES cipher feedback (AES-CFB) mode.
Isolation level 3 is not supported.
In Isolation level 2 or higher, the number of peripherals configured as secure in Application Root of Trust (ARoT) is limited by the number of available MPU regions.
Nordic Semiconductor devices only support the GCC toolchain for building TF-M.
TF-M partition alignment requirements
TF-M requires that secure and non-secure partition addresses must be aligned to the flash region size CONFIG_NRF_TRUSTZONE_FLASH_REGION_SIZE
.
nRF Connect SDK ensures that they in fact are aligned and comply with the TF-M requirements.
In nRF53 and nRF91 series TF-M uses the SPU to enforce the security policy between the partitions, so the CONFIG_NRF_TRUSTZONE_FLASH_REGION_SIZE
is set to the SPU flash region size.
In nRF54L15 TF-M uses the MPC to enforce the security policy between the partitions, so the CONFIG_NRF_TRUSTZONE_FLASH_REGION_SIZE
is set to the MPC region size.
When the Partition Manager is enabled, it will take into consideration the alignment requirements. But when the static partitions are used, the user is responsible for following the alignment requirements.
If you are experiencing any partition alignment issues when using the Partition Manager, check the Known issues page on the main branch.
The partitions which need to be aligned with the TrustZone flash region size are partitions tfm_nonsecure
and nonsecure_storage
.
Both the partition start address and the partition size need to be aligned with the flash region size CONFIG_NRF_TRUSTZONE_FLASH_REGION_SIZE
.
Note that the tfm_nonsecure
partition is placed after the tfm_secure
partition, thus the end address of the tfm_secure
partition is the same as the start address of the tfm_nonsecure
partition.
As a result, altering the size of the tfm_secure
partition affects the start address of the tfm_nonsecure
partition.
The following static partition snippet shows a non-aligned configuration for nRF5340 which has a TrustZone flash region size CONFIG_NRF_TRUSTZONE_FLASH_REGION_SIZE
of 0x4000.
tfm_secure:
address: 0x4000
size: 0x4200
span: [mcuboot_pad, tfm]
mcuboot_pad:
address: 0x4000
size: 0x200
tfm:
address: 0x4200
size: 0x4000
tfm_nonsecure:
address: 0x8200
size: 0x4000
span: [app]
app:
address: 0x8200
size: 0x4000
In the above example, the tfm_nonsecure
partition starts at address 0x8200, which is not aligned with the requirement of 0x4000.
Since tfm_secure
spans the mcuboot_pad
and tfm
partitions we can decrease the size of any of them by 0x200 to fix the alignment issue.
We will decrease the size of the (optional) mcuboot_pad
partition and thus the size of the tfm_secure
partition as follows:
tfm_secure:
address: 0x4000
size: 0x4000
span: [mcuboot_pad, tfm]
mcuboot_pad:
address: 0x4000
size: 0x0
tfm:
address: 0x4000
size: 0x4000
tfm_nonsecure:
address: 0x8000
size: 0x4000
span: [app]
app:
address: 0x8000
size: 0x4000
Migrating from Secure Partition Manager to Trusted Firmware-M
The interface to TF-M is different from the interface to SPM. Due to that, the application code that uses the SPM Secure Services needs to be ported to use TF-M instead.
TF-M can replace the following SPM services:
spm_request_system_reboot
withtfm_platform_system_reset
.spm_request_random_number
withpsa_generate_random
orentropy_get_entropy
.spm_request_read
withtfm_platform_mem_read
orsoc_secure_mem_read
.spm_s0_active
withtfm_platform_s0_active
.spm_firmware_info
withtfm_firmware_info
.
The following SPM services have no replacement in TF-M:
spm_prevalidate_b1_upgrade
spm_busy_wait
spm_set_ns_fatal_error_handler
Note
By default, TF-M configures memory regions as secure memory, while SPM configures memory regions as non-secure.
The partitions tfm_nonsecure
, mcuboot_secondary
, and nonsecure_storage
are configured as non-secure flash memory regions.
The partition sram_nonsecure
is configured as a non-secure RAM region.
If a static partition file is used for the application, make the following changes:
Rename the
spm
partition totfm
.Add a partition called
tfm_secure
that spansmcuboot_pad
(if MCUboot is enabled) andtfm
partitions.Add a partition called
tfm_nonsecure
that spans the application, and other possible application partitions that must be non-secure.For non-secure storage partitions, place the partitions inside the
nonsecure_storage
partition.