What changed, and why it matters
This commit fixes the TrustZone security configuration on the STM32U5 chip used in Trezor hardware wallets. TrustZone splits the processor into a secure world (for secrets like the seed and PIN) and a non-secure world (for the main user interface). The patch makes three changes: it temporarily disables the Security Attribution Unit (SAU) while reprogramming it, adds memory barriers so the new rules take effect correctly, and marks one DMA channel's interrupt as secure. Without these fixes, secure memory regions could potentially be reachable from non-secure code, or security settings might not be applied reliably during boot.
Treat this as a security hardening fix and include it in the next firmware release. Review the full TrustZone boot sequence for other missing DSB/ISB barriers or NVIC target-state settings. Consider whether a changelog entry is warranted despite the [no changelog] tag, because the change is security-relevant.
Security signals we found
TrustZone-M SAU reconfiguration without disabling the unit first can leave stale/invalid region attributes active during updates
Missing DSB/ISB barriers after SAU control changes can cause speculative/instruction fetches to use old security attribution
DMA channel interrupt left in non-secure state could allow non-secure code to intercept or influence a secure DMA channel
Commit title explicitly calls this a 'fix trustzone configuration' security-relevant fix
Evidence from the diff
The diff modifies core/embed/sec/trustzone/stm32u5/tz_init.c. It adds SAU->CTRL = 0 at the start of tz_configure_sau() to disable the SAU before reprogramming region registers, followed by __DSB() and __ISB() barriers. After re-enabling the SAU, it adds another __DSB()/__ISB() pair. In tz_init(), it calls NVIC_ClearTargetState(GPDMA1_Channel12_IRQn) so the GPDMA1 Channel 12 interrupt targets the secure state. These are defensive hardening steps for the ARM TrustZone-M initialization sequence on STM32U5.
Changed components
Trezor Core firmwareSTM32U5 TrustZone secure monitor / secure world initializationcore/embed/sec/trustzone/stm32u5/tz_init.cGPDMA1 Channel 12 interrupt routingSAU (Security Attribution Unit) region configurationInspect captured patch +10 / −0
diff --git a/core/embed/sec/trustzone/stm32u5/tz_init.c b/core/embed/sec/trustzone/stm32u5/tz_init.c
index 9511b109..6b3057ae 100644
--- a/core/embed/sec/trustzone/stm32u5/tz_init.c
+++ b/core/embed/sec/trustzone/stm32u5/tz_init.c
@@ -44,11 +44,18 @@
#ifndef SECMON
static void tz_configure_sau(void) {
+ SAU->CTRL = 0;
+ __DSB();
+ __ISB();
+
SET_REGION(0, 0x0BF90000, 0x00019000, 0); // OTP etc
SAU->CTRL =
((SAU_INIT_CTRL_ENABLE << SAU_CTRL_ENABLE_Pos) & SAU_CTRL_ENABLE_Msk) |
((SAU_INIT_CTRL_ALLNS << SAU_CTRL_ALLNS_Pos) & SAU_CTRL_ALLNS_Msk);
+
+ __DSB();
+ __ISB();
}
#endif
@@ -320,6 +327,9 @@ void tz_init(void) {
GPDMA1->SECCFGR |= (1 << 12);
GPDMA1->PRIVCFGR |= 0xFFFF;
+ // Make GPDMA1 Channel 12 interrupt secure
+ NVIC_ClearTargetState(GPDMA1_Channel12_IRQn);
+
// Enable all GPIOS and make them non-secure & privileged
__HAL_RCC_GPIOA_CLK_ENABLE();
Why this scored 59/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.