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 in
ARM1176JZ-S
Cortex-M23 / M33
State switching
Software-controlled via SMC (Secure Monitor Call); flush pipeline; context save
Hardware-controlled; automatic context save on cross-domain call
Secure monitor
Dedicated secure-monitor layer (EL3)
No monitor layer; S and NS call each other directly via SG + BXNS
IRQ handling
SMC into monitor
Direct — an IRQ targets S or NS based on NVIC.ITNS bit
Latency
Hundreds 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
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:
IDAU — Implementation-Defined Attribution Unit. Hard-wired by the SoC vendor; typically partitions the 4 GiB at power-of-two boundaries.
SAU — Security Attribution Unit. Programmable by the Secure kernel at runtime; up to 8 regions.
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.
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 SG — Secure 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
Instruction
Meaning
Use case
BXNS Rm
Branch 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 Rm
Branch-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
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
Register
Banked?
Notes
MSP / PSP
✓ per state
MSP_S · PSP_S · MSP_NS · PSP_NS
MSPLIM / PSPLIM
✓ per state
HW stack-overflow detection banks per world
CONTROL
✓
Separate nPRIV & SPSEL for S and NS threads; FPCA shared
PRIMASK / BASEPRI / FAULTMASK
✓
NS cannot set its mask to block S IRQs
VTOR
✓
VTOR_S, VTOR_NS
MPU
✓
MPU_S, MPU_NS — each with own region config
NVIC priority / enable
✓
NS can only write NS IRQ masks; S can touch both
SYSCTL / AIRCR
banked fields
Some 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
NS code running; S-targeted IRQ arrives at higher priority.
CPU stacks 8 "basic" words on NS stack.
CPU then stacks an additional context (R4-R11, "state context") plus a 4-word integrity signature, again on the NS stack.
Switches to Secure handler; all caller-saved NS regs are cleared.
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:
User code touching SCB/NVIC; preventing raw peripheral config.
Ring 0 bugs; kernel-to-kernel compromise; any attack at same privilege.
TrustZone
Any 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.
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
Arm — Armv8-M Architecture Reference Manual (ARM DDI 0553) — chapter B4 (Security State) Arm — TrustZone technology for Armv8-M Architecture white paper (ARM 100690, v2.1) Arm — Cortex-M23 / M33 Technical Reference Manuals Joseph Yiu — Definitive Guide to Arm Cortex-M23 & Cortex-M33 Processors (Newnes, 2021) — chapters 10–13 Arm PSA — Platform Security Architecture specifications (Attestation, Firmware Update, Secure Storage) Trusted Firmware-M — trustedfirmware.org/projects/tf-m and GitHub mirror Arm CMSE — ACLE Extensions for Cortex-M Security (cmse_nonsecure_entry, cmse_check_address_range) STMicro — AN5347 STM32L5 TrustZone; AN5429 STM32U5 TF-M guide Nordic — nRF5340 / nRF54L Product Specification, chapters on SPU and TrustZone NXP — LPC55Sxx TrustZone User Manual
Presentation built with Reveal.js 4.6 · Playfair Display + DM Sans + JetBrains Mono
Educational use.