diff --git a/docs/bootloader.md b/docs/bootloader.md index a39e680a..c186265a 100644 --- a/docs/bootloader.md +++ b/docs/bootloader.md @@ -160,14 +160,3 @@ Total length of firmware header is always 1024 bytes. | 0x0220 | 415 | reserved | not used yet (zeroed) | | 0x03BF | 1 | sigmask | vendor signature indexes (bitmap) | | 0x03C0 | 64 | sig | vendor aggregated signature of the firmware header | - - -## Various ideas - -* Bootloader should be able to read vendor + firmware header and send info - about FW to client in features message. -* Bootloader should not try to run firmware if there is not any. -* Storage wiping rule: Don't erase storage when old FW and new FW are signed - using the same key set. Otherwise erase. -* Bootloader should send error to client when firmware update fails and allow - client to try one more time. This prevents storage area erasure by accident. diff --git a/embed/bootloader/main.c b/embed/bootloader/main.c index 932fc718..109a68b9 100644 --- a/embed/bootloader/main.c +++ b/embed/bootloader/main.c @@ -81,7 +81,7 @@ void display_welcome(secbool firmware_present) } if (sectrue == firmware_present) { display_header(ICON_TOOLS, "TREZOR Bootloader"); - // TODO: show info about installed firmware + // TODO: show info about installed firmware (vendor, version, etc.) } display_fade(0, BACKLIGHT_NORMAL, 1000); } diff --git a/embed/bootloader/messages.c b/embed/bootloader/messages.c index 2403a08f..bdf479fa 100644 --- a/embed/bootloader/messages.c +++ b/embed/bootloader/messages.c @@ -213,6 +213,7 @@ void process_msg_Initialize(uint8_t iface_num, uint32_t msg_size, uint8_t *buf, MSG_SEND_ASSIGN_VALUE(patch_version, VERSION_PATCH); MSG_SEND_ASSIGN_VALUE(bootloader_mode, true); MSG_SEND_ASSIGN_VALUE(firmware_present, firmware_present); + // TODO: pass info about installed firmware (vendor, version, etc.) MSG_SEND(Features); } @@ -325,8 +326,27 @@ secbool compare_to_current_vendor_header(const vendor_header * const new_vhdr) if (sectrue != load_vendor_header_keys((const uint8_t *)FIRMWARE_START, ¤t_vhdr)) { return secfalse; } - // TODO: less strict rules - return sectrue * (0 == memcmp(new_vhdr, ¤t_vhdr, sizeof(vendor_header))); + // check whether current and new vendor header have the same key set + if (new_vhdr->vsig_m != current_vhdr.vsig_m) { + return secfalse; + } + if (new_vhdr->vsig_n != current_vhdr.vsig_n) { + return secfalse; + } + for (int i = 0; i < MAX_VENDOR_PUBLIC_KEYS; i++) { + if (new_vhdr->vpub[i] != 0 && current_vhdr.vpub[i] != 0) { + if (0 != memcmp(new_vhdr->vpub[i], current_vhdr.vpub[i], 32)) { + return secfalse; + } + } + if (new_vhdr->vpub[i] == 0 && current_vhdr.vpub[i] != 0) { + return secfalse; + } + if (new_vhdr->vpub[i] != 0 && current_vhdr.vpub[i] == 0) { + return secfalse; + } + } + return sectrue; } int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)