From 336a41723327af12ba5a2f31468cbda107d1f34e Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Tue, 24 Mar 2020 17:53:08 +0000 Subject: [PATCH] core/bootloader: distinguish between a vendor change and downgrade with wipe --- core/embed/bootloader/bootui.c | 11 +++++++---- core/embed/bootloader/bootui.h | 5 +++-- core/embed/bootloader/messages.c | 13 +++++++++---- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/core/embed/bootloader/bootui.c b/core/embed/bootloader/bootui.c index 221b4d5614..783a7aeff0 100644 --- a/core/embed/bootloader/bootui.c +++ b/core/embed/bootloader/bootui.c @@ -229,11 +229,14 @@ void ui_screen_install_confirm_upgrade(const vendor_header *const vhdr, ui_confirm_cancel_buttons(); } -void ui_screen_install_confirm_newvendor(const vendor_header *const vhdr, - const image_header *const hdr) { +void ui_screen_install_confirm_newvendor_or_downgrade_wipe( + const vendor_header *const vhdr, const image_header *const hdr, + secbool downgrade_wipe) { display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE); - display_text(16, 32, "Vendor change", -1, FONT_NORMAL, COLOR_BLACK, - COLOR_WHITE); + display_text( + 16, 32, + (sectrue == downgrade_wipe) ? "Firmware downgrade" : "Vendor change", -1, + FONT_NORMAL, COLOR_BLACK, COLOR_WHITE); display_bar(16, 44, DISPLAY_RESX - 14 * 2, 1, COLOR_BLACK); display_icon(16, 54, 32, 32, toi_icon_info + 12, sizeof(toi_icon_info) - 12, COLOR_BLACK, COLOR_WHITE); diff --git a/core/embed/bootloader/bootui.h b/core/embed/bootloader/bootui.h index 6c61d759ce..4c07f9f17d 100644 --- a/core/embed/bootloader/bootui.h +++ b/core/embed/bootloader/bootui.h @@ -38,8 +38,9 @@ void ui_screen_info_fingerprint(const image_header* const hdr); void ui_screen_install_confirm_upgrade(const vendor_header* const vhdr, const image_header* const hdr); -void ui_screen_install_confirm_newvendor(const vendor_header* const vhdr, - const image_header* const hdr); +void ui_screen_install_confirm_newvendor_or_downgrade_wipe( + const vendor_header* const vhdr, const image_header* const hdr, + secbool downgrade_wipe); void ui_screen_install(void); void ui_screen_install_progress_erase(int pos, int len); void ui_screen_install_progress_upload(int pos); diff --git a/core/embed/bootloader/messages.c b/core/embed/bootloader/messages.c index 3cd408f057..06675c5a03 100644 --- a/core/embed/bootloader/messages.c +++ b/core/embed/bootloader/messages.c @@ -425,9 +425,11 @@ static void detect_installation(vendor_header *current_vhdr, image_header *current_hdr, const vendor_header *const new_vhdr, const image_header *const new_hdr, - secbool *is_new, secbool *is_upgrade) { + secbool *is_new, secbool *is_upgrade, + secbool *is_downgrade_wipe) { *is_new = secfalse; *is_upgrade = secfalse; + *is_downgrade_wipe = secfalse; if (sectrue != load_vendor_header_keys((const uint8_t *)FIRMWARE_START, current_vhdr)) { *is_new = sectrue; @@ -448,6 +450,7 @@ static void detect_installation(vendor_header *current_vhdr, return; } if (version_compare(new_hdr->version, current_hdr->fix_version) < 0) { + *is_downgrade_wipe = sectrue; return; } *is_upgrade = sectrue; @@ -473,6 +476,7 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, static image_header hdr; secbool is_upgrade = secfalse; + secbool is_downgrade_wipe = secfalse; if (firmware_block == 0) { if (headers_offset == 0) { @@ -500,7 +504,7 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, image_header current_hdr; secbool is_new = secfalse; detect_installation(¤t_vhdr, ¤t_hdr, &vhdr, &hdr, &is_new, - &is_upgrade); + &is_upgrade, &is_downgrade_wipe); int response = INPUT_CANCEL; if (sectrue == is_new) { @@ -513,9 +517,10 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, ui_fadein(); response = ui_user_input(INPUT_CONFIRM | INPUT_CANCEL); } else { - // new firmware vendor + // downgrade with wipe or new firmware vendor ui_fadeout(); - ui_screen_install_confirm_newvendor(&vhdr, &hdr); + ui_screen_install_confirm_newvendor_or_downgrade_wipe( + &vhdr, &hdr, is_downgrade_wipe); ui_fadein(); response = ui_user_input(INPUT_CONFIRM | INPUT_CANCEL); }