diff --git a/legacy/intermediate_fw/trezor.c b/legacy/intermediate_fw/trezor.c index d9f777de5..b6190ac1a 100644 --- a/legacy/intermediate_fw/trezor.c +++ b/legacy/intermediate_fw/trezor.c @@ -20,18 +20,28 @@ #include "trezor.h" #include #include +#include #include #include "bitmaps.h" #include "bl_check.h" #include "layout.h" #include "memory.h" #include "memzero.h" +#include "norcow_config.h" #include "oled.h" #include "rng.h" #include "setup.h" #include "timer.h" #include "util.h" +// legacy storage magic +#define LEGACY_STORAGE_SECTOR 2 +static const uint32_t META_MAGIC_V10 = 0x525a5254; // 'TRZR' + +// norcow storage magic +static const uint32_t NORCOW_MAGIC = 0x3243524e; // 'NRC2' +static const uint8_t norcow_sectors[NORCOW_SECTOR_COUNT] = NORCOW_SECTORS; + /** Sector erase operation extracted from libopencm3 - flash_erase_sector * so it can run from RAM */ @@ -61,22 +71,14 @@ erase_sector(uint8_t sector, uint32_t psize) { FLASH_CR &= ~(FLASH_CR_SNB_MASK << FLASH_CR_SNB_SHIFT); } -static void __attribute__((noinline, section(".data"))) -erase_firmware_and_storage(void) { +static void __attribute__((noinline, section(".data"))) erase_firmware(void) { // Flash unlock FLASH_KEYR = FLASH_KEYR_KEY1; FLASH_KEYR = FLASH_KEYR_KEY2; - // Erase storage sectors to prevent firmware downgrade to vulnerable version - for (int i = FLASH_STORAGE_SECTOR_FIRST; i <= FLASH_STORAGE_SECTOR_LAST; - i++) { - erase_sector(i, FLASH_CR_PROGRAM_X32); - } - - // Erase firmware sectors - for (int i = FLASH_CODE_SECTOR_FIRST; i <= FLASH_CODE_SECTOR_LAST; i++) { - erase_sector(i, FLASH_CR_PROGRAM_X32); - } + // Erase the first firmware sector + // (we don't need full erasure, this speeds up the process) + erase_sector(FLASH_CODE_SECTOR_FIRST, FLASH_CR_PROGRAM_X32); // Flash lock FLASH_CR |= FLASH_CR_LOCK; @@ -91,8 +93,8 @@ void __attribute__((noinline, noreturn, section(".data"))) reboot_device(void) { /** Entry point of RAM shim that deletes old FW, storage and reboot */ void __attribute__((noinline, noreturn, section(".data"))) -erase_fw_and_reboot(void) { - erase_firmware_and_storage(); +erase_firmware_and_reboot(void) { + erase_firmware(); reboot_device(); for (;;) @@ -114,12 +116,33 @@ int main(void) { timer_init(); check_and_replace_bootloader(false); - layoutDialog(&bmp_icon_warning, NULL, NULL, NULL, "Erasing old data", NULL, - NULL, "DO NOT UNPLUG", "YOUR TREZOR!", NULL); - oledRefresh(); + secbool storage_initialized = secfalse; - // from this point the execution is from RAM instead of flash - erase_fw_and_reboot(); + // check legacy storage + uint32_t *magic = (uint32_t *)flash_get_address(LEGACY_STORAGE_SECTOR, 0, + sizeof(META_MAGIC_V10)); + if (*magic == META_MAGIC_V10) { + storage_initialized = sectrue; + } + + if (storage_initialized == secfalse) { + // check norcow storage + for (uint8_t i = 0; i < NORCOW_SECTOR_COUNT; i++) { + magic = (uint32_t *)flash_get_address(norcow_sectors[i], 0, + sizeof(NORCOW_MAGIC)); + if (*magic == NORCOW_MAGIC) { + storage_initialized = sectrue; + break; + } + } + } + + if (sectrue == storage_initialized) { + // don't erase + reboot_device(); + } else { + erase_firmware_and_reboot(); + } return 0; }