What changed, and why it matters
This is a routine code cleanup that simplifies how the Trezor firmware handles flash memory writes. It removes an older 16-byte 'quadword' write path and makes a newer 128-byte 'burst' write path the standard for all affected STM32U5 devices. There is no indication this fixes a security bug or introduces a vulnerability.
No security action required. Treat as normal refactoring; standard regression testing for flash/storage operations on STM32U5-based devices is sufficient.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors the flash-area abstraction layer. It deletes the flash_area_write_quadword() and flash_write_quadword() APIs, removes per-board USE_FLASH_BURST defines, and enables USE_FLASH_BURST globally for STM32U5 in stm32u5_common.py with a fixed 128-byte burst size. The low-level flash_write_quadword() implementation in the STM32U5 driver is made static/internal, while flash_area_write_burst() remains. The C unit-test mock for quadword writes is also removed. The change is purely structural/API simplification.
Changed components
core/embed/sys/flash/stm32u5/flash.cstorage/flash_area.cstorage/flash_area.hstorage/flash_ll.hstorage/tests/c/flash.ccore/site_scons/models/stm32u5_common.pycore/site_scons/models/D002/discovery2.pycore/site_scons/models/T3B1/trezor_t3b1_revB.pycore/site_scons/models/T3T1/trezor_t3t1_revE.pycore/site_scons/models/T3W1/trezor_t3w1_revA.pycore/site_scons/models/T3W1/trezor_t3w1_revB.pycore/site_scons/models/T3W1/trezor_t3w1_revC.pyInspect captured patch +10 / −39
diff --git a/core/embed/sys/flash/stm32u5/flash.c b/core/embed/sys/flash/stm32u5/flash.c
index 9ee27547..8549f4af 100644
--- a/core/embed/sys/flash/stm32u5/flash.c
+++ b/core/embed/sys/flash/stm32u5/flash.c
@@ -25,6 +25,9 @@
#ifdef KERNEL_MODE
+#define FLASH_QUADWORD_WORDS (4)
+#define FLASH_QUADWORD_SIZE (FLASH_QUADWORD_WORDS * sizeof(uint32_t))
+
#ifdef STM32U585xx
#define FLASH_BANK_PAGES 128
#define FLASH_SECTOR_COUNT (FLASH_BANK_PAGES * 2)
@@ -168,8 +171,8 @@ secbool flash_sector_erase(uint16_t sector) {
return sectrue;
}
-secbool flash_write_quadword(uint16_t sector, uint32_t offset,
- const uint32_t *data) {
+static secbool flash_write_quadword(uint16_t sector, uint32_t offset,
+ const uint32_t *data) {
uint32_t address =
(uint32_t)flash_get_address(sector, offset, FLASH_QUADWORD_SIZE);
if (address == 0) {
diff --git a/core/site_scons/models/D002/discovery2.py b/core/site_scons/models/D002/discovery2.py
index 34f16ef8..fa38a2d0 100644
--- a/core/site_scons/models/D002/discovery2.py
+++ b/core/site_scons/models/D002/discovery2.py
@@ -118,7 +118,6 @@ def configure(
"USE_HASH_PROCESSOR=1",
"USE_STORAGE_HWKEY=1",
"USE_TAMPER=1",
- "USE_FLASH_BURST=1",
"USE_OEM_KEYS_CHECK=1",
]
diff --git a/core/site_scons/models/T3B1/trezor_t3b1_revB.py b/core/site_scons/models/T3B1/trezor_t3b1_revB.py
index 42d0fb95..349d3bf6 100644
--- a/core/site_scons/models/T3B1/trezor_t3b1_revB.py
+++ b/core/site_scons/models/T3B1/trezor_t3b1_revB.py
@@ -109,7 +109,6 @@ def configure(
("USE_HASH_PROCESSOR", "1"),
("USE_STORAGE_HWKEY", "1"),
("USE_TAMPER", "1"),
- ("USE_FLASH_BURST", "1"),
("USE_OEM_KEYS_CHECK", "1"),
("USE_PVD", "1"),
]
diff --git a/core/site_scons/models/T3T1/trezor_t3t1_revE.py b/core/site_scons/models/T3T1/trezor_t3t1_revE.py
index 4293168e..0817bef0 100644
--- a/core/site_scons/models/T3T1/trezor_t3t1_revE.py
+++ b/core/site_scons/models/T3T1/trezor_t3t1_revE.py
@@ -142,7 +142,6 @@ def configure(
("USE_HASH_PROCESSOR", "1"),
("USE_STORAGE_HWKEY", "1"),
("USE_TAMPER", "1"),
- ("USE_FLASH_BURST", "1"),
("USE_OEM_KEYS_CHECK", "1"),
("USE_PVD", "1"),
]
diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revA.py b/core/site_scons/models/T3W1/trezor_t3w1_revA.py
index 38866ae1..117cbed7 100644
--- a/core/site_scons/models/T3W1/trezor_t3w1_revA.py
+++ b/core/site_scons/models/T3W1/trezor_t3w1_revA.py
@@ -270,7 +270,6 @@ def configure(
("USE_HASH_PROCESSOR", "1"),
("USE_STORAGE_HWKEY", "1"),
("USE_TAMPER", "1"),
- ("USE_FLASH_BURST", "1"),
("USE_OEM_KEYS_CHECK", "1"),
]
diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revB.py b/core/site_scons/models/T3W1/trezor_t3w1_revB.py
index 79d59809..fcd4e756 100644
--- a/core/site_scons/models/T3W1/trezor_t3w1_revB.py
+++ b/core/site_scons/models/T3W1/trezor_t3w1_revB.py
@@ -284,7 +284,6 @@ def configure(
("USE_HASH_PROCESSOR", "1"),
("USE_STORAGE_HWKEY", "1"),
("USE_TAMPER", "1"),
- ("USE_FLASH_BURST", "1"),
("USE_OEM_KEYS_CHECK", "1"),
]
diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revC.py b/core/site_scons/models/T3W1/trezor_t3w1_revC.py
index c4257b9f..372ac661 100644
--- a/core/site_scons/models/T3W1/trezor_t3w1_revC.py
+++ b/core/site_scons/models/T3W1/trezor_t3w1_revC.py
@@ -282,7 +282,6 @@ def configure(
("USE_HASH_PROCESSOR", "1"),
("USE_STORAGE_HWKEY", "1"),
("USE_TAMPER", "1"),
- ("USE_FLASH_BURST", "1"),
("USE_OEM_KEYS_CHECK", "1"),
]
diff --git a/core/site_scons/models/stm32u5_common.py b/core/site_scons/models/stm32u5_common.py
index be5fd103..273cb022 100644
--- a/core/site_scons/models/stm32u5_common.py
+++ b/core/site_scons/models/stm32u5_common.py
@@ -7,6 +7,9 @@ def stm32u5_common_files(env, features_wanted, defines, sources, paths):
defines += [
("STM32_HAL_H", "<stm32u5xx.h>"),
("FLASH_BLOCK_WORDS", "4"),
+ ("USE_FLASH_BURST", "1"),
+ ("FLASH_BURST_WORDS", "32"),
+ ("FLASH_BURST_SIZE", "128"),
("USE_TRUSTZONE", "1"),
]
diff --git a/storage/flash_area.c b/storage/flash_area.c
index 037319e1..820601bf 100644
--- a/storage/flash_area.c
+++ b/storage/flash_area.c
@@ -108,19 +108,7 @@ secbool flash_area_write_word(const flash_area_t *area, uint32_t offset,
return flash_write_word(sector, sector_offset, data);
}
-#else // not defined FLASH_BIT_ACCESS
-
-secbool flash_area_write_quadword(const flash_area_t *area, uint32_t offset,
- const uint32_t *data) {
- uint16_t sector;
- uint32_t sector_offset;
- if (get_sector_and_offset(area, offset, §or, §or_offset) != sectrue) {
- return secfalse;
- }
- return flash_write_quadword(sector, sector_offset, data);
-}
-
-#endif // not defined FLASH_BIT_ACCESS
+#endif // FLASH_BIT_ACCESS
#ifdef USE_FLASH_BURST
secbool flash_area_write_burst(const flash_area_t *area, uint32_t offset,
diff --git a/storage/flash_area.h b/storage/flash_area.h
index a0b2ee1f..b1c7ac9c 100644
--- a/storage/flash_area.h
+++ b/storage/flash_area.h
@@ -67,8 +67,6 @@ secbool __wur flash_area_write_byte(const flash_area_t *area, uint32_t offset,
secbool __wur flash_area_write_word(const flash_area_t *area, uint32_t offset,
uint32_t data);
#endif
-secbool __wur flash_area_write_quadword(const flash_area_t *area,
- uint32_t offset, const uint32_t *data);
secbool __wur flash_area_write_burst(const flash_area_t *area, uint32_t offset,
const uint32_t *data);
diff --git a/storage/flash_ll.h b/storage/flash_ll.h
index ddb167d8..b4d1cbe1 100644
--- a/storage/flash_ll.h
+++ b/storage/flash_ll.h
@@ -30,12 +30,6 @@
// 1. Non-uniform sector number on STM32F4
// 2. Uniform page number on STM32U5
-#define FLASH_QUADWORD_WORDS (4)
-#define FLASH_QUADWORD_SIZE (FLASH_QUADWORD_WORDS * sizeof(uint32_t))
-
-#define FLASH_BURST_WORDS (8 * FLASH_QUADWORD_WORDS)
-#define FLASH_BURST_SIZE (FLASH_BURST_WORDS * sizeof(uint32_t))
-
#define FLASH_BLOCK_SIZE (sizeof(uint32_t) * FLASH_BLOCK_WORDS)
typedef uint32_t flash_block_t[FLASH_BLOCK_WORDS];
@@ -50,7 +44,7 @@ typedef uint32_t flash_block_t[FLASH_BLOCK_WORDS];
#error Unsupported number of FLASH_BLOCK_WORDS.
#endif
-// Returns the size of the a continuous area of sectors
+// Returns the size of a continuous area of sectors
// Returns 0 if any of the sectors is out of range
uint32_t flash_sector_size(uint16_t first_sector, uint16_t sector_count);
@@ -80,10 +74,6 @@ secbool __wur flash_write_word(uint16_t sector, uint32_t offset, uint32_t data);
#endif
-// Writes a 16-byte block to specified 'offset' inside a flash 'sector'
-secbool __wur flash_write_quadword(uint16_t sector, uint32_t offset,
- const uint32_t *data);
-
// Writes a 128-byte burst to specified 'offset' inside a flash 'sector'
secbool __wur flash_write_burst(uint16_t sector, uint32_t offset,
const uint32_t *data);
diff --git a/storage/tests/c/flash.c b/storage/tests/c/flash.c
index 2098838d..900ded45 100644
--- a/storage/tests/c/flash.c
+++ b/storage/tests/c/flash.c
@@ -144,11 +144,6 @@ secbool flash_write_word(uint16_t sector, uint32_t offset, uint32_t data) {
return flash_write(sector, offset, (uint8_t *)&data, sizeof(uint32_t));
}
-secbool flash_write_quadword(uint16_t sector, uint32_t offset,
- const uint32_t *data) {
- return flash_write(sector, offset, (uint8_t *)data, 4 * sizeof(uint32_t));
-}
-
secbool flash_write_burst(uint16_t sector, uint32_t offset,
const uint32_t *data) {
return flash_write(sector, offset, (uint8_t *)data, 32 * sizeof(uint32_t));
Why this scored 15/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.