fix(core): explicitly disable external tamper trigger
What changed, and why it matters
This commit adds a new function that explicitly turns off an external physical tamper-detection input on Trezor's secure microcontroller after initialization. Previously, the tamper input may have been left enabled by default after tamper_init(), which could allow a physical attacker to trigger a tamper event (and potentially wipe secrets or reset the device) using an external signal. The fix ensures the external trigger is disabled unless later explicitly enabled.
Treat as a security hardening fix. Verify that tamper_external_enable() is only invoked in trusted contexts (e.g., factory testing or intentional user configuration) and that no other code paths leave TAMP2E set unexpectedly. Review whether additional tamper inputs (TAMP1, TAMP3, etc.) require similar explicit disablement.
Security signals we found
New tamper_external_disable() function clears TAMP_CR1_TAMP2E
Called immediately after tamper_init() in secure monitor boot path
Targets external tamper input 2 specifically
No changelog entry suggests low-profile hardening fix
Change is defensive: disables a physical security feature rather than enabling one
Evidence from the diff
The patch introduces tamper_external_disable() in the STM32U5 tamper driver, which clears the TAMP_CR1_TAMP2E bit for TAMPER_INPUT_2, disabling the external tamper input. It also declares the function in the tamper subsystem header and calls it immediately after tamper_init() in the secmon (security monitor) initialization. This prevents the external tamper line from remaining active by default after tamper initialization, reducing the attack surface against physical glitching/tamper-trigger attacks.
Changed components
core/embed/sys/tamper/stm32u5/tamper.ccore/embed/sys/tamper/inc/sys/tamper.hcore/embed/projects/secmon/main.cTrezor Model T / Safe 3 secure monitor (secmon)STM32U5 TAMP peripheral external tamper input 2Inspect captured patch +10 / −0
diff --git a/core/embed/projects/secmon/main.c b/core/embed/projects/secmon/main.c
index 0e8c0b1dc..59bf00b08 100644
--- a/core/embed/projects/secmon/main.c
+++ b/core/embed/projects/secmon/main.c
@@ -64,6 +64,7 @@ static void drivers_init(void) {
#ifdef USE_TAMPER
tamper_init();
+ tamper_external_disable();
#endif
random_delays_init();
diff --git a/core/embed/sys/tamper/inc/sys/tamper.h b/core/embed/sys/tamper/inc/sys/tamper.h
index 013f62eaa..79d20a04a 100644
--- a/core/embed/sys/tamper/inc/sys/tamper.h
+++ b/core/embed/sys/tamper/inc/sys/tamper.h
@@ -35,4 +35,7 @@ uint8_t tamper_external_read(void);
// Enable external tamper inputs
void tamper_external_enable(void);
+// Disable external tamper inputs
+void tamper_external_disable(void);
+
#endif // SECURE_MODE
diff --git a/core/embed/sys/tamper/stm32u5/tamper.c b/core/embed/sys/tamper/stm32u5/tamper.c
index 1e4bbefbd..2dbc4354e 100644
--- a/core/embed/sys/tamper/stm32u5/tamper.c
+++ b/core/embed/sys/tamper/stm32u5/tamper.c
@@ -199,6 +199,12 @@ void tamper_external_enable(void) {
#endif
}
+void tamper_external_disable(void) {
+#ifdef TAMPER_INPUT_2
+ TAMP->CR1 &= ~TAMP_CR1_TAMP2E;
+#endif
+}
+
void tamper_build_pminfo(systask_postmortem_t* pminfo, uint32_t tamper_sr) {
const char* title = "TAMPER";
Why this scored 46/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.