Skip to content

Commit

Permalink
chore(core): use cortex-m33 stack protection
Browse files Browse the repository at this point in the history
  • Loading branch information
cepetr authored and TychoVrahe committed Nov 15, 2023
1 parent dda5b6f commit 5964132
Show file tree
Hide file tree
Showing 21 changed files with 129 additions and 46 deletions.
1 change: 1 addition & 0 deletions core/SConscript.bootloader_emu
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ SOURCE_BOOTLOADER = [
SOURCE_TREZORHAL = [
'embed/trezorhal/unix/boot_args.c',
'embed/trezorhal/unix/display-unix.c',
'embed/trezorhal/unix/fault_handlers.c',
'embed/trezorhal/unix/flash.c',
'embed/trezorhal/unix/common.c',
'embed/trezorhal/unix/touch/touch.c',
Expand Down
3 changes: 3 additions & 0 deletions core/embed/boardloader/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "common.h"
#include "compiler_traits.h"
#include "display.h"
#include "fault_handlers.h"
#include "flash.h"
#include "image.h"
#include "model.h"
Expand Down Expand Up @@ -256,6 +257,8 @@ int main(void) {

mpu_config_boardloader();

fault_handlers_init();

#ifdef USE_SDRAM
sdram_init();
#endif
Expand Down
4 changes: 2 additions & 2 deletions core/embed/boardloader/memory_stm32u5a.ld
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ MEMORY {
}

main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
_sstack = ORIGIN(SRAM2) + 0x100;
_sstack = ORIGIN(SRAM2);
_estack = main_stack_base;

/* used by the startup code to populate variables used by the C code */
Expand Down Expand Up @@ -80,7 +80,7 @@ SECTIONS {
} >SRAM1

.stack : ALIGN(8) {
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */
. = 16K; /* Overflow causes UsageFault */
} >SRAM2

.sensitive : ALIGN(8) {
Expand Down
5 changes: 5 additions & 0 deletions core/embed/boardloader/startup_stm32u5.s
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
.global reset_handler
.type reset_handler, STT_FUNC
reset_handler:
// set the stack protection
ldr r0, =_sstack
add r0, r0, #16 // padding
msr MSPLIM, r0

bl SystemInit

// read the first rng data and save it
Expand Down
3 changes: 3 additions & 0 deletions core/embed/bootloader/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "boot_args.h"
#include "common.h"
#include "display.h"
#include "fault_handlers.h"
#include "flash.h"
#include "image.h"
#include "lowlevel.h"
Expand Down Expand Up @@ -423,6 +424,8 @@ int bootloader_main(void) {

mpu_config_bootloader();

fault_handlers_init();

#ifdef TREZOR_EMULATOR
// wait a bit so that the empty lock icon is visible
// (on a real device, we are waiting for touch init which takes longer)
Expand Down
4 changes: 2 additions & 2 deletions core/embed/bootloader/memory_stm32u5a.ld
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ MEMORY {
}

main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
_sstack = ORIGIN(SRAM2) + 0x100;
_sstack = ORIGIN(SRAM2);
_estack = main_stack_base;

/* used by the startup code to populate variables used by the C code */
Expand Down Expand Up @@ -81,7 +81,7 @@ SECTIONS {
} >SRAM1

.stack : ALIGN(8) {
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */
. = 16K; /* Overflow causes UsageFault */
} >SRAM2

.sensitive : ALIGN(512) {
Expand Down
5 changes: 5 additions & 0 deletions core/embed/bootloader/startup_stm32u5.s
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
.global reset_handler
.type reset_handler, STT_FUNC
reset_handler:
// set the stack protection
ldr r0, =_sstack
add r0, r0, #16 // padding
msr MSPLIM, r0

// setup environment for subsequent stage of code
ldr r2, =0 // r2 - the word-sized value to be written

Expand Down
21 changes: 17 additions & 4 deletions core/embed/firmware/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include "common.h"
#include "compiler_traits.h"
#include "display.h"
#include "fault_handlers.h"
#include "flash.h"
#include "image.h"
#include "memzero.h"
Expand Down Expand Up @@ -95,6 +96,19 @@
// from util.s
extern void shutdown_privileged(void);

volatile int aa = 1;

int test_stk(int i) {
int a[4096];
a[40] = i;
a[50] = i;
memset(a, 0, sizeof(a));
for (i = 0; i < 4096; i++) {
aa = a[i];
}
return 0;
}

int main(void) {
random_delays_init();

Expand Down Expand Up @@ -143,10 +157,7 @@ int main(void) {
dma2d_init();
#endif

#if !PRODUCTION
// enable BUS fault and USAGE fault handlers
SCB->SHCSR |= (SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk);
#endif
fault_handlers_init();

#if defined TREZOR_MODEL_T
set_core_clock(CLOCK_180_MHZ);
Expand Down Expand Up @@ -193,6 +204,8 @@ int main(void) {
drop_privileges();
#endif

// aa = test_stk(4096);

#ifdef USE_SECP256K1_ZKP
ensure(sectrue * (zkp_context_init() == 0), NULL);
#endif
Expand Down
4 changes: 2 additions & 2 deletions core/embed/firmware/memory_DISC2.ld
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ MEMORY {
}

main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
_sstack = ORIGIN(SRAM2) + 0x100;
_sstack = ORIGIN(SRAM2);
_estack = main_stack_base;

/* used by the startup code to populate variables used by the C code */
Expand Down Expand Up @@ -97,7 +97,7 @@ SECTIONS {
} >SRAM1

.stack : ALIGN(8) {
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */
. = 16K; /* Overflow causes UsageFault */
} >SRAM2

.sensitive : ALIGN(512) {
Expand Down
5 changes: 5 additions & 0 deletions core/embed/firmware/startup_stm32u5.S
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
.global reset_handler
.type reset_handler, STT_FUNC
reset_handler:
// set the stack protection
ldr r0, =_sstack
add r0, r0, #16 // padding
msr MSPLIM, r0

// setup environment for subsequent stage of code
ldr r2, =0 // r2 - the word-sized value to be written

Expand Down
3 changes: 3 additions & 0 deletions core/embed/prodtest/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "button.h"
#include "common.h"
#include "display.h"
#include "fault_handlers.h"
#include "flash.h"
#include "i2c.h"
#include "model.h"
Expand Down Expand Up @@ -569,6 +570,8 @@ int main(void) {
#endif

mpu_config_prodtest();
fault_handlers_init();

drop_privileges();

display_clear();
Expand Down
4 changes: 2 additions & 2 deletions core/embed/prodtest/memory_stm32u5a.ld
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ MEMORY {
}

main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
_sstack = ORIGIN(SRAM2) + 0x100;
_sstack = ORIGIN(SRAM2);
_estack = main_stack_base;

/* used by the startup code to populate variables used by the C code */
Expand Down Expand Up @@ -96,7 +96,7 @@ SECTIONS {
} >SRAM1

.stack : ALIGN(8) {
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */
. = 16K; /* Overflow causes UsageFault */
} >SRAM2

.sensitive : ALIGN(512) {
Expand Down
5 changes: 5 additions & 0 deletions core/embed/prodtest/startup_stm32u5.s
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
.global reset_handler
.type reset_handler, STT_FUNC
reset_handler:
// set the stack protection
ldr r0, =_sstack
add r0, r0, #16 // padding
msr MSPLIM, r0

// setup environment for subsequent stage of code
ldr r2, =0 // r2 - the word-sized value to be written

Expand Down
4 changes: 2 additions & 2 deletions core/embed/reflash/memory_stm32u5a.ld
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ MEMORY {
}

main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
_sstack = ORIGIN(SRAM2) + 0x100;
_sstack = ORIGIN(SRAM2);
_estack = main_stack_base;

/* used by the startup code to populate variables used by the C code */
Expand Down Expand Up @@ -97,7 +97,7 @@ SECTIONS {
} >SRAM1

.stack : ALIGN(8) {
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */
. = 16K + 0x100; /* Overflow causes UsageFault */
} >SRAM2

.sensitive : ALIGN(512) {
Expand Down
5 changes: 5 additions & 0 deletions core/embed/reflash/startup_stm32u5.s
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
.global reset_handler
.type reset_handler, STT_FUNC
reset_handler:
// set the stack protection
ldr r0, =_sstack
add r0, r0, #16 // padding
msr MSPLIM, r0

// setup environment for subsequent stage of code
ldr r2, =0 // r2 - the word-sized value to be written

Expand Down
7 changes: 7 additions & 0 deletions core/embed/trezorhal/fault_handlers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef TREZORHAL_FAULT_HANDLERS_H
#define TREZORHAL_FAULT_HANDLERS_H

// Initializes and enables fault handlers
void fault_handlers_init(void);

#endif // TREZORHAL_FAULT_HANDLERS_H
5 changes: 5 additions & 0 deletions core/embed/trezorhal/stm32f4/fault_handlers.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#include "common.h"

void fault_handlers_init(void) {
// Enable BUS fault and USAGE fault handlers
SCB->SHCSR |= (SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk);
}

void HardFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(HF)"); }

void MemManage_Handler_MM(void) { error_shutdown("INTERNAL ERROR", "(MM)"); }
Expand Down
22 changes: 18 additions & 4 deletions core/embed/trezorhal/stm32u5/fault_handlers.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
#include "common.h"

void HardFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(HF)"); }
void fault_handlers_init(void) {
// Enable BUS fault and USAGE fault handlers
SCB->SHCSR |= (SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk);
}

void MemManage_Handler_MM(void) { error_shutdown("INTERNAL ERROR", "(MM)"); }
void HardFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(HF)"); }

void MemManage_Handler_SO(void) { error_shutdown("INTERNAL ERROR", "(SO)"); }
void MemManage_Handler(void) { error_shutdown("INTERNAL ERROR", "(MM)"); }

void BusFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(BF)"); }

void UsageFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(UF)"); }
void UsageFault_Handler(void) {
if (SCB->CFSR & SCB_CFSR_STKOF_Msk) {
// Stack overflow
extern uint8_t _estack; // linker script symbol
// Fix stack pointer
__set_MSP((uint32_t)&_estack);
error_shutdown("INTERNAL ERROR", "(SO)");
} else {
// Other error
error_shutdown("INTERNAL ERROR", "(UF)");
}
}

void SecureFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(SF)"); }

Expand Down
12 changes: 0 additions & 12 deletions core/embed/trezorhal/stm32u5/limited_util.s
Original file line number Diff line number Diff line change
Expand Up @@ -130,16 +130,4 @@ shutdown_privileged:
ldr r0, =0
b . // loop forever

.global MemManage_Handler
.type MemManage_Handler, STT_FUNC
MemManage_Handler:
ldr r2, =_sstack
mrs r1, msp
ldr r0, =_estack
msr msp, r0
cmp r1, r2
IT lt
bllt MemManage_Handler_SO
bl MemManage_Handler_MM

.end
31 changes: 15 additions & 16 deletions core/embed/trezorhal/stm32u5/mpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,7 @@ static void mpu_set_attributes() {
#define SIZE_128K (128 * 1024)
#define SIZE_192K (192 * 1024)
#define SIZE_320K (320 * 1024)
#define SIZE_768K (768 * 1024)
#define SIZE_1728K ((832 * 2 + 64) * 1024)
#define SIZE_2496K (2496 * 1024)
#define SIZE_3776K ((4096 - 320) * 1024)
#define SIZE_3904K ((4096 - 192) * 1024)
#define SIZE_4032K ((4096 - 64) * 1024)
Expand All @@ -131,10 +130,10 @@ void mpu_config_boardloader() {
SET_REGION( 0, FLASH_BASE_S, SIZE_16K, FLASH_DATA, YES, NO ); // Secret
SET_REGION( 1, FLASH_BASE_S + SIZE_16K, SIZE_48K, FLASH_CODE, NO, NO ); // Boardloader code
SET_REGION( 2, FLASH_BASE_S + SIZE_64K, SIZE_4032K, FLASH_DATA, YES, NO ); // Bootloader + Storage + Firmware
SET_REGION( 3, SRAM1_BASE_S, SIZE_768K, SRAM, YES, NO ); // SRAM1
SET_REGION( 4, SRAM2_BASE_S + 0x100, SIZE_1728K - 0x100, SRAM, YES, NO ); // SRAM2/3/5 + stack guard
SET_REGION( 5, GFXMMU_BUFFERS_S, SIZE_16M, SRAM, YES, NO ); // Frame buffer
SET_REGION( 6, PERIPH_BASE_S, SIZE_256M, PERIPHERAL, YES, NO ); // Peripherals
SET_REGION( 3, SRAM1_BASE_S, SIZE_2496K, SRAM, YES, NO ); // SRAM1/2/3/5
SET_REGION( 4, GFXMMU_BUFFERS_S, SIZE_16M, SRAM, YES, NO ); // Frame buffer
SET_REGION( 5, PERIPH_BASE_S, SIZE_256M, PERIPHERAL, YES, NO ); // Peripherals
DIS_REGION( 6 );
DIS_REGION( 7 );
// clang-format on
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
Expand All @@ -148,11 +147,11 @@ void mpu_config_bootloader() {
SET_REGION( 0, FLASH_BASE_S, SIZE_64K, FLASH_DATA, YES, NO ); // Secret + Boardloader
SET_REGION( 1, FLASH_BASE_S + SIZE_64K, SIZE_128K, FLASH_CODE, NO, NO ); // Bootloader code
SET_REGION( 2, FLASH_BASE_S + SIZE_192K, SIZE_3904K, FLASH_DATA, YES, NO ); // Storage + Firmware
SET_REGION( 3, SRAM1_BASE_S, SIZE_768K, SRAM, YES, NO ); // SRAM1
SET_REGION( 4, SRAM2_BASE_S + 0x100, SIZE_1728K - 0x100, SRAM, YES, NO ); // SRAM2/3/5 + stack guard
SET_REGION( 5, GFXMMU_BUFFERS_S, SIZE_16M, SRAM, YES, NO ); // Frame buffer
SET_REGION( 6, PERIPH_BASE_S, SIZE_256M, PERIPHERAL, YES, NO ); // Peripherals
SET_REGION( 7, FLASH_OTP_BASE, FLASH_OTP_SIZE, FLASH_DATA, YES, NO ); // OTP
SET_REGION( 3, SRAM1_BASE_S, SIZE_2496K, SRAM, YES, NO ); // SRAM1/2/3/5
SET_REGION( 4, GFXMMU_BUFFERS_S, SIZE_16M, SRAM, YES, NO ); // Frame buffer
SET_REGION( 5, PERIPH_BASE_S, SIZE_256M, PERIPHERAL, YES, NO ); // Peripherals
SET_REGION( 6, FLASH_OTP_BASE, FLASH_OTP_SIZE, FLASH_DATA, YES, NO ); // OTP
DIS_REGION( 7 );
// clang-format on
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
}
Expand All @@ -164,11 +163,11 @@ void mpu_config_firmware() {
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
SET_REGION( 0, FLASH_BASE_S + SIZE_192K, SIZE_128K, FLASH_DATA, YES, YES ); // Storage
SET_REGION( 1, FLASH_BASE_S + SIZE_320K, SIZE_3776K, FLASH_CODE, NO, YES ); // Firmware
SET_REGION( 2, SRAM1_BASE_S, SIZE_768K, SRAM, YES, YES ); // SRAM1
SET_REGION( 3, SRAM2_BASE_S + 0x100, SIZE_1728K - 0x100, SRAM, YES, YES ); // SRAM2/3/5 + stack guard
SET_REGION( 4, GFXMMU_BUFFERS_S, SIZE_16M, SRAM, YES, YES ); // Frame buffer
SET_REGION( 5, PERIPH_BASE_S, SIZE_256M, PERIPHERAL, YES, YES ); // Peripherals
SET_REGION( 6, FLASH_OTP_BASE, FLASH_OTP_SIZE, FLASH_DATA, YES, YES ); // OTP
SET_REGION( 2, SRAM1_BASE_S, SIZE_2496K, SRAM, YES, YES ); // SRAM1/2/3/5
SET_REGION( 3, GFXMMU_BUFFERS_S, SIZE_16M, SRAM, YES, YES ); // Frame buffer
SET_REGION( 4, PERIPH_BASE_S, SIZE_256M, PERIPHERAL, YES, YES ); // Peripherals
SET_REGION( 5, FLASH_OTP_BASE, FLASH_OTP_SIZE, FLASH_DATA, YES, YES ); // OTP
DIS_REGION( 6 );
DIS_REGION( 7 );
// clang-format on
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
Expand Down
Loading

0 comments on commit 5964132

Please sign in to comment.