mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-23 06:48:16 +00:00
bootloader: cleanup ui code
This commit is contained in:
parent
5e476b856e
commit
1a32e46e5d
@ -25,7 +25,7 @@
|
|||||||
#define ICON_UPDATE 1
|
#define ICON_UPDATE 1
|
||||||
#define ICON_WIPE 2
|
#define ICON_WIPE 2
|
||||||
|
|
||||||
void display_header(int icon, const char *text)
|
static void display_header(int icon, const char *text)
|
||||||
{
|
{
|
||||||
display_bar(0, 0, DISPLAY_RESX, 32, COLOR_BL_ORANGE);
|
display_bar(0, 0, DISPLAY_RESX, 32, COLOR_BL_ORANGE);
|
||||||
switch (icon) {
|
switch (icon) {
|
||||||
@ -42,37 +42,33 @@ void display_header(int icon, const char *text)
|
|||||||
display_text(8 + 24 + 8, 23, text, -1, FONT_BOLD, COLOR_BLACK, COLOR_BL_ORANGE);
|
display_text(8 + 24 + 8, 23, text, -1, FONT_BOLD, COLOR_BLACK, COLOR_BL_ORANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_footer(const char *text, uint16_t color)
|
static void display_footer(const char *text, uint16_t color, int bottom)
|
||||||
{
|
{
|
||||||
display_bar(0, 184, DISPLAY_RESX, 56, COLOR_BLACK);
|
display_bar(0, DISPLAY_RESY - bottom - 24, DISPLAY_RESX, bottom + 24, COLOR_BLACK);
|
||||||
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 20, text, -1, FONT_BOLD, color, COLOR_BLACK);
|
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - bottom, text, -1, FONT_BOLD, color, COLOR_BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_done(int restart)
|
static void display_done(int restart)
|
||||||
{
|
{
|
||||||
if (restart == 0 || restart == 3) {
|
if (restart == 0 || restart == 3) {
|
||||||
display_loader(1000, 0, COLOR_BL_GREEN, COLOR_BLACK, toi_icon_tick, sizeof(toi_icon_tick), COLOR_WHITE);
|
display_loader(1000, 0, COLOR_BL_GREEN, COLOR_BLACK, toi_icon_tick, sizeof(toi_icon_tick), COLOR_WHITE);
|
||||||
}
|
}
|
||||||
if (restart == 3) {
|
if (restart <= 3 && restart >= 1) {
|
||||||
display_footer("Done! Restarting in 3s", COLOR_BL_GREEN);
|
char count_str[24];
|
||||||
} else
|
mini_snprintf(count_str, sizeof(count_str), "Done! Restarting in %ds", restart);
|
||||||
if (restart == 2) {
|
display_footer(count_str, COLOR_BL_GREEN, 20);
|
||||||
display_footer("Done! Restarting in 2s", COLOR_BL_GREEN);
|
|
||||||
} else
|
|
||||||
if (restart == 1) {
|
|
||||||
display_footer("Done! Restarting in 1s", COLOR_BL_GREEN);
|
|
||||||
} else {
|
} else {
|
||||||
display_footer("Done! Unplug the device", COLOR_BL_GREEN);
|
display_footer("Done! Unplug the device", COLOR_BL_GREEN, 20);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_error(void)
|
static void display_error(void)
|
||||||
{
|
{
|
||||||
display_loader(1000, 0, COLOR_BL_RED, COLOR_BLACK, toi_icon_cross, sizeof(toi_icon_cross), COLOR_WHITE);
|
display_loader(1000, 0, COLOR_BL_RED, COLOR_BLACK, toi_icon_cross, sizeof(toi_icon_cross), COLOR_WHITE);
|
||||||
display_footer("Error! Unplug the device", COLOR_BL_RED);
|
display_footer("Error! Unplug the device", COLOR_BL_RED, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_welcome(secbool firmware_present)
|
static void display_welcome(secbool firmware_present)
|
||||||
{
|
{
|
||||||
display_clear();
|
display_clear();
|
||||||
if (secfalse == firmware_present) {
|
if (secfalse == firmware_present) {
|
||||||
@ -89,7 +85,7 @@ void display_welcome(secbool firmware_present)
|
|||||||
#define VENDOR_IMAGE_RESX 120
|
#define VENDOR_IMAGE_RESX 120
|
||||||
#define VENDOR_IMAGE_RESY 120
|
#define VENDOR_IMAGE_RESY 120
|
||||||
|
|
||||||
void display_vendor(const uint8_t *vimg, const char *vstr, uint32_t vstr_len, uint32_t fw_version, char red_background)
|
static void display_vendor(const uint8_t *vimg, const char *vstr, uint32_t vstr_len, uint32_t fw_version, char red_background)
|
||||||
{
|
{
|
||||||
if (red_background) {
|
if (red_background) {
|
||||||
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_BL_RED);
|
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_BL_RED);
|
||||||
@ -132,7 +128,7 @@ static const uint8_t * const BOOTLOADER_KEYS[] = {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void usb_init_all(void) {
|
static void usb_init_all(void) {
|
||||||
static const usb_dev_info_t dev_info = {
|
static const usb_dev_info_t dev_info = {
|
||||||
.vendor_id = 0x1209,
|
.vendor_id = 0x1209,
|
||||||
.product_id = 0x53C0,
|
.product_id = 0x53C0,
|
||||||
@ -178,7 +174,7 @@ void usb_init_all(void) {
|
|||||||
usb_start();
|
usb_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
secbool bootloader_loop(secbool firmware_present)
|
static secbool bootloader_loop(secbool firmware_present)
|
||||||
{
|
{
|
||||||
usb_init_all();
|
usb_init_all();
|
||||||
|
|
||||||
@ -209,7 +205,7 @@ secbool bootloader_loop(secbool firmware_present)
|
|||||||
display_fade(BACKLIGHT_NORMAL, 0, 100);
|
display_fade(BACKLIGHT_NORMAL, 0, 100);
|
||||||
display_clear();
|
display_clear();
|
||||||
display_header(ICON_WIPE, "Wiping Device");
|
display_header(ICON_WIPE, "Wiping Device");
|
||||||
display_footer("Please wait ...", COLOR_WHITE);
|
display_footer("Please wait ...", COLOR_WHITE, 20);
|
||||||
display_fade(0, BACKLIGHT_NORMAL, 100);
|
display_fade(0, BACKLIGHT_NORMAL, 100);
|
||||||
r = process_msg_WipeDevice(USB_IFACE_NUM, msg_size, buf);
|
r = process_msg_WipeDevice(USB_IFACE_NUM, msg_size, buf);
|
||||||
if (r < 0) { // error
|
if (r < 0) { // error
|
||||||
@ -228,7 +224,7 @@ secbool bootloader_loop(secbool firmware_present)
|
|||||||
display_fade(BACKLIGHT_NORMAL, 0, 100);
|
display_fade(BACKLIGHT_NORMAL, 0, 100);
|
||||||
display_clear();
|
display_clear();
|
||||||
display_header(ICON_UPDATE, "Updating Firmware");
|
display_header(ICON_UPDATE, "Updating Firmware");
|
||||||
display_footer("Please wait ...", COLOR_WHITE);
|
display_footer("Please wait ...", COLOR_WHITE, 20);
|
||||||
display_fade(0, BACKLIGHT_NORMAL, 100);
|
display_fade(0, BACKLIGHT_NORMAL, 100);
|
||||||
process_msg_FirmwareErase(USB_IFACE_NUM, msg_size, buf);
|
process_msg_FirmwareErase(USB_IFACE_NUM, msg_size, buf);
|
||||||
break;
|
break;
|
||||||
@ -257,11 +253,31 @@ secbool bootloader_loop(secbool firmware_present)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
secbool load_vendor_header_keys(const uint8_t * const data, vendor_header * const vhdr)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
uint8_t hash[32];
|
||||||
|
vendor_keys_hash(vhdr, hash);
|
||||||
|
return sectrue * (0 == memcmp(lock, hash, 32));
|
||||||
|
}
|
||||||
|
|
||||||
// protection against bootloader downgrade
|
// protection against bootloader downgrade
|
||||||
|
|
||||||
|
#if PRODUCTION
|
||||||
|
|
||||||
#define OTP_BLOCK_BOOTLOADER_VERSION 1
|
#define OTP_BLOCK_BOOTLOADER_VERSION 1
|
||||||
|
|
||||||
void check_bootloader_version(void)
|
static void check_bootloader_version(void)
|
||||||
{
|
{
|
||||||
uint8_t bits[FLASH_OTP_BLOCK_SIZE];
|
uint8_t bits[FLASH_OTP_BLOCK_SIZE];
|
||||||
for (int i = 0; i < FLASH_OTP_BLOCK_SIZE * 8; i++) {
|
for (int i = 0; i < FLASH_OTP_BLOCK_SIZE * 8; i++) {
|
||||||
@ -279,23 +295,7 @@ void check_bootloader_version(void)
|
|||||||
ensure(sectrue * (0 == memcmp(bits, bits2, FLASH_OTP_BLOCK_SIZE)), "Bootloader downgraded");
|
ensure(sectrue * (0 == memcmp(bits, bits2, FLASH_OTP_BLOCK_SIZE)), "Bootloader downgraded");
|
||||||
}
|
}
|
||||||
|
|
||||||
secbool load_vendor_header_keys(const uint8_t * const data, vendor_header * const vhdr)
|
#endif
|
||||||
{
|
|
||||||
return load_vendor_header(data, BOOTLOADER_KEY_M, BOOTLOADER_KEY_N, BOOTLOADER_KEYS, vhdr);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define OTP_BLOCK_VENDOR_KEYS_LOCK 2
|
|
||||||
|
|
||||||
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);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
uint8_t hash[32];
|
|
||||||
vendor_keys_hash(vhdr, hash);
|
|
||||||
return sectrue * (0 == memcmp(lock, hash, 32));
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
@ -358,23 +358,20 @@ int main(void)
|
|||||||
check_image_contents(&hdr, IMAGE_HEADER_SIZE + vhdr.hdrlen, sectors, 13),
|
check_image_contents(&hdr, IMAGE_HEADER_SIZE + vhdr.hdrlen, sectors, 13),
|
||||||
"invalid firmware hash");
|
"invalid firmware hash");
|
||||||
|
|
||||||
display_vendor(vhdr.vimg, (const char *)vhdr.vstr, vhdr.vstr_len, hdr.version, (vhdr.vtrust & 0x0010) == 0);
|
display_vendor(vhdr.vimg, (const char *)vhdr.vstr, vhdr.vstr_len, hdr.version, (vhdr.vtrust & VTRUST_RED) == 0);
|
||||||
display_fade(0, BACKLIGHT_NORMAL, 1000);
|
display_fade(0, BACKLIGHT_NORMAL, 1000);
|
||||||
|
|
||||||
if ((vhdr.vtrust & 0x0001) == 0) {
|
int start_delay = (vhdr.vtrust & VTRUST_WAIT) ^ VTRUST_WAIT;
|
||||||
|
while (start_delay > 0) {
|
||||||
|
char wait_str[16];
|
||||||
|
mini_snprintf(wait_str, sizeof(wait_str), "waiting for %ds", start_delay);
|
||||||
|
display_footer(wait_str, COLOR_GRAY64, 2);
|
||||||
hal_delay(1000);
|
hal_delay(1000);
|
||||||
|
start_delay--;
|
||||||
}
|
}
|
||||||
if ((vhdr.vtrust & 0x0002) == 0) {
|
|
||||||
hal_delay(2000);
|
if ((vhdr.vtrust & VTRUST_CLICK) == 0) {
|
||||||
}
|
display_footer("click to continue ...", COLOR_GRAY64, 2);
|
||||||
if ((vhdr.vtrust & 0x0004) == 0) {
|
|
||||||
hal_delay(4000);
|
|
||||||
}
|
|
||||||
if ((vhdr.vtrust & 0x0008) == 0) {
|
|
||||||
hal_delay(8000);
|
|
||||||
}
|
|
||||||
if ((vhdr.vtrust & 0x0020) == 0) {
|
|
||||||
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 2, "click to continue ...", -1, FONT_BOLD, COLOR_GRAY64, COLOR_BLACK);
|
|
||||||
touch_click();
|
touch_click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,10 @@ typedef struct {
|
|||||||
|
|
||||||
#define MAX_VENDOR_PUBLIC_KEYS 8
|
#define MAX_VENDOR_PUBLIC_KEYS 8
|
||||||
|
|
||||||
|
#define VTRUST_WAIT 0x000F
|
||||||
|
#define VTRUST_RED 0x0010
|
||||||
|
#define VTRUST_CLICK 0x0020
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
uint32_t hdrlen;
|
uint32_t hdrlen;
|
||||||
|
Loading…
Reference in New Issue
Block a user