mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-10 23:40:58 +00:00
fix(legacy): don't erase firmware and storage in intermediate firmware
if the storage has been already initialized
This commit is contained in:
parent
e09a74a79e
commit
0c46b79ebf
@ -20,18 +20,28 @@
|
|||||||
#include "trezor.h"
|
#include "trezor.h"
|
||||||
#include <libopencm3/stm32/desig.h>
|
#include <libopencm3/stm32/desig.h>
|
||||||
#include <libopencm3/stm32/flash.h>
|
#include <libopencm3/stm32/flash.h>
|
||||||
|
#include <string.h>
|
||||||
#include <vendor/libopencm3/include/libopencmsis/core_cm3.h>
|
#include <vendor/libopencm3/include/libopencmsis/core_cm3.h>
|
||||||
#include "bitmaps.h"
|
#include "bitmaps.h"
|
||||||
#include "bl_check.h"
|
#include "bl_check.h"
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "memzero.h"
|
#include "memzero.h"
|
||||||
|
#include "norcow_config.h"
|
||||||
#include "oled.h"
|
#include "oled.h"
|
||||||
#include "rng.h"
|
#include "rng.h"
|
||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "util.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
|
/** Sector erase operation extracted from libopencm3 - flash_erase_sector
|
||||||
* so it can run from RAM
|
* 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);
|
FLASH_CR &= ~(FLASH_CR_SNB_MASK << FLASH_CR_SNB_SHIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((noinline, section(".data")))
|
static void __attribute__((noinline, section(".data"))) erase_firmware(void) {
|
||||||
erase_firmware_and_storage(void) {
|
|
||||||
// Flash unlock
|
// Flash unlock
|
||||||
FLASH_KEYR = FLASH_KEYR_KEY1;
|
FLASH_KEYR = FLASH_KEYR_KEY1;
|
||||||
FLASH_KEYR = FLASH_KEYR_KEY2;
|
FLASH_KEYR = FLASH_KEYR_KEY2;
|
||||||
|
|
||||||
// Erase storage sectors to prevent firmware downgrade to vulnerable version
|
// Erase the first firmware sector
|
||||||
for (int i = FLASH_STORAGE_SECTOR_FIRST; i <= FLASH_STORAGE_SECTOR_LAST;
|
// (we don't need full erasure, this speeds up the process)
|
||||||
i++) {
|
erase_sector(FLASH_CODE_SECTOR_FIRST, FLASH_CR_PROGRAM_X32);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flash lock
|
// Flash lock
|
||||||
FLASH_CR |= FLASH_CR_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 */
|
/** Entry point of RAM shim that deletes old FW, storage and reboot */
|
||||||
void __attribute__((noinline, noreturn, section(".data")))
|
void __attribute__((noinline, noreturn, section(".data")))
|
||||||
erase_fw_and_reboot(void) {
|
erase_firmware_and_reboot(void) {
|
||||||
erase_firmware_and_storage();
|
erase_firmware();
|
||||||
reboot_device();
|
reboot_device();
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
@ -114,12 +116,33 @@ int main(void) {
|
|||||||
timer_init();
|
timer_init();
|
||||||
check_and_replace_bootloader(false);
|
check_and_replace_bootloader(false);
|
||||||
|
|
||||||
layoutDialog(&bmp_icon_warning, NULL, NULL, NULL, "Erasing old data", NULL,
|
secbool storage_initialized = secfalse;
|
||||||
NULL, "DO NOT UNPLUG", "YOUR TREZOR!", NULL);
|
|
||||||
oledRefresh();
|
|
||||||
|
|
||||||
// from this point the execution is from RAM instead of flash
|
// check legacy storage
|
||||||
erase_fw_and_reboot();
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user