Skip to main content

Implementing TrustZone on STM32 B-U585I-IOT02A with SBSFU: Secure / Non-Secure Boundaries


Introduction:


In the previous article, we explored the cryptographic operations behind security on the STM32 B-U585I-IOT02A with SBSFU: AES, SHA, and PKI. Those primitives gave us the tools to encrypt, hash, and verify firmware images.


In this second part of the series, we move up one abstraction level and look at Arm TrustZone-M on the STM32U5, and how SBSFU leverages it to split the system into:

  • Secure world – where boot, keys, and critical services run

  • Non-Secure world – where the main application runs, with limited access to secrets

We will cover:

  • The basic TrustZone-M model

  • How the STM32U5 implements secure / non-secure memory and peripherals

  • How SBSFU uses TrustZone to protect the boot chain and keys

  • A conceptual overview of secure gateway functions (SG) and non-secure callable (NSC) regions

  • Practical hints to navigate and configure TrustZone projects in STM32CubeIDE


1. TrustZone-M: Conceptual Overview:


Arm TrustZone-M introduces hardware-enforced isolation in Cortex-M33 microcontrollers:

  • The MCU is logically split into Secure and Non-Secure states.

  • Code, data, and peripherals can be assigned to either domain.

  • The CPU can only cross from non-secure to secure through carefully defined secure gateways.

The goal is to keep the trusted computing base (TCB) small and well-protected, while allowing the non-secure application to run with minimal changes.

From a security perspective, TrustZone gives us:

  • A protected execution environment for the secure bootloader, key management, and crypto services

  • A way to limit the impact of vulnerabilities in the non-secure app, since it cannot directly access secure memory or peripherals

On the STM32U5 (used on the B-U585I-IOT02A), TrustZone is fully supported by both hardware and the ST software ecosystem.


2. Secure / Non-Secure Boundaries on STM32U5:


The STM32U5 uses several mechanisms to implement TrustZone:

  1. Memory Attribution (SAU, IDAU, GTZC)

    • The SAU (Security Attribution Unit) and IDAU (Implementation-Defined Attribution Unit) define which address ranges are SecureNon-Secure, or Non-Secure Callable (NSC).

    • STM’s GTZC (Global TrustZone Controller) extends this to peripherals and internal resources.

  2. Flash and SRAM partitioning

    • Flash is divided into secure, non-secure, and sometimes NSC regions.

    • SRAM can also be split so secrets remain in secure RAM only.

  3. Peripheral security attribution

    • Each peripheral can be configured as secure or non-secure, for example:

      • Cryptographic accelerators and key storage: secure only

      • UART / I2C used by the application: usually non-secure


TrustZone-enabled project template configures these boundaries during secure boot, before jumping to the non-secure application.

3. SBSFU and TrustZone- High-Level Architecture:


In a TrustZone configuration, SBSFU typically follows this structure:

  • Secure Boot + Secure Services (Secure world):

    • SBSFU secure bootloader

    • Firmware verification (hash + signature)

    • Secure storage (keys, version counters, device identity)

    • Secure cryptographic services

    • Secure gateway functions exposed to the non-secure application

  • User Application (Non-Secure world):

    • Main application code (RTOS, stacks, middleware)

    • Networking, sensors, user interface

    • No direct access to secure flash or secure peripherals

The secure image is responsible for:

  1. Running first after reset.

  2. Authenticating the firmware (using AES/SHA/PKI from Article 1).

  3. Configuring TrustZone memory and peripheral attribution.

  4. Setting up the Non-Secure vector table and jumping to the non-secure reset handler.

This ensures that no non-secure code runs before the secure boot process completes.

4. Memory Layout and NSC Region:


To make secure functions callable from non-secure code, TrustZone introduces the concept of a Non-Secure Callable (NSC) region:

  • NSC is a special flash region flagged as secure but callable from non-secure.

  • It contains tiny “veneer” functions that act as gateways into secure services.

  • Non-secure code is allowed to branch only to these NSC veneers, not to arbitrary secure addresses.

A typical memory layout on STM32U5 with SBSFU might look like:

  • Secure Flash

    • Secure bootloader (SBSFU secure)

    • Secure services and key management

    • NSC veneers

  • Non-Secure Flash

    • User application firmware

    • Non-secure libraries, middleware, and drivers

This separation is configured in STM32CubeMX and reflected in the linker scripts:

  • secure.ld – secure image memory regions

  • non_secure.ld – non-secure image memory regions

  • Sections defining .nsc for gateway veneers

The exact filenames vary between Cube releases, but the logic is similar.


5. Boot Flow with TrustZone and SBSFU:


Let’s connect the pieces in a boot sequence:

  1. Reset → CPU starts in Secure state.

  2. SBSFU secure boot runs from secure flash.

    • Initializes hardware and clocks.

    • Verifies integrity/authenticity of the firmware using SHA + PKI (see Video 1).

    • Optionally decrypts images (AES).

  3. TrustZone configuration:

    • Set SAU/IDAU regions for secure, non-secure, and NSC.

    • Configure GTZC for secure/non-secure peripherals and memories.

  4. Non-Secure vector table setup:

    • Secure code writes the address of the non-secure vector table (usually in non-secure flash) into the VTOR_NS register.

  5. Transition to non-secure:

    • Secure code calls __TZ_set_MSP_NS() and __TZ_jump_to_NS() (or equivalent functions) to switch to non-secure stack and jump to the non-secure reset handler.

  6. Non-Secure application starts:

    • From now on, normal application code runs in the non-secure world.

    • When it needs secure services (e.g., a crypto operation on a secret key), it calls NSC veneer functions.

