ARM CORTEX-M · PRESENTATION 08

TrustZone for Armv8-M

Secure / Non-Secure State · SAU · IDAU · SG / BXNS · Veneer Tables · PSA · TF-M
A second execution state, orthogonal to Privileged/Unprivileged
02

Why TrustZone on MCUs

  • By 2015 the IoT market needed per-device cryptographic identity: secure boot, firmware update signatures, attested telemetry.
  • Adding a second secure-element chip (SE050 etc.) doubled BoM cost and board area.
  • On A-profile, TrustZone had been doing the same job since 2004 (phones). Arm re-architected the concept for MCUs with Armv8-M (2016).
  • v8-M TrustZone is now the backbone of PSA Certified, Trusted Firmware-M, and most IoT security standards.

Key design goal

Arm wanted an isolation mechanism that:

  • was not an MPU (MPU permission-matrix depends on privilege + task);
  • supported deterministic, cycle-level interrupt latency;
  • added < 5 % area to a Cortex-M33 over an M3;
  • could be enabled or disabled at synthesis — leave out for non-secure SKUs.
03

TrustZone-A vs TrustZone-M

TrustZone-A (2004)TrustZone-M (2016)
Introduced inARM1176JZ-SCortex-M23 / M33
State switchingSoftware-controlled via SMC (Secure Monitor Call); flush pipeline; context saveHardware-controlled; automatic context save on cross-domain call
Secure monitorDedicated secure-monitor layer (EL3)No monitor layer; S and NS call each other directly via SG + BXNS
IRQ handlingSMC into monitorDirect — an IRQ targets S or NS based on NVIC.ITNS bit
LatencyHundreds of cycles per switch< 10 cycles per switch
v8-M TrustZone is deliberately not a mini-version of A-profile TrustZone. It's a ground-up design that preserves the Cortex-M's core property — fast, deterministic interrupt entry.
04

Two Worlds

Non-Secure World • Application firmware, RTOS, user tasks • Can be field-updated freely • Cannot read Secure code or data • Cannot configure SAU / NVIC_S / MPU_S • Calls into Secure world only via declared NSC entry points MSP_NS · PSP_NS · MSPLIM_NS · PSPLIM_NS Secure World • TF-M / secure bootloader / crypto • Device identity & attestation keys • Root-of-trust, secure RNG, HUK • Signs firmware updates • Provides hardened APIs to NS (sign, verify, decrypt, attest) MSP_S · PSP_S · MSPLIM_S · PSPLIM_S NSC Gateway SG instruction BXNS / BLXNS
05

The 2 × 2 Execution Matrix

Privileged
Unprivileged
Secure
S-Priv
Secure kernel (TF-M core, secure bootloader). Full access to SAU, S-NVIC, MPU_S, keys.
S-Unpriv
Secure user tasks. Can call S APIs but not change security config. MPU_S constrains them.
Non-Secure
NS-Priv
NS kernel / RTOS. Full NS system access. Cannot see S memory or S registers.
NS-Unpriv
NS tasks / apps. MPU_NS constrains them further. Most application code lives here.
Four independent banks of CONTROL, PRIMASK, FAULTMASK, BASEPRI, MSP, PSP, MSPLIM, PSPLIM, and MPU regions — the CPU holds all of them and swaps the active set on state transitions.
06

Attribution — Who Decides S vs NS?

Every address has a security attribute determined on every bus access by:

  1. IDAU — Implementation-Defined Attribution Unit. Hard-wired by the SoC vendor; typically partitions the 4 GiB at power-of-two boundaries.
  2. SAU — Security Attribution Unit. Programmable by the Secure kernel at runtime; up to 8 regions.

Result: attribute ∈ { Secure, Non-Secure, Non-Secure Callable (NSC) }.

Secure
NSC
Secure
Non-Secure
S
NS

Example attribution of the flash region: mostly Secure, with a small NSC "door" holding gateway veneers, then a Non-Secure chunk for application firmware.

Rule: if IDAU and SAU disagree, the more secure attribution wins. The vendor can thus guarantee a region stays Secure no matter what the SAU says — the SAU can only carve an already-S region into NS, not upgrade an NS region to S.
07

