TF-M secure peripheral partition

The TF-M secure peripheral partition sample demonstrates the configuration and usage of secure peripherals in a Trusted Firmware-M (TF-M) partition.

Requirements

The sample supports the following development kits:

Hardware platforms

PCA

Board name

Build target

nRF9160 DK

PCA10090

nrf9160dk_nrf9160

nrf9160dk_nrf9160_ns

nRF5340 DK

PCA10095

nrf5340dk_nrf5340

nrf5340dk_nrf5340_cpuapp_ns

Optionally a logic analyzer can be used.

Overview

A secure partition is an isolated module that resides in TF-M. It exposes a number of functions or secure services to other partitions and/or to the firmware in Non-Secure Processing Environment (NSPE). TF-M already contains standard partitions such as crypto, protected storage and firmware update, but you can also create your own partitions.

The sample demonstrates how to configure peripherals as secure peripherals and use them in the secure partition. In this way, the peripheral is only accessible from Secure Processing Environment (SPE), or from the secure partition with isolation level 2 or higher.

The secure partition is located in the secure_peripheral_partition directory. It contains the partition sources, build files and build configuration files. The partition is built by the TF-M build system. See TF-M Build System for more details.

For more information on how to add custom secure partitions, see TF-M secure partition integration guide.

Configuration

To configure a peripheral as secure, the peripheral must be enabled and assigned to the partition, and any interrupt signals must be defined.

See Configuring and building an application for information about how to permanently or temporarily change the configuration.

Secure peripheral

To start using a peripheral as a secure peripheral, it must first be enabled for use in SPE.

CONFIG_NRF_TIMER1_SECURE=y
CONFIG_NRF_SPIM3_SECURE=y
CONFIG_NRF_GPIOTE0_SECURE=y

To use GPIO pins or DPPI channels with secure peripherals, assign them as secure pins or channels. This is done with a bitmask, for example to assign GPIO pin 23 as secure:

CONFIG_NRF_GPIO0_PIN_MASK_SECURE=0x00800000

In addition, the peripheral must be assigned to the specific partition in the partition manifest file:

"mmio_regions": [
        {
                "name": "TFM_PERIPHERAL_TIMER1",
                "permission": "READ-WRITE"
        },
]

Secure interrupt

If the secure peripheral generates interrupts, the interrupt needs to be integrated with TF-Ms interrupt mechanism. The interrupt source and handling type needs to be defined in the partition manifest file:

"irqs": [
        {
                "source": "TFM_TIMER1_IRQ",
                "name": "TFM_TIMER1_IRQ",
                "handling": "FLIH"
        },
]

If the type of interrupt handling is defined as the First Level Interrupt Handling (FLIH), then the FLIH handler needs to be defined. The return value specifies if the Second Level Interrupt Handling signal should be asserted or not.

psa_flih_result_t tfm_timer1_irq_flih(void)
{
        /* Application specific handling */

        if (condition) {
                return PSA_FLIH_SIGNAL;
        } else {
                return PSA_FLIH_NO_SIGNAL;
        }
}

If the type of interrupt handling is defined as the Second Level Interrupt Handling (SLIH), or the FLIH handler specifies the signal to be raised, the interrupt is sent to the partition as a signal. How to clear an interrupt signal depends on the type of interrupt handling.

if (signals & TFM_TIMER1_IRQ_SIGNAL) {
        /* Application specific handling */

        /* FLIH: Reset signal */
        psa_reset_signal(TFM_TIMER1_IRQ_SIGNAL);
}

if (signals & TFM_SPIM3_IRQ_SIGNAL) {
        /* Application specific handling */

        /* SLIH: End of Interrupt signal */
        psa_eoi(TFM_SPIM3_IRQ_SIGNAL);
}

Note

TF-M interrupt signals only assert the signal but do not schedule the partition to run. In cases where the interrupt signal is preempting the non-secure execution, the interrupt signal is not processed until the next time the partition is scheduled to run. The sample demonstrates a workaround for this limitation by triggering an EGU0 interrupt in the firmware in NSPE which calls the secure partition to process the interrupt signals.

Building and Running

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

To build the sample with Visual Studio Code, follow the steps listed on the How to build an application page in the nRF Connect for VS Code extension documentation. See Configuring and building an application for other building scenarios, Programming an application for programming steps, and Testing and optimization for general information about testing and debugging in the nRF Connect SDK.

Testing

The sample displays the following output in the console from the firmware in NSPE:

SPP: send message: Success
SPP: process signals: Success

The sample displays the following output in the console from the firmware in SPE:

IRQ: GPIOTE0 count: 0x00000002
IRQ: TIMER1 count: 0x00000001
IRQ: GPIOTE0 count: 0x00000003
IRQ: TIMER1 count: 0x00000002

In addition, the sample sends a hash as a text output using SPI on two GPIO pins. Connect a logic analyzer to the pins that are used for the SPI output.

Dependencies

This sample uses the TF-M module that can be found in the following location in the nRF Connect SDK folder structure:

  • modules/tee/tfm/