mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-26 17:38:39 +00:00
fix(core/bootloader): properly display upgrade/downgrade
This commit is contained in:
parent
d1d373a51f
commit
63c27bafd6
@ -179,30 +179,17 @@ uint32_t ui_screen_menu(void) { return screen_menu(); }
|
|||||||
|
|
||||||
// install UI
|
// install UI
|
||||||
|
|
||||||
uint32_t ui_screen_install_confirm_upgrade(const vendor_header *const vhdr,
|
uint32_t ui_screen_install_confirm(const vendor_header *const vhdr,
|
||||||
const image_header *const hdr) {
|
const image_header *const hdr,
|
||||||
|
secbool should_keep_seed,
|
||||||
|
secbool is_newvendor, int version_cmp) {
|
||||||
uint8_t fingerprint[32];
|
uint8_t fingerprint[32];
|
||||||
char ver_str[64];
|
char ver_str[64];
|
||||||
get_image_fingerprint(hdr, fingerprint);
|
get_image_fingerprint(hdr, fingerprint);
|
||||||
format_ver("%d.%d.%d", hdr->version, ver_str, sizeof(ver_str));
|
format_ver("%d.%d.%d", hdr->version, ver_str, sizeof(ver_str));
|
||||||
return screen_install_confirm(vhdr->vstr, vhdr->vstr_len, ver_str,
|
return screen_install_confirm(vhdr->vstr, vhdr->vstr_len, ver_str,
|
||||||
fingerprint, false, false);
|
fingerprint, should_keep_seed == sectrue,
|
||||||
}
|
is_newvendor == sectrue, version_cmp);
|
||||||
|
|
||||||
uint32_t ui_screen_install_confirm_newvendor_or_downgrade_wipe(
|
|
||||||
const vendor_header *const vhdr, const image_header *const hdr,
|
|
||||||
secbool downgrade_wipe) {
|
|
||||||
uint8_t fingerprint[32];
|
|
||||||
char ver_str[64];
|
|
||||||
get_image_fingerprint(hdr, fingerprint);
|
|
||||||
format_ver("%d.%d.%d", hdr->version, ver_str, sizeof(ver_str));
|
|
||||||
if (downgrade_wipe) {
|
|
||||||
return screen_install_confirm(vhdr->vstr, vhdr->vstr_len, ver_str,
|
|
||||||
fingerprint, true, false);
|
|
||||||
} else {
|
|
||||||
return screen_install_confirm(vhdr->vstr, vhdr->vstr_len, ver_str,
|
|
||||||
fingerprint, false, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui_screen_install_start() {
|
void ui_screen_install_start() {
|
||||||
|
@ -46,11 +46,10 @@ uint32_t ui_screen_intro(const vendor_header* const vhdr,
|
|||||||
|
|
||||||
uint32_t ui_screen_menu(void);
|
uint32_t ui_screen_menu(void);
|
||||||
|
|
||||||
uint32_t ui_screen_install_confirm_upgrade(const vendor_header* const vhdr,
|
uint32_t ui_screen_install_confirm(const vendor_header* const vhdr,
|
||||||
const image_header* const hdr);
|
const image_header* const hdr,
|
||||||
uint32_t ui_screen_install_confirm_newvendor_or_downgrade_wipe(
|
secbool shold_keep_seed,
|
||||||
const vendor_header* const vhdr, const image_header* const hdr,
|
secbool is_newvendor, int version_cmp);
|
||||||
secbool downgrade_wipe);
|
|
||||||
void ui_screen_install_start();
|
void ui_screen_install_start();
|
||||||
void ui_screen_install_progress_erase(int pos, int len);
|
void ui_screen_install_progress_erase(int pos, int len);
|
||||||
void ui_screen_install_progress_upload(int pos);
|
void ui_screen_install_progress_upload(int pos);
|
||||||
|
@ -432,10 +432,10 @@ static void detect_installation(const vendor_header *current_vhdr,
|
|||||||
const vendor_header *const new_vhdr,
|
const vendor_header *const new_vhdr,
|
||||||
const image_header *const new_hdr,
|
const image_header *const new_hdr,
|
||||||
secbool *is_new, secbool *is_upgrade,
|
secbool *is_new, secbool *is_upgrade,
|
||||||
secbool *is_downgrade_wipe) {
|
secbool *is_newvendor) {
|
||||||
*is_new = secfalse;
|
*is_new = secfalse;
|
||||||
*is_upgrade = secfalse;
|
*is_upgrade = secfalse;
|
||||||
*is_downgrade_wipe = secfalse;
|
*is_newvendor = secfalse;
|
||||||
if (sectrue != check_vendor_header_keys(current_vhdr)) {
|
if (sectrue != check_vendor_header_keys(current_vhdr)) {
|
||||||
*is_new = sectrue;
|
*is_new = sectrue;
|
||||||
return;
|
return;
|
||||||
@ -454,10 +454,10 @@ static void detect_installation(const vendor_header *current_vhdr,
|
|||||||
vendor_header_hash(new_vhdr, hash1);
|
vendor_header_hash(new_vhdr, hash1);
|
||||||
vendor_header_hash(current_vhdr, hash2);
|
vendor_header_hash(current_vhdr, hash2);
|
||||||
if (0 != memcmp(hash1, hash2, 32)) {
|
if (0 != memcmp(hash1, hash2, 32)) {
|
||||||
|
*is_newvendor = sectrue;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (version_compare(new_hdr->version, current_hdr->fix_version) < 0) {
|
if (version_compare(new_hdr->version, current_hdr->fix_version) < 0) {
|
||||||
*is_downgrade_wipe = sectrue;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*is_upgrade = sectrue;
|
*is_upgrade = sectrue;
|
||||||
@ -482,8 +482,8 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static image_header hdr;
|
static image_header hdr;
|
||||||
secbool is_upgrade = secfalse;
|
secbool is_newvendor = secfalse;
|
||||||
secbool is_downgrade_wipe = secfalse;
|
secbool should_keep_seed = secfalse;
|
||||||
|
|
||||||
if (firmware_block == 0) {
|
if (firmware_block == 0) {
|
||||||
if (headers_offset == 0) {
|
if (headers_offset == 0) {
|
||||||
@ -562,20 +562,17 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size,
|
|||||||
|
|
||||||
if (is_new == secfalse) {
|
if (is_new == secfalse) {
|
||||||
detect_installation(¤t_vhdr, current_hdr, &vhdr, &hdr, &is_new,
|
detect_installation(¤t_vhdr, current_hdr, &vhdr, &hdr, &is_new,
|
||||||
&is_upgrade, &is_downgrade_wipe);
|
&should_keep_seed, &is_newvendor);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t response = INPUT_CANCEL;
|
uint32_t response = INPUT_CANCEL;
|
||||||
if (sectrue == is_new) {
|
if (sectrue == is_new) {
|
||||||
// new installation - auto confirm
|
// new installation - auto confirm
|
||||||
response = INPUT_CONFIRM;
|
response = INPUT_CONFIRM;
|
||||||
} else if (sectrue == is_upgrade) {
|
|
||||||
// firmware upgrade
|
|
||||||
response = ui_screen_install_confirm_upgrade(&vhdr, &hdr);
|
|
||||||
} else {
|
} else {
|
||||||
// downgrade with wipe or new firmware vendor
|
int version_cmp = version_compare(hdr.version, current_hdr->version);
|
||||||
response = ui_screen_install_confirm_newvendor_or_downgrade_wipe(
|
response = ui_screen_install_confirm(&vhdr, &hdr, should_keep_seed,
|
||||||
&vhdr, &hdr, is_downgrade_wipe);
|
is_newvendor, version_cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (INPUT_CANCEL == response) {
|
if (INPUT_CANCEL == response) {
|
||||||
@ -601,7 +598,7 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size,
|
|||||||
// first block with the headers parsed -> the first chunk is now complete
|
// first block with the headers parsed -> the first chunk is now complete
|
||||||
read_offset = 0;
|
read_offset = 0;
|
||||||
// if firmware is not upgrade, erase storage
|
// if firmware is not upgrade, erase storage
|
||||||
if (sectrue != is_upgrade) {
|
if (sectrue != should_keep_seed) {
|
||||||
ensure(
|
ensure(
|
||||||
flash_erase_sectors(STORAGE_SECTORS, STORAGE_SECTORS_COUNT, NULL),
|
flash_erase_sectors(STORAGE_SECTORS, STORAGE_SECTORS_COUNT, NULL),
|
||||||
NULL);
|
NULL);
|
||||||
|
@ -9,8 +9,9 @@ void loader_uncompress_r(int32_t y_offset, uint16_t fg_color, uint16_t bg_color,
|
|||||||
|
|
||||||
uint32_t screen_install_confirm(const char* vendor_str, uint8_t vendor_str_len,
|
uint32_t screen_install_confirm(const char* vendor_str, uint8_t vendor_str_len,
|
||||||
const char* version_str,
|
const char* version_str,
|
||||||
const uint8_t* fingerprint, bool downgrade,
|
const uint8_t* fingerprint,
|
||||||
bool vendor);
|
bool should_keep_seed, bool is_newvendor,
|
||||||
|
int version_cmp);
|
||||||
uint32_t screen_wipe_confirm(void);
|
uint32_t screen_wipe_confirm(void);
|
||||||
void screen_install_progress(int16_t progress, bool initialize,
|
void screen_install_progress(int16_t progress, bool initialize,
|
||||||
bool initial_setup);
|
bool initial_setup);
|
||||||
|
@ -139,8 +139,9 @@ extern "C" fn screen_install_confirm(
|
|||||||
vendor_str_len: u8,
|
vendor_str_len: u8,
|
||||||
version: *const cty::c_char,
|
version: *const cty::c_char,
|
||||||
fingerprint: *const cty::uint8_t,
|
fingerprint: *const cty::uint8_t,
|
||||||
downgrade: bool,
|
should_keep_seed: bool,
|
||||||
vendor: bool,
|
is_newvendor: bool,
|
||||||
|
version_cmp: cty::c_int,
|
||||||
) -> u32 {
|
) -> u32 {
|
||||||
let text = unwrap!(unsafe { from_c_array(vendor_str, vendor_str_len as usize) });
|
let text = unwrap!(unsafe { from_c_array(vendor_str, vendor_str_len as usize) });
|
||||||
let version = unwrap!(unsafe { from_c_str(version) });
|
let version = unwrap!(unsafe { from_c_str(version) });
|
||||||
@ -158,23 +159,25 @@ extern "C" fn screen_install_confirm(
|
|||||||
unwrap!(version_str.push_str("\nby "));
|
unwrap!(version_str.push_str("\nby "));
|
||||||
unwrap!(version_str.push_str(text));
|
unwrap!(version_str.push_str(text));
|
||||||
|
|
||||||
let title_str = if downgrade {
|
let title_str = if is_newvendor {
|
||||||
"DOWNGRADE FW"
|
|
||||||
} else if vendor {
|
|
||||||
"CHANGE FW\nVENDOR"
|
"CHANGE FW\nVENDOR"
|
||||||
} else {
|
} else if version_cmp > 0 {
|
||||||
"UPDATE FIRMWARE"
|
"UPDATE FIRMWARE"
|
||||||
|
} else if version_cmp == 0 {
|
||||||
|
"REINSTALL FW"
|
||||||
|
} else {
|
||||||
|
"DOWNGRADE FW"
|
||||||
};
|
};
|
||||||
let title = Label::new(title_str, Alignment::Start, theme::TEXT_BOLD)
|
let title = Label::new(title_str, Alignment::Start, theme::TEXT_BOLD)
|
||||||
.vertically_aligned(Alignment::Center);
|
.vertically_aligned(Alignment::Center);
|
||||||
let msg = Label::new(version_str.as_ref(), Alignment::Start, theme::TEXT_NORMAL);
|
let msg = Label::new(version_str.as_ref(), Alignment::Start, theme::TEXT_NORMAL);
|
||||||
let alert = (vendor || downgrade).then_some(Label::new(
|
let alert = (!should_keep_seed).then_some(Label::new(
|
||||||
"SEED WILL BE ERASED!",
|
"SEED WILL BE ERASED!",
|
||||||
Alignment::Start,
|
Alignment::Start,
|
||||||
theme::TEXT_BOLD,
|
theme::TEXT_BOLD,
|
||||||
));
|
));
|
||||||
|
|
||||||
let (left, right) = if !(vendor || downgrade) {
|
let (left, right) = if should_keep_seed {
|
||||||
let l = Button::with_text("CANCEL").styled(button_bld());
|
let l = Button::with_text("CANCEL").styled(button_bld());
|
||||||
let r = Button::with_text("INSTALL").styled(button_confirm());
|
let r = Button::with_text("INSTALL").styled(button_confirm());
|
||||||
(l, r)
|
(l, r)
|
||||||
|
Loading…
Reference in New Issue
Block a user