SAU — Security Attribution Unit

  • Up to 8 programmable regions (or 0/4/8 by impl option).
  • Each region: base + limit (32-byte-aligned), plus attribute bits:
    • ENABLE
    • NSC (non-secure-callable)
  • Attribute encoding:
    • region match, NSC=0 → Non-Secure
    • region match, NSC=1 → NSC
    • no region match → Secure (default)
  • Configured only from Privileged Secure. NS code cannot read or write the SAU.
/* Mark 0x0807_F800..0x0808_0000 as NSC (veneers) */
SAU->RNR  = 0;
SAU->RBAR = 0x0807F800UL;
SAU->RLAR = 0x0807FFE0UL | (1u << 1) | 1;  /* NSC + ENABLE */

/* Mark 0x0808_0000..0x080F_FFFF as NS (app flash) */
SAU->RNR  = 1;
SAU->RBAR = 0x08080000UL;
SAU->RLAR = 0x080FFFE0UL | 1;              /* ENABLE */

/* Everything else stays Secure by default */
SAU->CTRL = 1;                              /* ENABLE SAU */
__DSB(); __ISB();
08

IDAU — The Vendor's Fixed Partitioning

  • Implemented entirely by the SoC vendor; not configurable at runtime.
  • Typical scheme splits a region in half:
    • lower half → Non-Secure alias
    • upper half → Secure alias
    Same underlying memory, two views. Accessing the "wrong" alias from the wrong state → SecureFault.
  • This trick means NS and S code can share an address space and a memory chip, with hardware-enforced mirroring.

Example — STM32L5

  • Flash S alias: 0x0C00_0000
  • Flash NS alias: 0x0800_0000
  • SRAM S: 0x3000_0000
  • SRAM NS: 0x2000_0000

Linker puts TF-M at 0x0C00_0000; NS app at 0x0800_0000; both actually live in the same flash bank. The IDAU enforces "NS world can only reach via 0x0800".

09

NSC — Non-Secure Callable Regions

  • A sub-class of Secure memory — marked NSC by SAU.
  • Only memory with the NSC attribute may hold entry points that NS code is allowed to call.
  • The very first instruction in an NSC-marked 32-bit slot must be SGSecure Gateway. Anything else → SecureFault on NS call.
  • Rationale: prevents an attacker from jumping into the middle of a Secure function via a crafted pointer. The only door is an SG.
/* Veneer (NSC) section in Secure image */

  .section ".gnu.sgstubs"        /* linker places in NSC */

  .global __acle_se_crypto_decrypt
__acle_se_crypto_decrypt:
    SG                              ; secure gateway entry
    B    crypto_decrypt_impl        ; tail-call to real impl

The compiler emits these veneers automatically when a function is attributed cmse_nonsecure_entry.

10

The SG Instruction

SG   ; Secure Gateway

; Preconditions:
;   current state = Non-Secure
;   PC  is in an NSC region
;   SG is the first halfword at this address

; Effects (atomically):
;   switch to Secure state
;   clear FAULTMASK_NS to avoid FAULTMASK escape
;   return-address LR bit[0] = 0 (FNC_RETURN tag)
;   pipeline refetches in new state
  • One instruction does what took many on A-profile.
  • Inside Secure, the function executes normally.
  • Returning is just BXNS LR (see next slide).
  • If SG is executed in any other context (already Secure, or PC not in NSC) → NOP on Secure side, or SecureFault.
The hardware ensures the only way for NS code to become Secure is to hit an SG in an NSC region. No call-gate, no trampoline, no software trust-on-first-use.
11

BXNS & BLXNS — Leaving Secure

InstructionMeaningUse case
BXNS RmBranch and switch to Non-Secure. Targets LR or a function pointer.Return from a secure function that was called from NS; launch NS firmware from Secure bootloader.
BLXNS RmBranch-with-link and switch to NS. Push a FNC_RETURN magic value onto the S stack so a BX lr from NS can re-enter S safely.Secure-world calls a Non-Secure callback (e.g. a user-provided log function).
  • BXNS clears LR bit 0 and tags it so the return address is marked non-secure.
  • The CPU pushes an integrity signature when the call crosses domains, so attempts to forge the return path fail.
  • BXNS is the only legitimate way to leave Secure. An ordinary BX lr with an LR pointing into NS memory → SecureFault.
