STM32WBA Bluetooth® LE & TrustZone

Revision as of 16:50, 3 November 2023 by Registered User

1. Introduction

As the STM32WBA is based on an Arm® Cortex®-M33, it embeds the Arm® TrustZone® security feature.

The TrustZone introduces hardware isolation allowing a developer to split its application between a Secure and a NonSecure part (sometimes referred to as Trusted and Nontrusted).

The basis of the isolation brought by the TrustZone is to identify critical code & data (keys, private user data, etc.) and isolate it from the rest of the application which does not contain valuable assets.

The majority of the code (Application, Operating system, libraries) should run on the NonSecure side: if a vulnerability is found and exploited by an attacker, the malicious code executes in the NonSecure side, thus it will not be able to break the isolation to access critical assets contained in the Secure side.

While it is technically possible to place a large amount of code in the secure world, it is generally not recommended. The secure world is designed to be a small, highly secure environment used to protect sensitive data and processes. Placing a large amount of code in the secure world increases the attack surface and potentially introduce vulnerabilities that could be exploited by attackers.

For more information, see TrustZone for Cortex-M reference[1]

2. Bluetooth® Low Energy

The Bluetooth® Low Energy (BLE) protocol is complex, therefore, a lot of code is written in order to establish the Bluetooth®LE protocol stack. Placing this stack in the Secure side of the STM32WBA breaks the principle of critical/not critical isolation of the TrustZone.

That’s why, in our architecture, the Bluetooth® LE stack is placed in the NonSecure side.

As the Bluetooth® LE stack uses several cryptographical keys, these keys are also be placed in the NonSecure side. These keys protect the application from an external attacker trying to eavesdrop on the Bluetooth® LE exchange or trying to conduct MITM (Man-in-the-Middle) attacks.

Regarding your application and the potential threats it may face, if one of those threats involves an attacker having the ability to remotely execute code, simply having the Bluetooth® LE keys stored in the non-secure area may not be sufficient to classify your application as secure. To ensure security, it is necessary to implement application-level encryption that utilizes keys isolated by the TrustZone architecture and managed by the Secure

Example architecture
Connectivity:Connectivity WBA BLE TZ Illustration.png


3. Example

In order to build connected IoT devices with isolation properties leveraged by the TrustZone, several configuration steps have to be followed to allow the Bluetooth® LE stack to run one the NonSecure side of the STM32WBA.

To illustrate such a configuration, the example BLE_p2pServer_TZ has been created.

This example is similar to BLE_p2pServer with the TrustZone activated and the Blue LED connected to the Secure side of the MCU: The NonSecure application runs the same application as the basic BLE_p2pServer. When a LED switch is required, the NonSecure application calls a Secure function in the Secure side. This Secure function then handles the GPIO connected to the blue LED.

This example illustrates the following points:

  • How to properly configure the STM32WBA when the TrustZone is activated in order to run the Bluetooth® LE stack.
  • How to connect a peripheral to the Secure side (here, the GPIO connected to the blue LED).
  • How to make a Secure function call (here, the Secure function managing the LED).

4. Configuration

When using the TrustZone, most of the STM32WBA subsystems (Flash, RAM, Peripherals, etc.) are attached to the Secure world. The MCU will boot on the Secure side and configure some of the subsystems as NonSecure for the NonSecure application to use them.

This section describes how to configure a project using CubeMX in order to create a NonSecure application using the Bluetooth® LE stack. To create the overall NonSecure application as a CubeMX project, you can follow the dedicated page STM32WBA Bluetooth® Low Energy - STM32CubeMX Application Conception

The main differences relative to the addition of the TrustZone are described in this section.

4.1. Starting the CubeMX project

When creating a new project, the TrustZone must be enabled first:

TrustZone enabled


From here, you have the same panel described in the BLE_p2pServer page, but every section has a Secure and/or NonSecure configuration (M33S for the Secure and M33NS NonSecure):

Security attribution example


Some of the individual panels also have new configuration options relative to the Secure/NonSecure world. From here, it is possible to attach some of the MCU part to the Secure/NonSecure side.

4.2. IP Configuration

When the TrustZone security is activated by the TZEN option bit in the FLASH_OPTR, the default system security state is detailed below:

  • CPU

– Cortex®-M33 is in secure state after reset. The boot address must be at a secure address.

  • Memory map

– SAU is fully secure after reset. Consequently, all memory map is fully secure. Up to height SAU configurable regions are available for security attribution.

  • Flash memory

– The Flash memory security area is defined by watermark user options.

– Flash block-based security attributions are non-secure after reset.

  • SRAMs

– All SRAMs are secure after reset. MPCBBx (block-based memory protection controller) are secure.

  • Peripherals

– Securable peripherals are non-secure after reset.