This flow ensures that all security checks and partitioning are done before any non-secure code executes.


6. Secure Services and NSC Veneers:


The secure image can expose a limited API to the non-secure world, such as:

  • “Verify a buffer signature”

  • “Encrypt/decrypt data using a protected key”

  • “Read device identity / certificate”

These services are provided via secure gateways:

  1. In secure code, you define functions with a special attribute, e.g.:

  1. The compiler places them in the NSC region, generating small veneer stubs.

  2. In non-secure code, you declare corresponding function pointers:

  1. The call crosses the secure boundary, executing the secure function while respecting TrustZone rules.

SBSFU can use this mechanism to offer secure cryptographic services to the non-secure application without exposing raw keys or secure memory.

7. TrustZone Configuration in STM32CubeMX / STM32CubeIDE:


When you create or import a TrustZone-enabled project for STM32U5 in STM32CubeMX/IDE, you typically get:

  • Two separate projects (or build targets):

    • Secure project (*_TrustZone_Secure)

    • Non-Secure project (*_TrustZone_NonSecure)

  • Configuration tabs in CubeMX for:

    • Security Attribution of flash and SRAM

    • GTZC settings for each peripheral

    • NSC region size and location

Key files to inspect (names may vary):

  • partition_stm32u5xx.h – memory and peripheral security attribution definitions.

  • main.c (secure) – boot and TrustZone configuration before jumping to non-secure.

  • secure_nsc.c / secure_nsc.h – NSC veneer functions.

  • main.c (non-secure) – non-secure application entry point.

8. How TrustZone Complements the Crypto from Article 1:


In Article 1, we saw that:

  • AES provides confidentiality

  • SHA provides integrity

  • PKI provides authenticity

TrustZone adds a fourth critical dimension: isolation.

  • Crypto alone cannot protect secrets if any code can read the keys.

  • TrustZone keeps keys, root of trust, and security-critical code in the secure domain.

  • The non-secure application can still request services (e.g., “sign this buffer”) without ever seeing the keys themselves.

  • Even if an attacker exploits a buffer overflow in the non-secure app, the secure world remains largely protected by hardware.

Together, cryptography + TrustZone + secure key storage (topic for the next article/video) create a much more robust security architecture for your IoT product.


9. Teaser- Secure Key Storage and Attestation:


Beyond cryptographic operations and TrustZone, we still have:

  • Secure Key Storage – how keys are stored in secure flash or dedicated hardware, and how SBSFU manages them.

  • Attestation – how the device can prove its identity and firmware state to a remote server using those securely stored keys.

These will be covered in the next part of the series, where we will build upon the TrustZone separation introduced here.


10. Conclusion:


In this article we:

  • Introduced Arm TrustZone-M on STM32U5 and its basic concepts.

  • Examined how SBSFU uses TrustZone to enforce secure / non-secure separation during boot.

Comments

Popular posts from this blog

Leetcode 1: Two Sum

  Leetcode Link: https://leetcode.com/problems/two-sum/ 1. Problem Statement (Simple Explanation) You are given: An array of integers nums An integer target You need to  return the indices of two numbers in the array  such that: Conditions: Each input has  exactly one solution . You  cannot use the same element twice . You can return the answer in  any order . 2. Examples Example 1 Input:                                    nums = [2, 7, 11, 15], target = 9 Output:                                 [0, 1] Explanation:                     nums[0]+nums[1]=2+7=9              So we return [0, 1]. Example 2 Input:           ...

Leetcode 3: Longest Substring Without Repeating Characters

  Leetcode Link 1. Problem Statement (Simple Explanation) You are given a string s. You need to find the length of the longest substring of s that does not  contain any repeated characters. A substring is a contiguous sequence of characters in the string. You must return an integer length, not the substring itself. 2. Examples Example 1 Input: s = "abcabcbb" Output: 3 Explanation: Some substrings without repeating characters: "abc", "bca", "cab"The longest length is 3. Example 2 Input: s = "bbbbb" Output: 1 Explanation: All substrings that are valid are just "b". The longest length is 1. Example 3 Input:   s = "pwwkew" Output:   3 Explanation: Possible substrings without repetition: "pw", "wke", "kew". "wke" or "kew" have length 3. "pwke" is not valid because it’s not contiguous in the original string (p and k are separated by ww). Constraints...

Leetcode 2: Add Two Numbers

Leetcode Link: https://leetcode.com/problems/add-two-numbers/ 1. Problem Statement (Simple Explanation) You are given  two non-empty linked lists , l1 and l2, that represent two non-negative integers. Each node contains a  single digit . The digits are stored in  reverse order  (i.e., the 1’s digit is at the head). You need to  add the two numbers  and return the  sum as a linked list , also in reverse order. You can assume: There are  no leading zeros , except when the number itself is 0. 2. Examples Example 1 Input:                l1 = [2,4,3]                l2 = [5,6,4]           Interpreting linked lists as numbers (reverse order): l1 represents 342 l2 represents 465 Output:                [7,0,8] Explanation:        ...