fix(core): disable secret access after locking
What changed, and why it matters
This update fixes a security gap in how the Trezor hardware wallet protects its most sensitive storage area. Previously, after the device 'locked' its secret memory region, that region might still have remained accessible to running code. Now the code explicitly disables all access to the secret area as soon as it is locked, making it harder for an attacker who has already broken into the device to read protected keys or data.
Treat this as a security hardening fix and include it in the next firmware release. Review whether other lock/unlock paths (bootloader, firmware update, recovery) also call `secret_disable_access()` consistently. Consider whether a changelog entry is warranted despite the [no changelog] tag, because the change has security relevance.
Security signals we found
Missing access-restriction after sensitive state change
Secret/key storage access control hardening
Post-lock privilege/permission cleanup added
Evidence from the diff
In core/embed/sec/secret/stm32u5/secret.c, the secret_lock() function previously only wrote zero-filled lock data to the SECRET_LOCK_SLOT and returned the result. The patch adds a call to secret_disable_access() immediately after a successful write. This ensures that the secret region is no longer readable/writable/executable by firmware once locked, closing a window where the region could remain accessible after the lock flag was set.
Changed components
core/embed/sec/secret/stm32u5/secret.csecret_lock()STM32U5 secret storage driverInspect captured patch +8 / −1
diff --git a/core/embed/sec/secret/stm32u5/secret.c b/core/embed/sec/secret/stm32u5/secret.c
index bd4468d38..44e711e74 100644
--- a/core/embed/sec/secret/stm32u5/secret.c
+++ b/core/embed/sec/secret/stm32u5/secret.c
@@ -554,7 +554,14 @@ void secret_unlock_bootloader(void) {
secbool secret_lock(void) {
uint8_t lock_data[SECRET_LOCK_SLOT_LEN] = {0};
- return secret_write(lock_data, SECRET_LOCK_SLOT_OFFSET, sizeof(lock_data));
+ secbool result =
+ secret_write(lock_data, SECRET_LOCK_SLOT_OFFSET, sizeof(lock_data));
+
+ if (sectrue == result) {
+ secret_disable_access();
+ }
+
+ return result;
}
secbool secret_is_locked(void) {
Why this scored 71/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.