TF-M: PSA template

This sample provides a template for Arm Platform Security Architecture (PSA) best practices on nRF devices.

Requirements

The sample supports the following development kits:

Hardware platforms

PCA

Board name

Board target

nRF9161 DK

PCA10153

nrf9161dk

nrf9161dk/nrf9161/ns

nRF9160 DK

PCA10090

nrf9160dk

nrf9160dk/nrf9160/ns

nRF9151 DK

PCA10171

nrf9151dk

nrf9151dk/nrf9151/ns

nRF5340 DK

PCA10095

nrf5340dk

nrf5340dk/nrf5340/cpuapp/ns

When built for a board target with the */ns variant, the sample is configured to compile and run as a non-secure application with Cortex-M Security Extensions enabled. Therefore, it automatically includes Trusted Firmware-M that prepares the required peripherals and secure services to be available for the application.

Overview

This sample uses Trusted Firmware-M, nRF Secure Immutable bootloader and MCUboot to demonstrate how to implement the best practices that comply with the Arm PSA requirements. It includes provisioning the device with keys and being able to perform a device firmware update. The sample prints information about the identity of the device and the firmware versions that are currently running.

On the nRF5340 devices, this sample also includes the B0n bootloader and the empty_net_core image for demonstrating the network core firmware update process.

Building and running

This sample can be found under samples/tfm/tfm_psa_template in the nRF Connect SDK folder structure.

When built as firmware image for a board target with the */ns variant, the sample has Cortex-M Security Extensions (CMSE) enabled and separates the firmware between Non-Secure Processing Environment (NSPE) and Secure Processing Environment (SPE). Because of this, it automatically includes the Trusted Firmware-M (TF-M). To read more about CMSE, see Processing environments.

To build the sample, follow the instructions in Building an application for your preferred building environment. See also Programming an application for programming steps and Testing and optimization for general information about testing and debugging in the nRF Connect SDK.

Note

When building repository applications in the SDK repositories, building with sysbuild is enabled by default. If you work with out-of-tree freestanding applications, you need to manually pass the --sysbuild parameter to every build command or configure west to always use it.

The sample requires that the device is provisioned using the provisioning image sample. Build and flash the provisioning image sample to provision the device with the PSA root-of-trust security parameters.

west build -b nrf5340dk/nrf5340/cpuapp nrf/samples/tfm/provisioning_image -d build_provisioning_image
west flash --erase --recover -d build_provisioning_image

Build and flash the TF-M PSA template sample. Do not flash with --erase as this will erase the PSA platform security parameters and they will be lost.

west build -b nrf5340dk/nrf5340/cpuapp/ns nrf/samples/tfm/tfm_psa_template
west flash

Testing

After programming the sample, the following output is displayed in the console:

*** Booting nRF Connect SDK v2.6.99-27b5931e8742 ***
*** Using Zephyr OS v3.6.99-b5cf30402984 ***
Attempting to boot slot 0.
Attempting to boot from address 0x8200.
Verifying signature against key 0.
Hash: 0x43...7f
Firmware signature verified.
Firmware version 1
*** Booting My Application v2.1.0-dev-0b5810de95eb ***
*** Using nRF Connect SDK v2.6.99-27b5931e8742 ***
*** Using Zephyr OS v3.6.99-b5cf30402984 ***
*** Booting nRF Connect SDK v2.6.99-27b5931e8742 ***
*** Using Zephyr OS v3.6.99-b5cf30402984 ***
build time: May 13 2024 17:13:28

FW info S0:
Magic: 0x281ee6de8fcebb4c00003502
Total Size: 60
Size: 0x000081c8
Version: 1
Address: 0x00008200
Boot address: 0x00008200
Valid: 0x9102ffff (CONFIG_FW_INFO_VALID_VAL=0x9102ffff)

FW info S1:
Magic: 0x281ee6de8fcebb4c00003502
Total Size: 60
Size: 0x000081c8
Version: 1
Address: 0x00014200
Boot address: 0x00014200
Valid: 0x9102ffff (CONFIG_FW_INFO_VALID_VAL=0x9102ffff)

Active slot: S0

Requesting initial attestation token with 64 byte challenge.
Received initial attestation token of 303 bytes.

