From 8ebb8c2128eb6b2fcb4d7228b7100f842f43e940 Mon Sep 17 00:00:00 2001 From: tychovrahe Date: Fri, 3 May 2024 13:49:48 +0200 Subject: [PATCH] fix(core): fix prodtest WIPE on STM32U5 [no changelog] --- core/embed/prodtest/main.c | 9 +-------- core/embed/trezorhal/common.h | 4 ++++ core/embed/trezorhal/stm32f4/common.c | 11 +++++++++++ core/embed/trezorhal/stm32u5/common.c | 15 +++++++++++++++ core/embed/trezorhal/stm32u5/mpu.c | 2 +- 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/core/embed/prodtest/main.c b/core/embed/prodtest/main.c index 986e7c850f..3495432bb4 100644 --- a/core/embed/prodtest/main.c +++ b/core/embed/prodtest/main.c @@ -459,14 +459,7 @@ static void test_firmware_version(void) { } static void test_wipe(void) { - // erase start of the firmware (metadata) -> invalidate FW - ensure(flash_unlock_write(), NULL); - for (int i = 0; i < (1024 / FLASH_BLOCK_SIZE); i += FLASH_BLOCK_SIZE) { - flash_block_t data = {0}; - ensure(flash_area_write_block(&FIRMWARE_AREA, i * FLASH_BLOCK_SIZE, data), - NULL); - } - ensure(flash_lock_write(), NULL); + invalidate_firmware(); display_clear(); display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY / 2 + 10, "WIPED", -1, FONT_BOLD, COLOR_WHITE, COLOR_BLACK); diff --git a/core/embed/trezorhal/common.h b/core/embed/trezorhal/common.h index cb871b8d1b..28464b0270 100644 --- a/core/embed/trezorhal/common.h +++ b/core/embed/trezorhal/common.h @@ -75,4 +75,8 @@ void collect_hw_entropy(void); #define HW_ENTROPY_LEN (12 + 32) extern uint8_t HW_ENTROPY_DATA[HW_ENTROPY_LEN]; +// Invalidates firmware on the device +// Note: only works when write access to firmware area is enabled by MPU +void invalidate_firmware(void); + #endif diff --git a/core/embed/trezorhal/stm32f4/common.c b/core/embed/trezorhal/stm32f4/common.c index 1c6d48f76f..4539211af2 100644 --- a/core/embed/trezorhal/stm32f4/common.c +++ b/core/embed/trezorhal/stm32f4/common.c @@ -234,3 +234,14 @@ void show_pin_too_many_screen(void) { error_uni("TOO MANY PIN ATTEMPTS", "All data has been erased from the device", "PLEASE RECONNECT\nTHE DEVICE"); } + +void invalidate_firmware(void) { + // erase start of the firmware (metadata) -> invalidate FW + ensure(flash_unlock_write(), NULL); + for (int i = 0; i < (1024 / FLASH_BLOCK_SIZE); i += FLASH_BLOCK_SIZE) { + flash_block_t data = {0}; + ensure(flash_area_write_block(&FIRMWARE_AREA, i * FLASH_BLOCK_SIZE, data), + NULL); + } + ensure(flash_lock_write(), NULL); +} diff --git a/core/embed/trezorhal/stm32u5/common.c b/core/embed/trezorhal/stm32u5/common.c index 6470005096..e7406df22e 100644 --- a/core/embed/trezorhal/stm32u5/common.c +++ b/core/embed/trezorhal/stm32u5/common.c @@ -210,3 +210,18 @@ void show_pin_too_many_screen(void) { error_uni("TOO MANY PIN ATTEMPTS", "All data has been erased from the device", "PLEASE RECONNECT\nTHE DEVICE"); } + +void invalidate_firmware(void) { + // on stm32u5, we need to disable the instruction cache before erasing the + // firmware - otherwise, the write check will fail + ICACHE->CR &= ~ICACHE_CR_EN; + + // erase start of the firmware (metadata) -> invalidate FW + ensure(flash_unlock_write(), NULL); + for (int i = 0; i < (1024 / FLASH_BLOCK_SIZE); i += FLASH_BLOCK_SIZE) { + flash_block_t data = {0}; + ensure(flash_area_write_block(&FIRMWARE_AREA, i * FLASH_BLOCK_SIZE, data), + NULL); + } + ensure(flash_lock_write(), NULL); +} diff --git a/core/embed/trezorhal/stm32u5/mpu.c b/core/embed/trezorhal/stm32u5/mpu.c index 733634777e..25c04d5e13 100644 --- a/core/embed/trezorhal/stm32u5/mpu.c +++ b/core/embed/trezorhal/stm32u5/mpu.c @@ -243,7 +243,7 @@ void mpu_config_prodtest(void) { // clang-format off // REGION ADDRESS SIZE TYPE WRITE UNPRIV SET_REGION( 0, STORAGE_START, STORAGE_SIZE, FLASH_DATA, YES, YES ); // Storage - SET_REGION( 1, FIRMWARE_START, FIRMWARE_SIZE, FLASH_CODE, NO, YES ); // Firmware + SET_REGION( 1, FIRMWARE_START, FIRMWARE_SIZE, FLASH_CODE, YES, YES ); // Firmware SET_REGION( 2, ASSETS_START, ASSETS_SIZE, FLASH_DATA, YES, YES ); // Assets SET_REGION( 3, SRAM1_BASE, SRAM_SIZE, SRAM, YES, YES ); // SRAM1/2/3/5 SET_REGION( 4, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, YES ); // Frame buffer or display interface