1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-04-25 03:29:02 +00:00

fix(core): fix optiga pairing issue

[no changelog]
This commit is contained in:
cepetr 2025-02-07 14:16:23 +01:00 committed by cepetr
parent d35f062866
commit 117eec798c
4 changed files with 24 additions and 18 deletions
core/embed/sys
startup
task/stm32

View File

@ -28,9 +28,13 @@ typedef void (*new_stack_callback_t)(uint32_t arg1, uint32_t arg2);
// Disables interrupts, disables the MPU, clears
// all registers, sets up a new stack and calls the given callback.
//
// If `clear_bkregs` is set, the function also clears the BKP registers
// and SRAM2 on STM32U5. It has no effect on STM32F4.
//
// The function is intended to be used in special cases, like
// emergency situations, where the current stack may be corrupted.
__attribute((noreturn)) void call_with_new_stack(uint32_t arg1, uint32_t arg2,
bool clear_bkpregs,
new_stack_callback_t callback);
// Ensure that we are running in privileged thread mode.

View File

@ -136,7 +136,7 @@ __attribute__((noreturn)) static void halt_device(void) {
// Disable interrupts, MPU, clear all registers and set up a new stack
// (on STM32U5 it also clear all CPU secrets and SRAM2).
call_with_new_stack(0, 0, halt_device_phase_2);
call_with_new_stack(0, 0, true, halt_device_phase_2);
}
#endif // RSOD_INFINITE_LOOP
@ -188,7 +188,7 @@ __attribute__((noreturn)) static void reboot_with_args(boot_command_t command,
// Disable interrupts, MPU, clear all registers and set up a new stack
// (on STM32U5 it also clear all CPU secrets and SRAM2).
call_with_new_stack(command, 0, reboot_with_args_phase_2);
call_with_new_stack(command, 0, true, reboot_with_args_phase_2);
}
__attribute__((noreturn)) void reboot_to_bootloader(void) {
@ -247,7 +247,7 @@ void __attribute__((noreturn)) jump_to_next_stage(uint32_t vectbl_address) {
// Disable interrupts, MPU, clear all registers and set up a new stack
// (on STM32U5 it also clear all CPU secrets and SRAM2).
call_with_new_stack(vectbl_address, 0, jump_to_next_stage_phase_2);
call_with_new_stack(vectbl_address, 0, false, jump_to_next_stage_phase_2);
}
#endif // KERNEL_MODE

View File

@ -29,7 +29,8 @@
#endif
__attribute((naked, noreturn, no_stack_protector)) void call_with_new_stack(
uint32_t arg1, uint32_t arg2, new_stack_callback_t callback) {
uint32_t arg1, uint32_t arg2, bool clear_bkpregs,
new_stack_callback_t callback) {
__asm__ volatile(
// R0, R1, R2 are used for arguments
@ -48,8 +49,10 @@ __attribute((naked, noreturn, no_stack_protector)) void call_with_new_stack(
#ifdef STM32U5
__asm__ volatile(
"CMP R2, #0 \n" // clear_bkpregs?
"BEQ 1f \n"
// --------------------------------------------------------------
// Delete all secrets and SRAM2 where stack is located.
// Delete all BKP registers and SRAM2 where stack is located.
// SAES peripheral need to be disabled, so that we don't get
// tamper events.
// --------------------------------------------------------------
@ -67,7 +70,7 @@ __attribute((naked, noreturn, no_stack_protector)) void call_with_new_stack(
"LDR R6, [R4] \n"
"ORR R6, R6, R5 \n"
"STR R6, [R4] \n"
"1: \n"
: // no output
: [_RCC_AHB2ENR1] "i"(&RCC->AHB2ENR1),
[_RCC_AHB2ENR1_SAESEN] "i"(RCC_AHB2ENR1_SAESEN),
@ -107,16 +110,15 @@ __attribute((naked, noreturn, no_stack_protector)) void call_with_new_stack(
// Clear all unused registers
// --------------------------------------------------------------
"MOV R3, #0 \n"
"MOV R4, R3 \n"
"MOV R5, R3 \n"
"MOV R6, R3 \n"
"MOV R7, R3 \n"
"MOV R8, R3 \n"
"MOV R9, R3 \n"
"MOV R10, R3 \n"
"MOV R11, R3 \n"
"MOV R12, R3 \n"
"MOV R4, #0 \n"
"MOV R5, R4 \n"
"MOV R6, R4 \n"
"MOV R7, R4 \n"
"MOV R8, R4 \n"
"MOV R9, R4 \n"
"MOV R10, R4 \n"
"MOV R11, R4 \n"
"MOV R12, R4 \n"
// --------------------------------------------------------------
// Invoke phase 2 function
@ -125,7 +127,7 @@ __attribute((naked, noreturn, no_stack_protector)) void call_with_new_stack(
// R0 = arg1
// R1 = arg2
"BX R2 \n"
"BX R3 \n"
: // no output
: [estack] "i"(&_stack_section_end),

View File

@ -131,7 +131,7 @@ __attribute((naked, noreturn, no_stack_protector)) void system_emergency_rescue(
// Save `pminfo` to bootargs so it isn't overwritten by succesive call
bootargs_set(BOOT_COMMAND_SHOW_RSOD, pminfo, sizeof(*pminfo));
call_with_new_stack((uint32_t)error_handler, 0,
call_with_new_stack((uint32_t)error_handler, 0, true,
system_emergency_rescue_phase_2);
}