fix(core): get rid of confidential global vars
What changed, and why it matters
This commit removes a special firmware memory section called ".confidential" that was meant to keep sensitive data (like cryptographic keys and seed-derived values) separate from ordinary memory. Previously, variables marked with a CONFIDENTIAL attribute were placed in this dedicated RAM region and copied from flash at startup. The patch deletes that whole mechanism across all Trezor models and instead marks sensitive local variables with a new LOCAL_CONFIDENTIAL macro. On the legacy build this still maps to the old behavior, but on the modern STM32 builds it effectively becomes a no-op, meaning those sensitive buffers now live in normal RAM/data sections. The change is presented as a cleanup, but it reduces a defense-in-depth isolation feature and could make it easier for a successful attacker to locate or extract secret material in memory.
Treat this as a defense-in-depth regression rather than an active vulnerability. Review whether the .confidential section was relied upon by downstream hardening (e.g., TrustZone MPU configuration, firmware-update integrity checks, or side-channel countermeasures). If so, reintroduce equivalent isolation, for example by mapping LOCAL_CONFIDENTIAL to a protected MPU region or by restoring the section for devices that support it. Verify that removing the section does not change the runtime layout in a way that breaks stack/heap boundaries or exposes secrets through uninitialized RAM. Add a changelog/security note explaining the rationale and compensating controls.
Security signals we found
Removal of dedicated .confidential RAM/flash section used for secret buffers
Deletion of startup copy routine that initialized confidential RAM from flash
Crypto and storage sensitive buffers moved from section-isolated globals to normal data/stack semantics
Build-system change makes CONFIDENTIAL a no-op on STM32F4/STM32U5/Unix builds
Legacy build retains CONFIDENTIAL/LOCAL_CONFIDENTIAL mapping, creating a behavior split
Bootloader global variables stripped of CONFIDENTIAL attribute
No changelog entry despite security-relevant memory-layout change
Evidence from the diff
The patch eliminates the .confidential linker section and the CONFIDENTIAL section attribute from the Trezor core firmware. Consequences: (1) SConscript objcopy invocations no longer include -j .confidential, so the section is dropped from produced binaries. (2) All STM32 linker scripts remove .confidential definitions and the associated confidential_section* symbols. (3) init_linker_sections() no longer copies .confidential from flash load address to RAM. (4) The CONFIDENTIAL macro is removed from stm32f4_common.py, stm32u5_common.py, and unix_common.py, and replaced by LOCAL_CONFIDENTIAL in options.h. (5) Crypto code (bip32.c, bip39.c, cardano.c, ecdsa.c, hmac.c) changes static CONFIDENTIAL buffers to LOCAL_CONFIDENTIAL. (6) Legacy Makefile still defines both CONFIDENTIAL and LOCAL_CONFIDENTIAL, preserving old behavior for legacy devices. (7) Two global variables in bootloader/main.c lose their CONFIDENTIAL qualifier. The commit is framed as removing unused/confusing infrastructure, but it materially weakens memory layout isolation for modern devices.
Changed components
core/SConscript.* build scriptscore/embed/sys/linker/*.ld linker scripts for STM32F4, STM32U58, STM32U5Gcore/embed/sys/linker/linker_utils.ccore/site_scons/models/stm32f4_common.py, stm32u5_common.py, unix_common.pycrypto/bip32.c, crypto/bip39.c, crypto/cardano.c, crypto/ecdsa.c, crypto/hmac.ccrypto/options.hlegacy/Makefile.includestorage/norcow.c, storage/storage.ccore/embed/projects/bootloader/main.cInspect captured patch +59 / −182
diff --git a/core/SConscript.boardloader b/core/SConscript.boardloader
index ba56bc28..70d59573 100644
--- a/core/SConscript.boardloader
+++ b/core/SConscript.boardloader
@@ -216,7 +216,7 @@ program_bin = env.Command(
target='boardloader.bin',
source=program_elf,
action=[
- '$OBJCOPY -O binary -j .vector_table -j .text -j .data -j .rodata -j .capabilities -j .confidential $SOURCE $TARGET',
+ '$OBJCOPY -O binary -j .vector_table -j .text -j .data -j .rodata -j .capabilities $SOURCE $TARGET',
'$CP $TARGET ' + BINARY_NAME,
],
)
diff --git a/core/SConscript.bootloader b/core/SConscript.bootloader
index 9f04d211..aeb6c193 100644
--- a/core/SConscript.bootloader
+++ b/core/SConscript.bootloader
@@ -310,7 +310,7 @@ program_bin = env.Command(
target='bootloader.bin',
source=program_elf,
action=[
- '$OBJCOPY -O binary -j .header -j .flash -j .data -j .confidential $SOURCE $TARGET',
+ '$OBJCOPY -O binary -j .header -j .flash -j .data $SOURCE $TARGET',
'$HEADERTOOL $TARGET ' + ('-D' if not PRODUCTION else ''),
'$CP $TARGET ' + BINARY_NAME,
], )
diff --git a/core/SConscript.bootloader_ci b/core/SConscript.bootloader_ci
index 32d39dbd..9beb11c5 100644
--- a/core/SConscript.bootloader_ci
+++ b/core/SConscript.bootloader_ci
@@ -241,7 +241,7 @@ program_bin = env.Command(
target='bootloader.bin',
source=program_elf,
action=[
- '$OBJCOPY -O binary -j .header -j .flash -j .data -j .confidential $SOURCE $TARGET',
+ '$OBJCOPY -O binary -j .header -j .flash -j .data $SOURCE $TARGET',
'$HEADERTOOL $TARGET ' + ('-D' if ARGUMENTS.get('PRODUCTION', '0') == '0' else ''),
'$CP $TARGET ' + BINARY_NAME,
], )
diff --git a/core/SConscript.firmware b/core/SConscript.firmware
index 9aa3246f..f224a70c 100644
--- a/core/SConscript.firmware
+++ b/core/SConscript.firmware
@@ -994,7 +994,7 @@ BINARY_NAME += ".bin"
if 'STM32F427xx' in CPPDEFINES_HAL or 'STM32F429xx' in CPPDEFINES_HAL:
action_bin=[
- '$OBJCOPY -O binary -j .vendorheader -j .header -j .flash -j .data -j .confidential --pad-to 0x08100000 $SOURCE ${TARGET}.p1',
+ '$OBJCOPY -O binary -j .vendorheader -j .header -j .flash -j .data --pad-to 0x08100000 $SOURCE ${TARGET}.p1',
'$OBJCOPY -O binary -j .flash2 $SOURCE ${TARGET}.p2',
'$CAT ${TARGET}.p1 ${TARGET}.p2 > $TARGET',
'$HEADERTOOL -h $TARGET ' + ('-D' if not PRODUCTION else ''),
@@ -1003,7 +1003,7 @@ if 'STM32F427xx' in CPPDEFINES_HAL or 'STM32F429xx' in CPPDEFINES_HAL:
]
elif 'STM32U5G9xx' in CPPDEFINES_HAL or 'STM32U585xx' in CPPDEFINES_HAL:
action_bin=[
- '$OBJCOPY -O binary -j .vendorheader -j .header -j .flash -j .data -j .confidential $SOURCE ${TARGET}',
+ '$OBJCOPY -O binary -j .vendorheader -j .header -j .flash -j .data $SOURCE ${TARGET}',
'$HEADERTOOL -h $TARGET ' + ('-D' if not PRODUCTION else ''),
'$CP $TARGET ' + BINARY_NAME,
]
diff --git a/core/SConscript.kernel b/core/SConscript.kernel
index cec1b269..0622ec6d 100644
--- a/core/SConscript.kernel
+++ b/core/SConscript.kernel
@@ -461,7 +461,7 @@ BINARY_NAME += "-dirty" if tools.get_git_modified() else ""
BINARY_NAME += ".bin"
action_bin=[
- '$OBJCOPY -O binary -j .flash -j .data -j .confidential $SOURCE ${TARGET}',
+ '$OBJCOPY -O binary -j .flash -j .data $SOURCE ${TARGET}',
'$CP $TARGET ' + BINARY_NAME,
]
diff --git a/core/SConscript.prodtest b/core/SConscript.prodtest
index fdf7b868..a96979e3 100644
--- a/core/SConscript.prodtest
+++ b/core/SConscript.prodtest
@@ -394,7 +394,7 @@ if secmon_prodtest:
target='secmon_prodtest.bin',
source=program_elf,
action=[
- '$OBJCOPY -O binary -j .secmon_header -j .flash -j .data -j .confidential $SOURCE $TARGET',
+ '$OBJCOPY -O binary -j .secmon_header -j .flash -j .data $SOURCE $TARGET',
'$HEADERTOOL $TARGET ' + ('-D' if ARGUMENTS.get('PRODUCTION', '0') == '0' else ''),
], )
@@ -420,7 +420,7 @@ else:
target='prodtest.bin',
source=program_elf,
action=[
- '$OBJCOPY -O binary -j .vendorheader -j .header -j .flash -j .data -j .confidential $SOURCE $TARGET',
+ '$OBJCOPY -O binary -j .vendorheader -j .header -j .flash -j .data $SOURCE $TARGET',
'$HEADERTOOL $TARGET ' + ('-D' if ARGUMENTS.get('PRODUCTION', '0') == '0' else ''),
'$CP $TARGET ' + BINARY_NAME,
], )
diff --git a/core/SConscript.secmon b/core/SConscript.secmon
index 45fa7aa3..244460e5 100644
--- a/core/SConscript.secmon
+++ b/core/SConscript.secmon
@@ -415,12 +415,12 @@ BINARY_NAME += ".bin"
if TREZOR_MODEL in ('T3B1', 'T3T1'):
action_bin=[
- '$OBJCOPY -O binary -j .secmon_header -j .flash -j .data -j .confidential -j .gnu.sgstubs $SOURCE ${TARGET}',
+ '$OBJCOPY -O binary -j .secmon_header -j .flash -j .data -j .gnu.sgstubs $SOURCE ${TARGET}',
'$CP $TARGET ' + BINARY_NAME,
]
else:
action_bin=[
- '$OBJCOPY -O binary -j .secmon_header -j .flash -j .data -j .confidential -j .gnu.sgstubs $SOURCE ${TARGET}',
+ '$OBJCOPY -O binary -j .secmon_header -j .flash -j .data -j .gnu.sgstubs $SOURCE ${TARGET}',
'$HEADERTOOL -h $TARGET ' + ('-D' if not PRODUCTION else ''),
'$CP $TARGET ' + BINARY_NAME,
]
diff --git a/core/embed/projects/bootloader/main.c b/core/embed/projects/bootloader/main.c
index d1bd58d3..e9d706ec 100644
--- a/core/embed/projects/bootloader/main.c
+++ b/core/embed/projects/bootloader/main.c
@@ -101,8 +101,8 @@
void failed_jump_to_firmware(void);
-CONFIDENTIAL volatile secbool dont_optimize_out_true = sectrue;
-CONFIDENTIAL void (*volatile firmware_jump_fn)(void) = failed_jump_to_firmware;
+volatile secbool dont_optimize_out_true = sectrue;
+void (*volatile firmware_jump_fn)(void) = failed_jump_to_firmware;
static secbool is_manufacturing_mode(vendor_header *vhdr) {
unit_properties_init();
diff --git a/core/embed/sys/linker/linker_utils.c b/core/embed/sys/linker/linker_utils.c
index bd377008..2a098686 100644
--- a/core/embed/sys/linker/linker_utils.c
+++ b/core/embed/sys/linker/linker_utils.c
@@ -27,9 +27,6 @@ void init_linker_sections(void) {
extern uint32_t _data_section_start;
extern uint32_t _data_section_end;
extern uint32_t _data_section_loadaddr;
- extern uint32_t _confidential_section_start;
- extern uint32_t _confidential_section_end;
- extern uint32_t _confidential_section_loadaddr;
// Pointer are intentionally volatile to prevent optimization
// (otherwise the compiler may optimize loops to memset/memcpy)
@@ -46,12 +43,6 @@ void init_linker_sections(void) {
while (dst < &_data_section_end) {
*dst++ = *src++;
}
-
- dst = &_confidential_section_start;
- src = &_confidential_section_loadaddr;
- while (dst < &_confidential_section_end) {
- *dst++ = *src++;
- }
}
static void memregion_remove_block(memregion_t* region, int idx) {
diff --git a/core/embed/sys/linker/stm32f4/boardloader.ld b/core/embed/sys/linker/stm32f4/boardloader.ld
index 83a7eee8..eb0ef692 100644
--- a/core/embed/sys/linker/stm32f4/boardloader.ld
+++ b/core/embed/sys/linker/stm32f4/boardloader.ld
@@ -19,10 +19,6 @@ _data_section_end = ADDR(.data) + SIZEOF(.data);
_bss_section_start = ADDR(.bss);
_bss_section_end = ADDR(.bss) + SIZEOF(.bss);
-_confidential_section_loadaddr = 0;
-_confidential_section_start = 0;
-_confidential_section_end = 0;
-
_bootargs_ram_start = BOOTARGS_START;
_bootargs_ram_end = BOOTARGS_START + BOOTARGS_SIZE;
diff --git a/core/embed/sys/linker/stm32f4/bootloader.ld b/core/embed/sys/linker/stm32f4/bootloader.ld
index 10a4d370..e546f818 100644
--- a/core/embed/sys/linker/stm32f4/bootloader.ld
+++ b/core/embed/sys/linker/stm32f4/bootloader.ld
@@ -19,10 +19,6 @@ _data_section_end = ADDR(.data) + SIZEOF(.data);
_bss_section_start = ADDR(.bss);
_bss_section_end = ADDR(.bss) + SIZEOF(.bss);
-_confidential_section_loadaddr = 0;
-_confidential_section_start = 0;
-_confidential_section_end = 0;
-
_bootargs_ram_start = BOOTARGS_START;
_bootargs_ram_end = BOOTARGS_START + BOOTARGS_SIZE;
diff --git a/core/embed/sys/linker/stm32f4/firmware.ld b/core/embed/sys/linker/stm32f4/firmware.ld
index 3b5cc393..3e771101 100644
--- a/core/embed/sys/linker/stm32f4/firmware.ld
+++ b/core/embed/sys/linker/stm32f4/firmware.ld
@@ -18,10 +18,6 @@ _data_section_end = ADDR(.data) + SIZEOF(.data);
_bss_section_start = ADDR(.bss);
_bss_section_end = ADDR(.bss) + SIZEOF(.bss);
-_confidential_section_loadaddr = 0;
-_confidential_section_start = 0;
-_confidential_section_end = 0;
-
_codelen = LENGTH(FLASH) - SIZEOF(.vendorheader) - SIZEOF(.header) + SIZEOF(.flash2);
_heap_start = ADDR(.heap);
_heap_end = ADDR(.heap) + SIZEOF(.heap);
diff --git a/core/embed/sys/linker/stm32f4/kernel.ld b/core/embed/sys/linker/stm32f4/kernel.ld
index 53dbfe02..10c3878d 100644
--- a/core/embed/sys/linker/stm32f4/kernel.ld
+++ b/core/embed/sys/linker/stm32f4/kernel.ld
@@ -19,10 +19,6 @@ _data_section_end = ADDR(.data) + SIZEOF(.data);
_bss_section_start = ADDR(.bss);
_bss_section_end = ADDR(.bss) + SIZEOF(.bss);
-_confidential_section_loadaddr = 0;
-_confidential_section_start = 0;
-_confidential_section_end = 0;
-
_bootargs_ram_start = BOOTARGS_START;
_bootargs_ram_end = BOOTARGS_START + BOOTARGS_SIZE;
diff --git a/core/embed/sys/linker/stm32f4/prodtest.ld b/core/embed/sys/linker/stm32f4/prodtest.ld
index d5058290..b07f1375 100644
--- a/core/embed/sys/linker/stm32f4/prodtest.ld
+++ b/core/embed/sys/linker/stm32f4/prodtest.ld
@@ -19,10 +19,6 @@ _data_section_end = ADDR(.data) + SIZEOF(.data);
_bss_section_start = ADDR(.bss);
_bss_section_end = ADDR(.bss) + SIZEOF(.bss);
-_confidential_section_loadaddr = 0;
-_confidential_section_start = 0;
-_confidential_section_end = 0;
-
_bootargs_ram_start = BOOTARGS_START;
_bootargs_ram_end = BOOTARGS_START + BOOTARGS_SIZE;
diff --git a/core/embed/sys/linker/stm32u58/boardloader.ld b/core/embed/sys/linker/stm32u58/boardloader.ld
index fae5b12e..f8acfe71 100644
--- a/core/embed/sys/linker/stm32u58/boardloader.ld
+++ b/core/embed/sys/linker/stm32u58/boardloader.ld
@@ -21,10 +21,6 @@ _data_section_end = ADDR(.data) + SIZEOF(.data);
_bss_section_start = ADDR(.bss);
_bss_section_end = ADDR(.bss) + SIZEOF(.bss);
-_confidential_section_loadaddr = LOADADDR(.confidential);
-_confidential_section_start = ADDR(.confidential);
-_confidential_section_end = ADDR(.confidential) + SIZEOF(.confidential);
-
_bootargs_ram_start = BOOTARGS_START;
_bootargs_ram_end = BOOTARGS_START + BOOTARGS_SIZE;
@@ -66,11 +62,6 @@ SECTIONS {
. = 16K; /* Overflow causes UsageFault */
} >MAIN_RAM
- .confidential : ALIGN(8) {
- *(.confidential*);
- . = ALIGN(4);
- } >MAIN_RAM AT>FLASH
-
.fb1 : ALIGN(4) {
*(.fb1*);
. = ALIGN(4);
diff --git a/core/embed/sys/linker/stm32u58/bootloader.ld b/core/embed/sys/linker/stm32u58/bootloader.ld
index 528b779e..455d31f4 100644
--- a/core/embed/sys/linker/stm32u58/bootloader.ld
+++ b/core/embed/sys/linker/stm32u58/bootloader.ld
@@ -20,14 +20,10 @@ _data_section_end = ADDR(.data) + SIZEOF(.data);
_bss_section_start = ADDR(.bss);
_bss_section_end = ADDR(.bss) + SIZEOF(.bss);
-_confidential_section_loadaddr = LOADADDR(.confidential);
-_confidential_section_start = ADDR(.confidential);
-_confidential_section_end = ADDR(.confidential) + SIZEOF(.confidential);
-
_bootargs_ram_start = BOOTARGS_START;
_bootargs_ram_end = BOOTARGS_START + BOOTARGS_SIZE;
-_codelen = SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.confidential);
+_codelen = SIZEOF(.flash) + SIZEOF(.data);
SECTIONS {
.header : ALIGN(4) {
@@ -68,11 +64,6 @@ SECTIONS {
. = 16K; /* Overflow causes UsageFault */
} >MAIN_RAM
- .confidential : ALIGN(512) {
- *(.confidential*);
- . = ALIGN(512);
- } >MAIN_RAM AT>FLASH
-
.fb1 : ALIGN(4) {
*(.fb1*);
. = ALIGN(4);
diff --git a/core/embed/sys/linker/stm32u58/firmware.ld b/core/embed/sys/linker/stm32u58/firmware.ld
index 77d5db8b..db5decbb 100644
--- a/core/embed/sys/linker/stm32u58/firmware.ld
+++ b/core/embed/sys/linker/stm32u58/firmware.ld
@@ -17,11 +17,7 @@ _data_section_end = ADDR(.data) + SIZEOF(.data);
_bss_section_start = ADDR(.bss);
_bss_section_end = ADDR(.bss) + SIZEOF(.bss);
-_confidential_section_loadaddr = LOADADDR(.confidential);
-_confidential_section_start = ADDR(.confidential);
-_confidential_section_end = ADDR(.confidential) + SIZEOF(.confidential);
-
-_codelen = SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.confidential);
+_codelen = SIZEOF(.flash) + SIZEOF(.data);
_heap_start = ADDR(.heap);
_heap_end = ADDR(.heap) + SIZEOF(.heap);
@@ -69,11 +65,6 @@ SECTIONS {
. = 32K; /* Overflow causes UsageFault */
} >AUX2_RAM
- .confidential : ALIGN(512) {
- *(.confidential*);
- . = ALIGN(512);
- } >AUX2_RAM AT>FLASH
-
.buf : ALIGN(4) {
*(.buf*);
. = ALIGN(4);
diff --git a/core/embed/sys/linker/stm32u58/kernel.ld b/core/embed/sys/linker/stm32u58/kernel.ld
index 6faee437..4c812876 100644
--- a/core/embed/sys/linker/stm32u58/kernel.ld
+++ b/core/embed/sys/linker/stm32u58/kernel.ld
@@ -19,10 +19,6 @@ _data_section_end = ADDR(.data) + SIZEOF(.data);
_bss_section_start = ADDR(.bss);
_bss_section_end = ADDR(.bss) + SIZEOF(.bss);
-_confidential_section_loadaddr = LOADADDR(.confidential);
-_confidential_section_start = ADDR(.confidential);
-_confidential_section_end = ADDR(.confidential) + SIZEOF(.confidential);
-
_bootargs_ram_start = BOOTARGS_START;
_bootargs_ram_end = BOOTARGS_START + BOOTARGS_SIZE;
@@ -68,11 +64,6 @@ SECTIONS {
. = ALIGN(4);
} >MAIN_RAM
- .confidential : ALIGN(512) {
- *(.confidential*);
- . = ALIGN(CODE_ALIGNMENT);
- } >MAIN_RAM AT>FLASH
-
.fb1 : ALIGN(4) {
*(.fb1*);
. = ALIGN(4);
diff --git a/core/embed/sys/linker/stm32u58/prodtest.ld b/core/embed/sys/linker/stm32u58/prodtest.ld
index ad9d7423..23114edf 100644
--- a/core/embed/sys/linker/stm32u58/prodtest.ld
+++ b/core/embed/sys/linker/stm32u58/prodtest.ld
@@ -21,14 +21,10 @@ _data_section_end = ADDR(.data) + SIZEOF(.data);
_bss_section_start = ADDR(.bss);
_bss_section_end = ADDR(.bss) + SIZEOF(.bss);
-_confidential_section_loadaddr = LOADADDR(.confidential);
-_confidential_section_start = ADDR(.confidential);
-_confidential_section_end = ADDR(.confidential) + SIZEOF(.confidential);
-
_bootargs_ram_start = BOOTARGS_START;
_bootargs_ram_end = BOOTARGS_START + BOOTARGS_SIZE;
-_codelen = SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.confidential);
+_codelen = SIZEOF(.flash) + SIZEOF(.data);
SECTIONS {
.vendorheader : ALIGN(4) {
@@ -84,11 +80,6 @@ SECTIONS {
. = 16K; /* Overflow causes UsageFault */
} >MAIN_RAM
- .confidential : ALIGN(512) {
- *(.confidential*);
- . = ALIGN(512);
- } >MAIN_RAM AT>FLASH
-
.fb1 : ALIGN(4) {
*(.fb1*);
. = ALIGN(4);
diff --git a/core/embed/sys/linker/stm32u5g/boardloader.ld b/core/embed/sys/linker/stm32u5g/boardloader.ld
index 8eb50a05..d48bfe38 100644
--- a/core/embed/sys/linker/stm32u5g/boardloader.ld
+++ b/core/embed/sys/linker/stm32u5g/boardloader.ld
@@ -21,10 +21,6 @@ _data_section_end = ADDR(.data) + SIZEOF(.data);
_bss_section_start = ADDR(.bss);
_bss_section_end = ADDR(.bss) + SIZEOF(.bss);
-_confidential_section_loadaddr = LOADADDR(.confidential);
-_confidential_section_start = ADDR(.confidential);
-_confidential_section_end = ADDR(.confidential) + SIZEOF(.confidential);
-
_bootargs_ram_start = BOOTARGS_START;
_bootargs_ram_end = BOOTARGS_START + BOOTARGS_SIZE;
@@ -67,11 +63,6 @@ SECTIONS {
. = 16K; /* Overflow causes UsageFault */
} >MAIN_RAM
- .confidential : ALIGN(8) {
- *(.confidential*);
- . = ALIGN(4);
- } >MAIN_RAM AT>FLASH
-
.fb1 : ALIGN(4) {
*(.fb1*);
. = ALIGN(4);
diff --git a/core/embed/sys/linker/stm32u5g/bootloader.ld b/core/embed/sys/linker/stm32u5g/bootloader.ld
index 1d6888ae..f64643d9 100644
--- a/core/embed/sys/linker/stm32u5g/bootloader.ld
+++ b/core/embed/sys/linker/stm32u5g/bootloader.ld
@@ -19,10 +19,6 @@ _data_section_end = ADDR(.data) + SIZEOF(.data);
_bss_section_start = ADDR(.bss);
_bss_section_end = ADDR(.bss) + SIZEOF(.bss);
-_confidential_section_loadaddr = LOADADDR(.confidential);
-_confidential_section_start = ADDR(.confidential);
-_confidential_section_end = ADDR(.confidential) + SIZEOF(.confidential);
-
_bootargs_ram_start = BOOTARGS_START;
_bootargs_ram_end = BOOTARGS_START + BOOTARGS_SIZE;
@@ -72,11 +68,6 @@ SECTIONS {
. = 16K; /* Overflow causes UsageFault */
} >MAIN_RAM
- .confidential : ALIGN(512) {
- *(.confidential*);
- . = ALIGN(512);
- } >MAIN_RAM AT>FLASH
-
.fb1 : ALIGN(4) {
*(.fb1*);
. = ALIGN(4);
diff --git a/core/embed/sys/linker/stm32u5g/firmware.ld b/core/embed/sys/linker/stm32u5g/firmware.ld
index c52b0400..d7cecb14 100644
--- a/core/embed/sys/linker/stm32u5g/firmware.ld
+++ b/core/embed/sys/linker/stm32u5g/firmware.ld
@@ -16,11 +16,8 @@ _data_section_end = ADDR(.data) + SIZEOF(.data);
_bss_section_start = ADDR(.bss);
_bss_section_end = ADDR(.bss) + SIZEOF(.bss);
-_confidential_section_loadaddr = LOADADDR(.confidential);
-_confidential_section_start = ADDR(.confidential);
-_confidential_section_end = ADDR(.confidential) + SIZEOF(.confidential);
+_codelen = SIZEOF(.padding) + SIZEOF(.flash) + SIZEOF(.data);
-_codelen = SIZEOF(.padding) + SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.confidential);
_heap_start = ADDR(.heap);
_heap_end = ADDR(.heap) + SIZEOF(.heap);
@@ -74,11 +71,6 @@ SECTIONS {
. = ALIGN(4);
} >AUX1_RAM
- .confidential : ALIGN(512) {
- *(.confidential*);
- . = ALIGN(512);
- } >AUX1_RAM AT>FLASH
-
.buf : ALIGN(4) {
*(.buf*);
. = ALIGN(4);
diff --git a/core/embed/sys/linker/stm32u5g/kernel.ld b/core/embed/sys/linker/stm32u5g/kernel.ld
index dc4ab78e..aea569ef 100644
--- a/core/embed/sys/linker/stm32u5g/kernel.ld
+++ b/core/embed/sys/linker/stm32u5g/kernel.ld
@@ -19,10 +19,6 @@ _data_section_end = ADDR(.data) + SIZEOF(.data);
_bss_section_start = ADDR(.bss);
_bss_section_end = ADDR(.bss) + SIZEOF(.bss);
-_confidential_section_loadaddr = LOADADDR(.confidential);
-_confidential_section_start = ADDR(.confidential);
-_confidential_section_end = ADDR(.confidential) + SIZEOF(.confidential);
-
_bootargs_ram_start = BOOTARGS_START;
_bootargs_ram_end = BOOTARGS_START + BOOTARGS_SIZE;
@@ -71,11 +67,6 @@ SECTIONS {
. = ALIGN(4);
} >MAIN_RAM
- .confidential : ALIGN(512) {
- *(.confidential*);
- . = ALIGN(512);
- } >MAIN_RAM AT>FLASH
-
.fb1 : ALIGN(4) {
*(.fb1*);
. = ALIGN(4);
diff --git a/core/embed/sys/linker/stm32u5g/prodtest.ld b/core/embed/sys/linker/stm32u5g/prodtest.ld
index 9f522103..e17957b5 100644
--- a/core/embed/sys/linker/stm32u5g/prodtest.ld
+++ b/core/embed/sys/linker/stm32u5g/prodtest.ld
@@ -20,15 +20,11 @@ _data_section_end = ADDR(.data) + SIZEOF(.data);
_bss_section_start = ADDR(.bss);
_bss_section_end = ADDR(.bss) + SIZEOF(.bss);
-_confidential_section_loadaddr = LOADADDR(.confidential);
-_confidential_section_start = ADDR(.confidential);
-_confidential_section_end = ADDR(.confidential) + SIZEOF(.confidential);
-
_bootargs_ram_start = BOOTARGS_START;
_bootargs_ram_end = BOOTARGS_START + BOOTARGS_SIZE;
-_codelen = SIZEOF(.secmon_header) + SIZEOF(.padding) + SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.confidential);
-_secmon_codelen = SIZEOF(.padding) + SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.confidential);
+_codelen = SIZEOF(.secmon_header) + SIZEOF(.padding) + SIZEOF(.flash) + SIZEOF(.data);
+_secmon_codelen = SIZEOF(.padding) + SIZEOF(.flash) + SIZEOF(.data);
SECTIONS {
.vendorheader : ALIGN(4) {
@@ -87,11 +83,6 @@ SECTIONS {
. = ALIGN(4);
} >AUX1_RAM
- .confidential : ALIGN(512) {
- *(.confidential*);
- . = ALIGN(512);
- } >MAIN_RAM AT>FLASH
-
.fb1 : ALIGN(4) {
*(.fb1*);
. = ALIGN(4);
diff --git a/core/embed/sys/linker/stm32u5g/secmon.ld b/core/embed/sys/linker/stm32u5g/secmon.ld
index ff185944..713644a6 100644
--- a/core/embed/sys/linker/stm32u5g/secmon.ld
+++ b/core/embed/sys/linker/stm32u5g/secmon.ld
@@ -21,10 +21,6 @@ _data_section_end = ADDR(.data) + SIZEOF(.data);
_bss_section_start = ADDR(.bss);
_bss_section_end = ADDR(.bss) + SIZEOF(.bss);
-_confidential_section_loadaddr = LOADADDR(.confidential);
-_confidential_section_start = ADDR(.confidential);
-_confidential_section_end = ADDR(.confidential) + SIZEOF(.confidential);
-
_bootargs_ram_start = BOOTARGS_START;
_bootargs_ram_end = BOOTARGS_START + BOOTARGS_SIZE;
@@ -77,11 +73,6 @@ SECTIONS {
. = ALIGN(512);
} >RAM AT>FLASH
- .confidential : ALIGN(512) {
- *(.confidential*);
- . = ALIGN(4);
- } >RAM AT>FLASH
-
.bss : ALIGN(4) {
*(.bss*);
. = ALIGN(4);
diff --git a/core/site_scons/models/stm32f4_common.py b/core/site_scons/models/stm32f4_common.py
index ef49cec9..5d07a78c 100644
--- a/core/site_scons/models/stm32f4_common.py
+++ b/core/site_scons/models/stm32f4_common.py
@@ -8,7 +8,6 @@ def stm32f4_common_files(env, features_wanted, defines, sources, paths):
("STM32_HAL_H", "<stm32f4xx.h>"),
("FLASH_BLOCK_WORDS", "1"),
("FLASH_BIT_ACCESS", "1"),
- ("CONFIDENTIAL", ""),
]
paths += [
diff --git a/core/site_scons/models/stm32u5_common.py b/core/site_scons/models/stm32u5_common.py
index 19b2cf75..88d8d7e5 100644
--- a/core/site_scons/models/stm32u5_common.py
+++ b/core/site_scons/models/stm32u5_common.py
@@ -8,7 +8,6 @@ def stm32u5_common_files(env, features_wanted, defines, sources, paths):
("STM32_HAL_H", "<stm32u5xx.h>"),
("FLASH_BLOCK_WORDS", "4"),
("USE_TRUSTZONE", "1"),
- ("CONFIDENTIAL", '__attribute__((section(".confidential")))'),
]
paths += [
diff --git a/core/site_scons/models/unix_common.py b/core/site_scons/models/unix_common.py
index 8efd7005..5b5b9c76 100644
--- a/core/site_scons/models/unix_common.py
+++ b/core/site_scons/models/unix_common.py
@@ -7,7 +7,6 @@ def unix_common_files(env, features_wanted, defines, sources, paths):
defines += [
("FLASH_BLOCK_WORDS", "1"),
("FLASH_BIT_ACCESS", "1"),
- ("CONFIDENTIAL", ""),
]
paths += [
diff --git a/crypto/bip32.c b/crypto/bip32.c
index 41d09c70..278f6623 100644
--- a/crypto/bip32.c
+++ b/crypto/bip32.c
@@ -144,7 +144,7 @@ int hdnode_from_xprv(uint32_t depth, uint32_t child_num,
int hdnode_from_seed(const uint8_t *seed, int seed_len, const char *curve,
HDNode *out) {
- static CONFIDENTIAL uint8_t I[32 + 32];
+ LOCAL_CONFIDENTIAL uint8_t I[32 + 32];
memzero(out, sizeof(HDNode));
out->depth = 0;
out->child_num = 0;
@@ -152,7 +152,7 @@ int hdnode_from_seed(const uint8_t *seed, int seed_len, const char *curve,
if (out->curve == 0) {
return 0;
}
- static CONFIDENTIAL HMAC_SHA512_CTX ctx;
+ LOCAL_CONFIDENTIAL HMAC_SHA512_CTX ctx;
hmac_sha512_Init(&ctx, (const uint8_t *)out->curve->bip32_name,
strlen(out->curve->bip32_name));
hmac_sha512_Update(&ctx, seed, seed_len);
@@ -194,9 +194,9 @@ uint32_t hdnode_fingerprint(HDNode *node) {
}
int hdnode_private_ckd_bip32(HDNode *inout, uint32_t i) {
- static CONFIDENTIAL uint8_t data[1 + 32 + 4];
- static CONFIDENTIAL uint8_t I[32 + 32];
- static CONFIDENTIAL bignum256 a, b;
+ LOCAL_CONFIDENTIAL uint8_t data[1 + 32 + 4];
+ LOCAL_CONFIDENTIAL uint8_t I[32 + 32];
+ LOCAL_CONFIDENTIAL bignum256 a, b;
#if USE_CARDANO
if (inout->curve == &ed25519_cardano_info) {
@@ -222,7 +222,7 @@ int hdnode_private_ckd_bip32(HDNode *inout, uint32_t i) {
bn_read_be(inout->private_key, &a);
- static CONFIDENTIAL HMAC_SHA512_CTX ctx;
+ LOCAL_CONFIDENTIAL HMAC_SHA512_CTX ctx;
hmac_sha512_Init(&ctx, inout->chain_code, 32);
hmac_sha512_Update(&ctx, data, sizeof(data));
hmac_sha512_Final(&ctx, I);
diff --git a/crypto/bip39.c b/crypto/bip39.c
index e844c390..f46ca046 100644
--- a/crypto/bip39.c
+++ b/crypto/bip39.c
@@ -195,7 +195,7 @@ void mnemonic_to_seed(const char *mnemonic, const char *passphrase,
uint8_t salt[8 + 256] = {0};
memcpy(salt, "mnemonic", 8);
memcpy(salt + 8, passphrase, passphraselen);
- static CONFIDENTIAL PBKDF2_HMAC_SHA512_CTX pctx;
+ LOCAL_CONFIDENTIAL PBKDF2_HMAC_SHA512_CTX pctx;
pbkdf2_hmac_sha512_Init(&pctx, (const uint8_t *)mnemonic, mnemoniclen, salt,
passphraselen + 8, 1);
if (progress_callback) {
diff --git a/crypto/cardano.c b/crypto/cardano.c
index 090dfe3c..116c3e2d 100644
--- a/crypto/cardano.c
+++ b/crypto/cardano.c
@@ -89,10 +89,10 @@ int hdnode_private_ckd_cardano(HDNode *inout, uint32_t index) {
keysize = 64;
}
- static CONFIDENTIAL uint8_t data[1 + 64 + 4];
- static CONFIDENTIAL uint8_t z[32 + 32];
- static CONFIDENTIAL uint8_t priv_key[64];
- static CONFIDENTIAL uint8_t res_key[64];
+ LOCAL_CONFIDENTIAL uint8_t data[1 + 64 + 4];
+ LOCAL_CONFIDENTIAL uint8_t z[32 + 32];
+ LOCAL_CONFIDENTIAL uint8_t priv_key[64];
+ LOCAL_CONFIDENTIAL uint8_t res_key[64];
write_le(data + keysize + 1, index);
@@ -111,12 +111,12 @@ int hdnode_private_ckd_cardano(HDNode *inout, uint32_t index) {
memcpy(data + 1, inout->public_key + 1, 32);
}
- static CONFIDENTIAL HMAC_SHA512_CTX ctx;
+ LOCAL_CONFIDENTIAL HMAC_SHA512_CTX ctx;
hmac_sha512_Init(&ctx, inout->chain_code, 32);
hmac_sha512_Update(&ctx, data, 1 + keysize + 4);
hmac_sha512_Final(&ctx, z);
- static CONFIDENTIAL uint8_t zl8[32];
+ LOCAL_CONFIDENTIAL uint8_t zl8[32];
memzero(zl8, 32);
/* get 8 * Zl */
@@ -177,8 +177,8 @@ int hdnode_from_secret_cardano(const uint8_t secret[CARDANO_SECRET_LENGTH],
// SLIP-0023.
int secret_from_seed_cardano_slip23(const uint8_t *seed, int seed_len,
uint8_t secret_out[CARDANO_SECRET_LENGTH]) {
- static CONFIDENTIAL uint8_t I[SHA512_DIGEST_LENGTH];
- static CONFIDENTIAL HMAC_SHA512_CTX ctx;
+ LOCAL_CONFIDENTIAL uint8_t I[SHA512_DIGEST_LENGTH];
+ LOCAL_CONFIDENTIAL HMAC_SHA512_CTX ctx;
hmac_sha512_Init(&ctx, (const uint8_t *)ED25519_CARDANO_NAME,
strlen(ED25519_CARDANO_NAME));
@@ -200,10 +200,10 @@ int secret_from_seed_cardano_slip23(const uint8_t *seed, int seed_len,
// https://github.com/cardano-foundation/CIPs/blob/09d7d8ee1bd64f7e6b20b5a6cae088039dce00cb/CIP-0003/Ledger.md
int secret_from_seed_cardano_ledger(const uint8_t *seed, int seed_len,
uint8_t secret_out[CARDANO_SECRET_LENGTH]) {
- static CONFIDENTIAL uint8_t chain_code[SHA256_DIGEST_LENGTH];
- static CONFIDENTIAL uint8_t root_key[SHA512_DIGEST_LENGTH];
- static CONFIDENTIAL HMAC_SHA256_CTX ctx;
- static CONFIDENTIAL HMAC_SHA512_CTX sctx;
+ LOCAL_CONFIDENTIAL uint8_t chain_code[SHA256_DIGEST_LENGTH];
+ LOCAL_CONFIDENTIAL uint8_t root_key[SHA512_DIGEST_LENGTH];
+ LOCAL_CONFIDENTIAL HMAC_SHA256_CTX ctx;
+ LOCAL_CONFIDENTIAL HMAC_SHA512_CTX sctx;
const uint8_t *intermediate_result = seed;
int intermediate_result_len = seed_len;
@@ -260,8 +260,8 @@ int secret_from_entropy_cardano_icarus(
const uint8_t *pass, int pass_len, const uint8_t *entropy, int entropy_len,
uint8_t secret_out[CARDANO_SECRET_LENGTH],
void (*progress_callback)(uint32_t, uint32_t)) {
- static CONFIDENTIAL PBKDF2_HMAC_SHA512_CTX pctx;
- static CONFIDENTIAL uint8_t digest[SHA512_DIGEST_LENGTH];
+ LOCAL_CONFIDENTIAL PBKDF2_HMAC_SHA512_CTX pctx;
+ LOCAL_CONFIDENTIAL uint8_t digest[SHA512_DIGEST_LENGTH];
uint32_t progress = 0;
// PASS 1: first 64 bytes
diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c
index 8c013378..e8a63c97 100644
--- a/crypto/ecdsa.c
+++ b/crypto/ecdsa.c
@@ -418,13 +418,13 @@ int point_multiply(const ecdsa_curve *curve, const bignum256 *k,
}
int i = 0, j = 0;
- static CONFIDENTIAL bignum256 a;
+ LOCAL_CONFIDENTIAL bignum256 a;
uint32_t *aptr = NULL;
uint32_t abits = 0;
int ashift = 0;
uint32_t is_even = (k->val[0] & 1) - 1;
uint32_t bits = {0}, sign = {0}, nsign = {0};
- static CONFIDENTIAL jacobian_curve_point jres;
+ LOCAL_CONFIDENTIAL jacobian_curve_point jres;
curve_point pmult[8] = {0};
const bignum256 *prime = &curve->prime;
@@ -544,10 +544,10 @@ int scalar_multiply(const ecdsa_curve *curve, const bignum256 *k,
}
int i = {0}, j = {0};
- static CONFIDENTIAL bignum256 a;
+ LOCAL_CONFIDENTIAL bignum256 a;
uint32_t is_even = (k->val[0] & 1) - 1;
uint32_t lowbits = 0;
- static CONFIDENTIAL jacobian_curve_point jres;
+ LOCAL_CONFIDENTIAL jacobian_curve_point jres;
const bignum256 *prime = &curve->prime;
// is_even = 0xffffffff if k is even, 0 otherwise.
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 654f2d6e..c9de37a6 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -29,7 +29,7 @@
void hmac_sha256_Init(HMAC_SHA256_CTX *hctx, const uint8_t *key,
const uint32_t keylen) {
- static CONFIDENTIAL uint8_t i_key_pad[SHA256_BLOCK_LENGTH];
+ LOCAL_CONFIDENTIAL uint8_t i_key_pad[SHA256_BLOCK_LENGTH];
memzero(i_key_pad, SHA256_BLOCK_LENGTH);
if (keylen > SHA256_BLOCK_LENGTH) {
sha256_Raw(key, keylen, i_key_pad);
@@ -61,7 +61,7 @@ void hmac_sha256_Final(HMAC_SHA256_CTX *hctx, uint8_t *hmac) {
void hmac_sha256(const uint8_t *key, const uint32_t keylen, const uint8_t *msg,
const uint32_t msglen, uint8_t *hmac) {
- static CONFIDENTIAL HMAC_SHA256_CTX hctx;
+ LOCAL_CONFIDENTIAL HMAC_SHA256_CTX hctx;
hmac_sha256_Init(&hctx, key, keylen);
hmac_sha256_Update(&hctx, msg, msglen);
hmac_sha256_Final(&hctx, hmac);
@@ -69,11 +69,11 @@ void hmac_sha256(const uint8_t *key, const uint32_t keylen, const uint8_t *msg,
void hmac_sha256_prepare(const uint8_t *key, const uint32_t keylen,
uint32_t *opad_digest, uint32_t *ipad_digest) {
- static CONFIDENTIAL uint32_t key_pad[SHA256_BLOCK_LENGTH / sizeof(uint32_t)];
+ LOCAL_CONFIDENTIAL uint32_t key_pad[SHA256_BLOCK_LENGTH / sizeof(uint32_t)];
memzero(key_pad, sizeof(key_pad));
if (keylen > SHA256_BLOCK_LENGTH) {
- static CONFIDENTIAL SHA256_CTX context;
+ LOCAL_CONFIDENTIAL SHA256_CTX context;
sha256_Init(&context);
sha256_Update(&context, key, keylen);
sha256_Final(&context, (uint8_t *)key_pad);
@@ -103,7 +103,7 @@ void hmac_sha256_prepare(const uint8_t *key, const uint32_t keylen,
void hmac_sha512_Init(HMAC_SHA512_CTX *hctx, const uint8_t *key,
const uint32_t keylen) {
- static CONFIDENTIAL uint8_t i_key_pad[SHA512_BLOCK_LENGTH];
+ LOCAL_CONFIDENTIAL uint8_t i_key_pad[SHA512_BLOCK_LENGTH];
memzero(i_key_pad, SHA512_BLOCK_LENGTH);
if (keylen > SHA512_BLOCK_LENGTH) {
sha512_Raw(key, keylen, i_key_pad);
@@ -143,11 +143,11 @@ void hmac_sha512(const uint8_t *key, const uint32_t keylen, const uint8_t *msg,
void hmac_sha512_prepare(const uint8_t *key, const uint32_t keylen,
uint64_t *opad_digest, uint64_t *ipad_digest) {
- static CONFIDENTIAL uint64_t key_pad[SHA512_BLOCK_LENGTH / sizeof(uint64_t)];
+ LOCAL_CONFIDENTIAL uint64_t key_pad[SHA512_BLOCK_LENGTH / sizeof(uint64_t)];
memzero(key_pad, sizeof(key_pad));
if (keylen > SHA512_BLOCK_LENGTH) {
- static CONFIDENTIAL SHA512_CTX context;
+ LOCAL_CONFIDENTIAL SHA512_CTX context;
sha512_Init(&context);
sha512_Update(&context, key, keylen);
sha512_Final(&context, (uint8_t *)key_pad);
diff --git a/crypto/options.h b/crypto/options.h
index f7df3e71..fa6cbbba 100644
--- a/crypto/options.h
+++ b/crypto/options.h
@@ -107,6 +107,11 @@
#define CONFIDENTIAL
#endif
+// add way how to mark local confidential data in functions
+#ifndef LOCAL_CONFIDENTIAL
+#define LOCAL_CONFIDENTIAL
+#endif
+
// add way to mark functions whose return value should always be checked
#ifndef __wur
#define __wur __attribute__((warn_unused_result))
diff --git a/legacy/Makefile.include b/legacy/Makefile.include
index c98ec6b2..600b30cf 100644
--- a/legacy/Makefile.include
+++ b/legacy/Makefile.include
@@ -36,7 +36,7 @@ OPENOCD := openocd -f interface/stlink.cfg -c "transport select hla_swd" -f tar
GDB := $(PREFIX)gdb --nx -ex 'set remotetimeout unlimited' -ex 'set confirm off' -ex 'target remote 127.0.0.1:3333' -ex 'monitor reset halt'
-CONFFLAG ?= -DCONFIDENTIAL='__attribute__((section("confidential")))' -fstack-protector-all
+CONFFLAG ?= -DCONFIDENTIAL='__attribute__((section("confidential")))' -DLOCAL_CONFIDENTIAL='static CONFIDENTIAL' -fstack-protector-all
OPTFLAGS ?= -O3
DBGFLAGS ?= -g -DNDEBUG
CPUFLAGS ?= -mcpu=cortex-m3 -mthumb
diff --git a/storage/norcow.c b/storage/norcow.c
index c0f6713d..076fde06 100644
--- a/storage/norcow.c
+++ b/storage/norcow.c
@@ -23,6 +23,7 @@
#include "flash_area.h"
#include "memzero.h"
#include "norcow.h"
+#include "options.h"
#include "storage_utils.h"
// NRC2 = 4e524332
diff --git a/storage/storage.c b/storage/storage.c
index 23e36c88..4eceade6 100644
--- a/storage/storage.c
+++ b/storage/storage.c
@@ -30,6 +30,7 @@
#include "hmac.h"
#include "memzero.h"
#include "norcow.h"
+#include "options.h"
#include "pbkdf2.h"
#include "rand.h"
#include "random_delays.h"
@@ -169,7 +170,7 @@ static enum storage_ui_message_t ui_message = NO_MSG;
CONFIDENTIAL static uint8_t cached_keys[KEYS_SIZE] = {0};
CONFIDENTIAL static uint8_t *const cached_dek = cached_keys;
CONFIDENTIAL static uint8_t *const cached_sak = cached_keys + DEK_SIZE;
-CONFIDENTIAL uint8_t authentication_sum[SHA256_DIGEST_LENGTH] = {0};
+CONFIDENTIAL static uint8_t authentication_sum[SHA256_DIGEST_LENGTH] = {0};
CONFIDENTIAL static uint8_t hardware_salt[HARDWARE_SALT_SIZE] = {0};
CONFIDENTIAL static uint32_t norcow_active_version = 0;
static const uint8_t TRUE_BYTE = 0x01;
Why this scored 63/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.