diff --git a/embed/boardloader/main.c b/embed/boardloader/main.c index 8cab160e8..dc9a512f1 100644 --- a/embed/boardloader/main.c +++ b/embed/boardloader/main.c @@ -144,6 +144,10 @@ int main(void) { __stack_chk_guard = rng_get(); +#if PRODUCTION + flash_set_option_bytes(); +#endif + clear_otg_hs_memory(); periph_init(); diff --git a/embed/bootloader/main.c b/embed/bootloader/main.c index 7643dcc87..e76787a0e 100644 --- a/embed/bootloader/main.c +++ b/embed/bootloader/main.c @@ -176,10 +176,36 @@ void mainloop(void) } } +// protection against bootloader downgrade + +#define BOOTLOADER_VERSION_OTP_BLOCK 1 + +void check_bootloader_version(void) +{ + uint8_t bits[FLASH_OTP_BLOCK_SIZE]; + for (int i = 0; i < FLASH_OTP_BLOCK_SIZE * 8; i++) { + if (i < VERSION_MONOTONIC) { + bits[i / 8] &= ~(1 << (7 - (i % 8))); + } else { + bits[i / 8] |= (1 << (7 - (i % 8))); + } + } + trassert(true == flash_otp_write(BOOTLOADER_VERSION_OTP_BLOCK, 0, bits, FLASH_OTP_BLOCK_SIZE), NULL); + + uint8_t bits2[FLASH_OTP_BLOCK_SIZE]; + trassert(true == flash_otp_read(BOOTLOADER_VERSION_OTP_BLOCK, 0, bits2, FLASH_OTP_BLOCK_SIZE), NULL); + + trassert(0 == memcmp(bits, bits2, FLASH_OTP_BLOCK_SIZE), "Bootloader downgraded"); +} + int main(void) { __stack_chk_guard = rng_get(); +#if PRODUCTION + check_bootloader_version(); +#endif + periph_init(); display_pwm_init(); diff --git a/embed/bootloader/version.h b/embed/bootloader/version.h index a62341fe9..c30364ead 100644 --- a/embed/bootloader/version.h +++ b/embed/bootloader/version.h @@ -2,3 +2,5 @@ #define VERSION_MINOR 1 #define VERSION_PATCH 0 #define VERSION_BUILD 0 + +#define VERSION_MONOTONIC 1 diff --git a/embed/trezorhal/flash.c b/embed/trezorhal/flash.c index ea9560b3b..ad1b180aa 100644 --- a/embed/trezorhal/flash.c +++ b/embed/trezorhal/flash.c @@ -56,8 +56,6 @@ bool flash_write_word(uint32_t address, uint32_t data) } #define FLASH_OTP_LOCK_BASE 0x1FFF7A00U -#define FLASH_OTP_NUM_BLOCKS 16 -#define FLASH_OTP_BLOCK_SIZE 32 bool flash_otp_read(uint8_t block, uint8_t offset, uint8_t *data, uint8_t datalen) { diff --git a/embed/trezorhal/flash.h b/embed/trezorhal/flash.h index 085368cc8..94ffb898d 100644 --- a/embed/trezorhal/flash.h +++ b/embed/trezorhal/flash.h @@ -24,6 +24,9 @@ bool flash_erase_sectors(int start, int end, void (*progress)(uint16_t val)); bool flash_write_byte(uint32_t address, uint8_t data); bool flash_write_word(uint32_t address, uint32_t data); +#define FLASH_OTP_NUM_BLOCKS 16 +#define FLASH_OTP_BLOCK_SIZE 32 + bool flash_otp_read(uint8_t block, uint8_t offset, uint8_t *data, uint8_t datalen); bool flash_otp_write(uint8_t block, uint8_t offset, const uint8_t *data, uint8_t datalen); bool flash_otp_lock(uint8_t block);