firmware: use OTP block 3 for storing randomness

pull/25/head
Pavol Rusnak 5 years ago
parent 7e3673ad26
commit ee3e313230
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D

@ -187,11 +187,9 @@ secbool load_vendor_header_keys(const uint8_t * const data, vendor_header * cons
return load_vendor_header(data, BOOTLOADER_KEY_M, BOOTLOADER_KEY_N, BOOTLOADER_KEYS, vhdr);
}
#define OTP_BLOCK_VENDOR_KEYS_LOCK 2
static secbool check_vendor_keys_lock(const vendor_header * const vhdr) {
uint8_t lock[FLASH_OTP_BLOCK_SIZE];
ensure(flash_otp_read(OTP_BLOCK_VENDOR_KEYS_LOCK, 0, lock, FLASH_OTP_BLOCK_SIZE), NULL);
ensure(flash_otp_read(FLASH_OTP_BLOCK_VENDOR_KEYS_LOCK, 0, lock, FLASH_OTP_BLOCK_SIZE), NULL);
if (0 == memcmp(lock, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", FLASH_OTP_BLOCK_SIZE)) {
return sectrue;
}
@ -204,8 +202,6 @@ static secbool check_vendor_keys_lock(const vendor_header * const vhdr) {
#if PRODUCTION
#define OTP_BLOCK_BOOTLOADER_VERSION 1
static void check_bootloader_version(void)
{
uint8_t bits[FLASH_OTP_BLOCK_SIZE];
@ -216,10 +212,10 @@ static void check_bootloader_version(void)
bits[i / 8] |= (1 << (7 - (i % 8)));
}
}
ensure(flash_otp_write(OTP_BLOCK_BOOTLOADER_VERSION, 0, bits, FLASH_OTP_BLOCK_SIZE), NULL);
ensure(flash_otp_write(FLASH_OTP_BLOCK_BOOTLOADER_VERSION, 0, bits, FLASH_OTP_BLOCK_SIZE), NULL);
uint8_t bits2[FLASH_OTP_BLOCK_SIZE];
ensure(flash_otp_read(OTP_BLOCK_BOOTLOADER_VERSION, 0, bits2, FLASH_OTP_BLOCK_SIZE), NULL);
ensure(flash_otp_read(FLASH_OTP_BLOCK_BOOTLOADER_VERSION, 0, bits2, FLASH_OTP_BLOCK_SIZE), NULL);
ensure(sectrue * (0 == memcmp(bits, bits2, FLASH_OTP_BLOCK_SIZE)), "Bootloader downgraded");
}

@ -89,7 +89,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_FlashOTP_lock_obj, mod_trezorio_Fl
/// '''
STATIC mp_obj_t mod_trezorio_FlashOTP_is_locked(mp_obj_t self, mp_obj_t block) {
uint8_t b = trezor_obj_get_uint8(block);
return flash_otp_is_locked(b) ? mp_const_true : mp_const_false;
return (sectrue == flash_otp_is_locked(b)) ? mp_const_true : mp_const_false;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_FlashOTP_is_locked_obj, mod_trezorio_FlashOTP_is_locked);

@ -328,7 +328,7 @@ static void test_otp_read(void)
{
uint8_t data[32];
memzero(data, sizeof(data));
ensure(flash_otp_read(0, 0, data, sizeof(data)), NULL);
ensure(flash_otp_read(FLASH_OTP_BLOCK_BATCH, 0, data, sizeof(data)), NULL);
// strip trailing 0xFF
for (size_t i = 0; i < sizeof(data); i++) {
@ -351,7 +351,7 @@ static void test_otp_write(const char *args)
char data[32];
memzero(data, sizeof(data));
strncpy(data, args, sizeof(data) - 1);
ensure(flash_otp_write(0, 0, (const uint8_t *) data, sizeof(data)), NULL);
ensure(flash_otp_write(FLASH_OTP_BLOCK_BATCH, 0, (const uint8_t *) data, sizeof(data)), NULL);
ensure(flash_otp_lock(0), NULL);
vcp_printf("OK");
}
@ -376,7 +376,7 @@ int main(void)
char dom[32];
// format: TREZOR2-YYMMDD
if (sectrue == flash_otp_read(0, 0, (uint8_t *)dom, 32) && 0 == memcmp(dom, "TREZOR2-", 8) && dom[31] == 0) {
if (sectrue == flash_otp_read(FLASH_OTP_BLOCK_BATCH, 0, (uint8_t *)dom, 32) && 0 == memcmp(dom, "TREZOR2-", 8) && dom[31] == 0) {
display_qrcode(DISPLAY_RESX / 2, DISPLAY_RESY / 2, dom, strlen(dom), 4);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 30, dom + 8, -1, FONT_BOLD, COLOR_WHITE, COLOR_BLACK);
}

@ -24,6 +24,8 @@
#include "common.h"
#include "display.h"
#include "rng.h"
#include "rand.h"
#include "flash.h"
#include "stm32f4xx_ll_utils.h"
@ -136,10 +138,20 @@ uint8_t HW_ENTROPY_DATA[HW_ENTROPY_LEN];
void collect_hw_entropy(void)
{
// collect entropy from UUID
uint32_t w = LL_GetUID_Word0();
memcpy(HW_ENTROPY_DATA, &w, 4);
w = LL_GetUID_Word1();
memcpy(HW_ENTROPY_DATA + 4, &w, 4);
w = LL_GetUID_Word2();
memcpy(HW_ENTROPY_DATA + 8, &w, 4);
// set entropy in the OTP randomness block
if (secfalse == flash_otp_is_locked(FLASH_OTP_BLOCK_RANDOMNESS)) {
uint8_t entropy[FLASH_OTP_BLOCK_SIZE];
random_buffer(entropy, FLASH_OTP_BLOCK_SIZE);
ensure(flash_otp_write(FLASH_OTP_BLOCK_RANDOMNESS, 0, entropy, FLASH_OTP_BLOCK_SIZE), NULL);
}
// collect entropy from OTP randomness block
ensure(flash_otp_read(FLASH_OTP_BLOCK_RANDOMNESS, 0, HW_ENTROPY_DATA + 12, FLASH_OTP_BLOCK_SIZE), NULL);
}

@ -45,7 +45,7 @@ void clear_otg_hs_memory(void);
extern uint32_t __stack_chk_guard;
void collect_hw_entropy(void);
#define HW_ENTROPY_LEN 12
#define HW_ENTROPY_LEN (12 + 32)
extern uint8_t HW_ENTROPY_DATA[HW_ENTROPY_LEN];
// the following functions are defined in util.s

@ -197,5 +197,5 @@ secbool flash_otp_lock(uint8_t block)
secbool flash_otp_is_locked(uint8_t block)
{
return *(__IO uint8_t *)(FLASH_OTP_LOCK_BASE + block) == 0x00;
return sectrue * (0x00 == *(__IO uint8_t *)(FLASH_OTP_LOCK_BASE + block));
}

@ -82,6 +82,12 @@ secbool __wur flash_write_word(uint8_t sector, uint32_t offset, uint32_t data);
#define FLASH_OTP_NUM_BLOCKS 16
#define FLASH_OTP_BLOCK_SIZE 32
// OTP blocks allocation
#define FLASH_OTP_BLOCK_BATCH 0
#define FLASH_OTP_BLOCK_BOOTLOADER_VERSION 1
#define FLASH_OTP_BLOCK_VENDOR_KEYS_LOCK 2
#define FLASH_OTP_BLOCK_RANDOMNESS 3
secbool __wur flash_otp_read(uint8_t block, uint8_t offset, uint8_t *data, uint8_t datalen);
secbool __wur flash_otp_write(uint8_t block, uint8_t offset, const uint8_t *data, uint8_t datalen);
secbool __wur flash_otp_lock(uint8_t block);

@ -41,7 +41,7 @@ void __attribute__((noreturn)) error_shutdown(const char *line1, const char *lin
void hal_delay(uint32_t ms);
void collect_hw_entropy(void);
#define HW_ENTROPY_LEN 12
#define HW_ENTROPY_LEN (12 + 32)
extern uint8_t HW_ENTROPY_DATA[HW_ENTROPY_LEN];
#endif

Loading…
Cancel
Save