Why BLXNS exists: a secure crypto library sometimes wants to invoke an NS logger. Without a safe "call-back into NS" primitive, secure code would have to trust that NS returns politely. BLXNS encodes the policy in hardware.
12

The Veneer Table Pattern

Non-Secure app int sign_payload(uint8_t *p, size_t n) { uint8_t buf[32]; return psa_mac_sign(...); } ↓ BL psa_mac_sign NSC Veneer psa_mac_sign: SG B __acle_se_psa_mac_sign ; linker auto-generated ; 8 bytes total (SG + B) Secure implementation __acle_se_psa_mac_sign: PUSH {r4, lr} BL sanitize_ns_ptrs BL crypto_engine POP {r4, lr} BXNS lr ; back to NS
13

ACLE Annotations

/* Secure library header, shared with NS */

#include <arm_cmse.h>

/* Exported to NS */
__attribute__((cmse_nonsecure_entry))
int psa_mac_sign(const uint8_t *buf,
                 size_t         n,
                 uint8_t       *out);

/* Callback called from S back into NS */
typedef void (*ns_log_t)(const char *)
    __attribute__((cmse_nonsecure_call));
  • cmse_nonsecure_entry — marks an exported function; compiler emits an SG-gated veneer, clears caller-saved regs that might leak S state before BXNS.
  • cmse_nonsecure_call — marks a pointer to NS code; compiler emits BLXNS with the right safety scrubbing.
  • CMSE helper intrinsics like cmse_check_address_range() let the Secure handler verify that an NS pointer really points into NS memory — essential defence against the "Bubble" attack.
14

Banked System Registers

RegisterBanked?Notes
MSP / PSP✓ per stateMSP_S · PSP_S · MSP_NS · PSP_NS
MSPLIM / PSPLIM✓ per stateHW stack-overflow detection banks per world
CONTROLSeparate nPRIV & SPSEL for S and NS threads; FPCA shared
PRIMASK / BASEPRI / FAULTMASKNS cannot set its mask to block S IRQs
VTORVTOR_S, VTOR_NS
MPUMPU_S, MPU_NS — each with own region config
NVIC priority / enableNS can only write NS IRQ masks; S can touch both
SYSCTL / AIRCRbanked fieldsSome fields (e.g. PRIGROUP) per state; reset controls Secure-only

The silicon area cost is mostly flops for these banked registers — still < 5 % overall, which is why Arm could price TrustZone-capable cores competitively.

15

NVIC & IRQ Targeting

  • Each external IRQ has an ITNS bit in NVIC_ITNS[n]: 0 = IRQ targets Secure, 1 = NS.
  • ITNS is writable only from Privileged Secure. NS cannot re-target an IRQ.
  • IRQ of priority higher than current state may preempt, even across domains — that is when the integrity signature is stacked.
  • System exceptions (HardFault, NMI, SecureFault, BusFault) may be configured S-target or NS-target via AIRCR.BFHFNMINS.

Typical policy

  • Crypto engine, RNG, HUK: Secure IRQ.
  • Radio, USB, UART, DMA to app buffers: NS IRQ.
  • Shared I²C with secure sensor: usually Secure IRQ with a forwarded NS notification via mailbox.
The SAU also has analogous SAU-region-attribute-based IRQ routing in future extensions, but ITNS remains the core mechanism for v8-M.
16

Exception Across Domains

S preempts NS

  1. NS code running; S-targeted IRQ arrives at higher priority.
  2. CPU stacks 8 "basic" words on NS stack.
  3. CPU then stacks an additional context (R4-R11, "state context") plus a 4-word integrity signature, again on the NS stack.
  4. Switches to Secure handler; all caller-saved NS regs are cleared.
  5. On return, the signature is verified. Mismatch → Secure fault.