0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F
D2 84 43 A1 01 26 A0 58  E4 AA 3A 00 01 24 FF 58  |  ..C..&.X..:..$.X
40 00 11 22 33 44 55 66  77 88 99 AA BB CC DD EE  |  @.."3DUfw.......
FF 00 11 22 33 44 55 66  77 88 99 AA BB CC DD EE  |  ..."3DUfw.......
FF 00 11 22 33 44 55 66  77 88 99 AA BB CC DD EE  |  ..."3DUfw.......
FF 00 11 22 33 44 55 66  77 88 99 AA BB CC DD EE  |  ..."3DUfw.......
FF 3A 00 01 24 FB 58 20  3B 32 D3 C6 4F E0 9E 44  |  .:..$.X ;2..O..D
85 33 05 C0 7E 1B 14 39  C0 73 22 2E AE 63 68 8C  |  .3..~..9.s"..ch.
26 66 52 D2 84 50 EF 56  3A 00 01 25 00 58 21 01  |  &fR..P.V:..%.X!.
70 7D AE 14 A9 68 1F 77  99 6F F8 02 CF 69 C2 47  |  p}...h.w.o...i.G
BF 3A 10 DD EA C3 74 6E  0B F7 45 CF 2A 25 A9 DA  |  .:....tn..E.*%..
3A 00 01 24 FA 58 20 AA  AA AA AA AA AA AA AA BB  |  :..$.X .........
BB BB BB BB BB BB BB CC  CC CC CC CC CC CC CC DD  |  ................
DD DD DD DD DD DD DD 3A  00 01 24 F8 20 3A 00 01  |  .......:..$. :..
24 F9 19 30 00 3A 00 01  24 FE 01 3A 00 01 24 F7  |  $..0.:..$..:..$.
60 3A 00 01 25 01 60 3A  00 01 24 FC 60 58 40 00  |  `:..%.`:..$.`X@.
E0 AB 97 6B C1 24 8D AF  C9 E1 1C 77 E4 5E 1D 8E  |  ...k.$.....w.^..
0D 44 61 76 28 A5 0D A1  BE A3 2D B2 A0 35 77 0E  |  .Dav(.....-..5w.
78 72 7D E6 BE A1 10 A2  DC 7C ED 87 76 C7 33 E4  |  xr}......|..v.3.
4E 8C 39 3D AA EC 40 EB  31 4B D5 68 80 53 77     |  N.9=..@.1K.h.Sw

Firmware update

This sample supports firmware update of both the application and TF-M, and the second stage bootloader.

The firmware update process requires signature verification keys in order to sign the images used in the process. The nRF Secure Immutable bootloader and MCUboot will use signing keys that should not be used in production. For signing and verifying images, use ECDSA with secp256r1-sha256, which is supported by the nRF Connect SDK cryptographic libraries nrf_oberon crypto library and nRF CC310 bootloader crypto library.

Below is an example of how to generate and use the keys.

Generate security keys if needed:

mkdir _keys
python3 bootloader/mcuboot/scripts/imgtool.py keygen -t ecdsa-p256 -k ~/ncs/_keys/mcuboot_priv.pem
python3 bootloader/mcuboot/scripts/imgtool.py keygen -t ecdsa-p256 -k ~/ncs/_keys/nsib_priv.pem

Update the sysbuild.conf file to set the private signing keys for MCUboot and NSIB:

SB_CONFIG_BOOT_SIGNATURE_KEY_FILE="/home/user/ncs/_keys/mcuboot_priv.pem"
SB_CONFIG_SECURE_BOOT_SIGNING_KEY_FILE="/home/user/ncs/_keys/nsib_priv.pem"

See Signature keys for more information on how to generate and use keys for a project.

The bootloader and the application can be updated using the mcumgr command-line tool. See SMP server for installation and usage instructions.

Note

Remember to rebuild the sample with the updated keys before proceeding with the firmware update.

Application and TF-M firmware update

Use firmware update to update the application and TF-M firmware. For the image to be updatable, the firmware image version CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION has to be updated to a higher version. See Downgrade protection for information on downgrade protection in MCUboot.

To upload a new application image, build an application with an updated image version.

west build -b nrf5340dk/nrf5340/cpuapp/ns nrf/samples/tfm/tfm_psa_template -d build_update \
-DCONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION=\"1.2.3\"

Then upload the new application image to the device.

mcumgr --conntype serial --connstring dev=/dev/ttyACM1,baud=115200,mtu=512 image list
mcumgr --conntype serial --connstring dev=/dev/ttyACM1,baud=115200,mtu=512 image upload \
build_update/tfm_psa_template/zephyr/zephyr.signed.bin

Once the new application image is uploaded, the hash of the image is shown in the image list. Flag the image to be tested on next reboot using its hash.

mcumgr --conntype serial --connstring dev=/dev/ttyACM1,baud=115200,mtu=512 image list
mcumgr --conntype serial --connstring dev=/dev/ttyACM1,baud=115200,mtu=512 image test <hash>

Trigger the application update by initiating a reset. The verification of the image will happen during the update process.

mcumgr --conntype serial --connstring dev=/dev/ttyACM1,baud=115200,mtu=512 reset

Bootloader firmware update

To upload a new bootloader image, build a bootloader targeting the correct bootloader slot with an updated firmware image version.

west build -b nrf5340dk/nrf5340/cpuapp/ns nrf/samples/tfm/tfm_psa_template -d build_update \
-Dmcuboot_CONFIG_FW_INFO_FIRMWARE_VERSION=2

List the current firmware images and upload a bootloader image that targets the non-active bootloader slot.

mcumgr --conntype serial --connstring dev=/dev/ttyACM1,baud=115200,mtu=512 image list
mcumgr --conntype serial --connstring dev=/dev/ttyACM1,baud=115200,mtu=512 image upload \
build_update/signed_by_mcuboot_and_b0_s1_image.bin

Once the new bootloader image is uploaded, the hash of the image is shown in the image list. Flag the image to be tested on next reboot using its hash.

mcumgr --conntype serial --connstring dev=/dev/ttyACM1,baud=115200,mtu=512 image list
mcumgr --conntype serial --connstring dev=/dev/ttyACM1,baud=115200,mtu=512 image test <hash>

Trigger the bootloader update by initiating a reset. The verification of the image will happen during the update process.

mcumgr --conntype serial --connstring dev=/dev/ttyACM1,baud=115200,mtu=512 reset

Network core update (nRF5340 only)

To upload a new network core image, build the empty_net_core image with an updated firmware image version.

west build -b nrf5340dk/nrf5340/cpuapp/ns nrf/samples/tfm/tfm_psa_template -d build_update \
-Dempty_net_core_CONFIG_FW_INFO_FIRMWARE_VERSION=2

Then upload the new network core image to the device. Note that the image is uploaded to the network core slot.

mcumgr --conntype serial --connstring dev=/dev/ttyACM1,baud=115200,mtu=512 image upload \
build_update/signed_by_mcuboot_and_b0_empty_net_core.bin -e -n 1

mcumgr --conntype serial --connstring dev=/dev/ttyACM1,baud=115200,mtu=512 image list

Once the network core image is uploaded, the hash of the image is shown in the image list as image 1 in slot 1. Flag the image to be tested on next reboot using its hash.

mcumgr --conntype serial --connstring dev=/dev/ttyACM1,baud=115200,mtu=512 image test <hash>

Trigger the network core update by initiating a reset. The verification of the image will happen during the update process.

mcumgr --conntype serial --connstring dev=/dev/ttyACM1,baud=115200,mtu=512 reset

Alternatively, you can conduct a manual reset to trigger the network core update. This allows you to observe the update process in the application and network core console outputs.

Simultaneous application and network core update (nRF5340 only)

When the interface between the application and network core is updated, both the application and network core images must be updated simultaneously. To do this, build the application image with an updated image version and the network core image with an updated firmware image version.

west build -b nrf5340dk/nrf5340/cpuapp/ns nrf/samples/tfm/tfm_psa_template -d build_update \
-DCONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION=\"1.2.4\" -Dempty_net_core_CONFIG_FW_INFO_FIRMWARE_VERSION=3

Then upload the new application and network core images to the device. Note that the application image is uploaded to the application slot, and the network core image is uploaded to the network core slot.

mcumgr --conntype serial --connstring dev=/dev/ttyACM1,baud=115200,mtu=512 image upload \
build_update/tfm_psa_template/zephyr/zephyr.signed.bin -e -n 0

mcumgr --conntype serial --connstring dev=/dev/ttyACM1,baud=115200,mtu=512 image upload \
build_update/signed_by_mcuboot_and_b0_empty_net_core.bin -e -n 1

mcumgr --conntype serial --connstring dev=/dev/ttyACM1,baud=115200,mtu=512 image list

Once the images are uploaded, the hash of the images is shown in the image list. The application image is image 1 in slot 0, and the network core image is image 1 in slot 1. To allow the application and network core images to be updated simultaneously, first confirm the network core image and then the application image.

mcumgr --conntype serial --connstring dev=/dev/ttyACM1,baud=115200,mtu=512 image confirm <network core image hash>

mcumgr --conntype serial --connstring dev=/dev/ttyACM1,baud=115200,mtu=512 image confirm <application core image hash>

Trigger the core updates by initiating a reset. The verification of the images will happen during the update process.

mcumgr --conntype serial --connstring dev=/dev/ttyACM1,baud=115200,mtu=512 reset

Alternatively, you can conduct a manual reset to trigger the core updates. This allows you to observe the update process in the application and network core console outputs.

Dependencies