– TrustZone-aware peripherals are non-secure after reset. Their secure configuration registers are secure.

  • All GPIO are secure after reset
  • Interrupts

– NVIC: All interrupts are secure after reset. NVIC is banked for Secure and NonSecure state.

– TZIC: All illegal access interrupts are disabled after reset

This section describes how to properly configure these peripherals.

4.2.1. GTZC_S

The Global TrustZone Controller (GTZC) module configuration includes several submodules:

  • TrustZone illegal access Controller (TZIC)

This module allows generating an illegal access interrupt (GTZC_IRQHandler) when an illegal access is detected on a peripheral. In our example, we leave it deactivated.

TZIC configuration



  • TrustZone Security Controller (TZSC) – Privilegeable Peripherals

This module allows to create privilege /unprivileged access on peripherals. In our example, we do not use the different privilege level.

TZSC configuration - Privilegeable Peripherals


Info white.png Information

Note: The GTZC_NS can be used to only manage privileges on a NonSecure side Peripheral.


  • TrustZone Security Controller (TZSC) – Securable Peripherals

This module allows to attach peripherals to the Secure/NonSecure context. In our example, apart from the GPIO, no peripherals are attached to the Secure side.

TZSC configuration - Securable Peripherals


  • Block-Based Memory Protection Controller (MPCBB)

This module allows configuring part of the SRAM to the desired attribution (Secure/NonSecure & Privileged/Unprivileged). MPCBBx allows the configuration for SRAMx :

  • SRAM6 being used by the Bluetooth® LE IP (in NonSecure side), it must be configured as NonSecure & NonPrivileged, with MPCBB6
MPCBB6 configuration


  • SRAM2 being used by the NonSecure application, it must be configured as NonSecure & NonPrivileged, with MPCBB2.
MPCBB2 configuration


Other configurations of SRAM2 & SRAM1 are left to the user, depending on your application requirements.

4.2.2. GPDMA1

In the BLE_p2pServer_TZ example, the GPDMA1 is used by the UART logger.

With the addition of the TrustZone, the peripheral parameters (Channel, Source & Destination) can have security attribution. In our example, as the logging is done on the NonSecure side, all of the DMA parameters have to be NonPrivileged and NonSecure.

GPDMA1 configuration


4.2.3. GPIO

In the BLE_p2pServer_TZ project, the pin PB4 is connected to the Blue LED and controlled by the Secure world. This GPIO should be connected to the Secure world, the other GPIOs being connected to the NonSecure world

GPIO configuration


4.2.4. RTC

As the other peripherals, parts of the RTC can be defined to be accessed only by the Secure world. In our example we leave everything accessible by the NonSecure world

Interrupt configuration


4.2.5. NVIC

There are three different kinds of interrupts:

  • Banked the interrupt triggers in the current state context.
  • Secured the interrupt triggers in the Secure state context.
  • Configurable it is possible to choose the security state in which the interrupt triggers.

For the configurable interrupt, the register NVIC→ITNS manages its attribution. By correctly setting the attribution of your IRQ in the STM32CubeMX project, the right ITNS value is generated.

Once the correct security attribution has been set, it is possible to set the priority of the interrupt in the NVIC_S/NVIC_NS panel.

Interrupt configuration


4.2.6. SAU

The SAU (Secure Attribution Unit) configuration is created by default on the project and it is not possible to configure it with CubeMX.

The SAU configuration is aligned with the Secure and NonSecure project Linker file.

Here the project basic configuration:

Description Region Attribution
NonSecure code 0x08080000 - 0x080FFFFF Non-Secure
Bootloader, OTP, DESIG, Flash user options 0x0BF88000 - 0x0BF97FFF Non-Secure
NSC region 0x0C07E000 - 0x0C07FFFF Non-Secure Callable
NonSecure SRAM 0x20010000 - 0x2001FFFF Non-Secure
NonSecure Peripheral 0x40000000 - 0x4FFFFFFF Non-Secure


This configuration is made in the function TZ_SAU_Setup in the file partition_stm32wba52xx.h

4.2.7. Heap & Stack size

The Secure & NonSecure sides have their own Stack & Heap. It is possible to set them independently in the Project Manager panel:

Heap & Stack configuration


4.3. Secure Service creation

In our example, we create a function in the Secure side to manage the LED1, which will be called by the NonSecure side. This type of function is called a Secure function which realizes a Secure service.

As previously described, the goal of a Secure service is to provide a secure and isolated execution environment within the device. This allows sensitive data and processes to be protected from unauthorized access or tampering by other software or hardware components in the system.

In our example, it is impossible for the NonSecure side to change the LED state without calling the Secure side. This example is simple, but a more complex Service could be built to prevent the NonSecure side from accessing critical data while realizing the application for which it has been built. (Example: A Secure service signing data from the NonSecure world while keeping the keys inside the Secure world)