NS preempts S (rare)

  • Only possible if an NS IRQ has priority higher than the executing S handler.
  • By default, NS is not allowed to preempt S — the AIRCR.PRIS bit forces NS priorities to the low half.
  • When it does happen, additional S-context is stacked on the S stack (protected from NS read).
Lesson: cross-domain preemption is where the integrity signature lives — without it, NS could overwrite the return frame during the brief window before S resumes.
17

The Integrity Signature

  • On any exception that crosses state, CPU pushes a 4-word "signature frame" to the incoming side's stack.
  • Contains 0xFEF5EDA5 as a magic tag, plus state information.
  • On exception return, CPU checks the signature. If it has been altered → the CPU does not restore the stacked context and raises a Secure fault.
  • Defends against:
    • NS code corrupting the S-return path,
    • NS code forging an EXC_RETURN into S,
    • Race conditions where NS sees a partial S frame.

Why a signature, not encryption?

The whole point is to be fast — a few cycles of compare, not a crypto op. The signature is magic-value-plus-metadata, and it's checked only by the CPU. NS code trying to guess the right bytes can't, because the metadata includes current state bits that NS cannot read.

18

PSA & Trusted Firmware-M

Platform Security Architecture (PSA)

  • Arm-led specification defining a set of MCU security properties:
    • Attestation (prove identity & firmware version)
    • Cryptography (symmetric, asymmetric, hash)
    • Secure storage
    • Secure firmware update
    • Boot ROM & chain-of-trust
  • PSA Certified levels 1/2/3: increasingly stringent evaluation.

Trusted Firmware-M (TF-M)

  • Open-source reference implementation of the PSA Secure-side runtime.
  • Runs entirely in Secure state; exposes PSA APIs to NS via NSC veneers.
  • Includes crypto (via Mbed TLS), secure storage, attestation, firmware update (MCUboot).
  • Ships as the default secure firmware for STM32U5/L5, Nordic nRF54, NXP LPC55, Renesas RA.
  • github.com/trustedfirmware/trusted-firmware-m
19

Typical Boot Flow

ROM Boot immutable, masked in silicon Secure Bootloader MCUboot (Secure image) TF-M Secure runtime PSA APIs; starts in S NS Bootloader optional; verifies NS image NS App + RTOS production firmware Verify SB signature Verify TF-M Configure SAU Init keys, HUK BXNS → NS Load NS app from flash Root of Trust Each stage verifies signature of the next, chained from ROM → keys sealed in the HUK (Hardware Unique Key).
20

Secure Debug — ADAC

  • DAUTHCTRL register in SCB has four enable bits — one per {S, NS} × {halting, non-invasive debug}.
  • Secure bootloader sets them at power-on based on authentication policy.
  • Authenticated Debug Access Control (ADAC): challenge-response over DAP using device-specific keys, verified by secure ROM.
  • Allowed levels:
    • All debug off → truly unbrickable.
    • NS debug enabled → developers can attach to app firmware.
    • S + NS debug enabled → full access (engineering / RMA only).

Attack surface

  • Glitch attack on SAU configure → try to force a region NS before keys are derived.
  • Side-channel on RNG / HUK on first boot.
  • Rollback: replaying old signed firmware with known bugs. Mitigation: anti-rollback counter in NV fuses.
Cortex-M35P adds fault-injection countermeasures at gate level specifically for these attacks.
21

TrustZone vs MPU vs Privilege

MechanismProtects againstDoes not protect against
MPUTask-level bugs: task A reading task B's buffer; stack overflow hitting kernel data.Kernel compromise; malicious privileged code; firmware updates.
Privilege (nPRIV bit)User code touching SCB/NVIC; preventing raw peripheral config.Ring 0 bugs; kernel-to-kernel compromise; any attack at same privilege.
TrustZoneAny NS compromise (including NS kernel + NS firmware update flaws). Keeps crypto keys and attestation identity uncompromised.Physical attacks on silicon; compromise inside the Secure side itself.
The three layers compose: TrustZone isolates "things that must never be compromised" (crypto keys, root-of-trust) from the NS application world. MPU + privilege inside the NS world keeps user tasks from trampling each other. Together they enable a defence-in-depth story for certifications.
22

Hardware Memory Partitioning