The Secure services are written in the file secure_nsc.c.

CMSE_NS_ENTRY void SECURE_LED_Blue_Off()
{
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
}

CMSE_NS_ENTRY void SECURE_LED_Blue_On()
{
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);
}


The attributes CMSE_NS_ENTRY tell the compiler that this function is callable from the NonSecure world (i.e. associated veneer and SG instruction are created)

5. Option Bytes Configuration

Once the correct configuration in the Secure project is complete, in order to allow the Secure project to boot and the NonSecure side to execute, some Option bytes have to be correctly set.

  • TrustZone enabling
TZEN


You must first "Apply" this Option Byte to have access to the next Options Byte of this section.

  • Secure Boot

The SECBOOTADD0 defines where the initial MSP value and Reset_Handler address are fetched for the Secure project boot. It has to be correctly set according to our project linker file. In our example 0x0c000000

SECBOOTADD0



  • Secure Watermark

The Flash memory can be protected against NonSecure read and write access. The Secure flash region used in the project should be set as Secure by the Secure Watermark registers and match the project linker file. In our example the range 0x08000000 - 0x0807ffff is dedicated to the Secure side

SECWM1


6. Booting Sequence

This section summarizes how the previously mentioned configuration is performed during the booting phase on a project generated by STM32CubeMX and how it is ordered.

Overall booting sequence


puce1.png
Reset_Handler

The MCU launches the application at the Reset_Handler address present in the VTOR specified by the Option byte SECBOOTADD0.

puce2.png
TZ_SAU_Setup() called

This function handles the initialization of SAU region, SCR & AIRCR configuration, and Interrupt attribution (NVIC.ITNS).

puce3.png
Peripheral Initialization

GTZC_S Initialization with the MPCBB configuration:

puce4.png
Booting NonSecure application

Setting the MSP of the NonSecure application and getting the NonSecure Reset_Handler from the NonSecure VTOR:

Info white.png Information

Note: The NonSecure VTOR address is fixed in main.c file (VTOR_TABLE_NS_START_ADDR) and should match the VTOR address specified in the NonSecure linker file.

puce5.png
Secure service calling

Once the NonSecure side is booted, the Secure functions can be called if they have been created with the attribute CMSE_NS_ENTRY'.'

7. How to Debug ?

As the whole example is split into two different subprojects (Secure/NonSecure), the debugging of the example requires debugging the two projects at the same time.

7.1. IAR

With IAR, the right configuration is already present to the flash & debug of the two projects at the same time.

When selecting the Secure project, in Options > Debugger > Images, the NonSecure image is listed as an extra image.

When the debug and the flash of the Secure project are complete from the IAR panel, the NonSecure project is also flashed, and its symbols are loaded in case of debug.

IAR - Extra Image Download


The Secure project has to be compiled before the NonSecure project. The Download & Debug of the Secure project has to be used to correctly debug the entire example.

IAR - Debug


7.2. STM32CubeIDE

With STM32CubeIDE, the configuration of the flash and debug the two projects has to be performed at the same time.

When selecting the Secure project, in Debug as > Debug Configurations > startup, the NonSecure project has to be added. Select "Add" and choose the NonSecure project.

STM32CubeIDE - Extra Image Download


When the debug and the flash of the Secure project are complete from the STM32CubeIDE panel, the NonSecure project is also flashed, and its symbols are loaded in case of debug.

STM32CubeIDE - Debug


8. How to disable the TrustZone

Warning, if not done correctly, this step could brick your STM32WBA.

The ObtionByte TZEN can only be disabled when doing an RDP regression from RDP1 to RDP0.

If the STM32WBA is already in RDP 2, as this RDP level is final and the OptionBytes are read-only, no RDP regression and TrustZone deactivation are possible.

As the debugger should be connected to modify the OptionByte TZEN and the RDP to 1 preventing a debugger to be connected to the Secure part, the debugger should be connected in "Hot plug" mode when the NonSecure part is booted.

You must be sure that a NonSecure part is booted by the Secure before going in RDP 1. Two methods can be used to achieve this:

  • Use your custom application or with an example which successfully launches the NonSecure part.
  • Use the bootloader with the PH3 pin. Note that a wrong nSWBOOT0, nBOOT0, BOOT_LOCK configuration could prevent this method from working.

Once this preliminary verification is complete, attach STM32CubeProgrammer in Hot plug mode and perform the following step to put TZEN to 0:

  • If not in RDP 1, put the RDP to 1 and "Apply" the configuration.
  • Once in RDP 1, put the RDP to 0 and uncheck the TZEN ObtionByte and "Apply" the configuration in one shot.

The STM32WBA should have the TrustZone disabled.

9. References