TrustZone is only one layer — the SoC bus must also enforce HNONSEC attributes.

  • Every AHB-5 transaction carries a HNONSEC bit (0 = Secure access, 1 = NS).
  • Slaves may either be TrustZone-aware (check HNONSEC and reject) or TrustZone-oblivious (behind a filter).
  • Vendor filter blocks (STM32 GTZC, NXP AHB-RF, Nordic SPU) policy each slave as S-only, NS-only, or either.
  • Crypto engine & RNG are usually S-only; user GPIO, UART, timers are NS; flash controller is S-only but the flash contents are split per attribution.

STM32L5 GTZC example

  • GTZC_TZSC_IDMMR — per-peripheral security policy.
  • GTZC_MPCBB — per-page SRAM security.
  • GTZC_TZIC — consolidated illegal-access fault controller.
  • Any NS access to a S-allocated peripheral → TZIC raises interrupt → TF-M logs and resets.
23

Common TrustZone Bugs

1. TOCTOU on NS pointer

Secure function validates a pointer, then dereferences it later. Meanwhile an NS thread changes the memory at that address. Always copy args to S-local buffer before use, or use cmse_check_address_range atomically with DMA source.

2. Leaking secrets via caller-saved regs

If the compiler doesn't zero R0-R3 before BXNS, intermediate crypto values can leak. cmse_nonsecure_entry handles this correctly — but hand-written assembly must do it explicitly.

3. NS gets access to an S peripheral

Vendor filter not programmed → NS can touch the crypto engine MMIO. Audit the GTZC/SPU config in the secure bootloader.

4. Stack overflow into S memory

NS task overflows its PSP_NS into an adjacent S SRAM region. Solution: enforce PSPLIM_NS + MPU_NS + ensure S SRAM is not contiguous with NS stacks.

5. Wrong SAU region order

SAU region ordering matters on overlap. Debug a region configuration by walking the SAU with an MPU-check helper during bring-up.

6. Missing DSB+ISB after SAU update

Instructions in flight may still use old attributes; same as MPU. Always DSB(); ISB(); after reconfig.

24

Interview Checklist

  • Draw the 2×2 {S,NS} × {Priv, Unpriv} matrix and list what's banked.
  • Explain the difference between SAU, IDAU, and MPU.
  • Describe exactly what the SG instruction does and why NSC regions are necessary.
  • Explain the integrity signature and what it prevents.
  • Walk through a secure boot → TF-M → NS application handoff.
  • Compare TrustZone-M vs TrustZone-A (latency, monitor layer, switching model).
  • Give an example where TrustZone is the right answer and one where an MPU alone is sufficient.
  • List three attacks that TrustZone does not prevent (physical, glitch, side-channel).
  • Explain PSA Certified — what does "Level 2" demonstrate?
  • Describe BLXNS and when Secure calls back into NS.
  • Name the vendor filter blocks that enforce HNONSEC per peripheral on STM32L5 / Nordic / NXP.
  • Explain why cmse_nonsecure_entry matters more than just a calling convention.
25

References

ArmArmv8-M Architecture Reference Manual (ARM DDI 0553) — chapter B4 (Security State)
ArmTrustZone technology for Armv8-M Architecture white paper (ARM 100690, v2.1)
ArmCortex-M23 / M33 Technical Reference Manuals
Joseph YiuDefinitive Guide to Arm Cortex-M23 & Cortex-M33 Processors (Newnes, 2021) — chapters 10–13
Arm PSAPlatform Security Architecture specifications (Attestation, Firmware Update, Secure Storage)
Trusted Firmware-Mtrustedfirmware.org/projects/tf-m and GitHub mirror
Arm CMSE — ACLE Extensions for Cortex-M Security (cmse_nonsecure_entry, cmse_check_address_range)
STMicroAN5347 STM32L5 TrustZone; AN5429 STM32U5 TF-M guide
NordicnRF5340 / nRF54L Product Specification, chapters on SPU and TrustZone
NXPLPC55Sxx TrustZone User Manual

Presentation built with Reveal.js 4.6 · Playfair Display + DM Sans + JetBrains Mono
Educational use.