From 0be5e8111589f86f315dc2431c9b886015424c85 Mon Sep 17 00:00:00 2001 From: tychovrahe Date: Wed, 9 Aug 2023 23:01:39 +0200 Subject: [PATCH] fixup! feat(core): add prodtest and secret handling for T2B1 --- core/embed/bootloader/main.c | 11 ++- core/embed/prodtest/main.c | 99 ++++++++++--------- core/embed/rust/rust_ui.h | 1 + core/embed/rust/src/ui/display/mod.rs | 5 +- .../rust/src/ui/model_tr/bootloader/mod.rs | 20 +++- .../rust/src/ui/model_tr/component/error.rs | 22 +++-- 6 files changed, 92 insertions(+), 66 deletions(-) diff --git a/core/embed/bootloader/main.c b/core/embed/bootloader/main.c index 1478e37a8..cf1488bfb 100644 --- a/core/embed/bootloader/main.c +++ b/core/embed/bootloader/main.c @@ -226,10 +226,11 @@ static usb_result_t bootloader_usb_loop(const vendor_header *const vhdr, return RETURN; } process_msg_AttestationDelete(USB_IFACE_NUM, msg_size, buf); + screen_attestation_delete_success(); hal_delay(100); usb_stop(); usb_deinit(); - return RETURN; + return SHUTDOWN; break; #endif default: @@ -544,10 +545,10 @@ int bootloader_main(void) { #ifdef USE_OPTIGA if (((vhdr.vtrust & VTRUST_SECRET) != 0) && (sectrue != secret_wiped())) { display_clear(); - screen_fatal_error_rust( - "ATTESTATION PRESENT", - "You need to delete device attestation to run unofficial firmware", - "RECONNECT THE DEVICE"); + screen_fatal_error_rust("ATTESTATION PRESENT", + "On-device attestation must be deleted before " + "installing unofficial firmware.", + "PLEASE RECONNECT THE DEVICE"); display_refresh(); return 1; diff --git a/core/embed/prodtest/main.c b/core/embed/prodtest/main.c index cc915a898..76d26c4e4 100644 --- a/core/embed/prodtest/main.c +++ b/core/embed/prodtest/main.c @@ -661,51 +661,59 @@ static bool set_metadata(uint16_t oid, const optiga_metadata *metadata) { } static bool pair_optiga(void) { - // The pairing key may already be written and locked. The success of the - // pairing procedure is determined by optiga_sec_chan_handshake(). Therefore - // it is OK for some of the intermediate operations to fail. - - // Enable writing the pairing secret to OPTIGA. - optiga_metadata metadata = {0}; - metadata.change = OPTIGA_ACCESS_ALWAYS; - set_metadata(OID_KEY_PAIRING, &metadata); // Ignore result. - - // Generate pairing secret. - uint8_t secret[SECRET_OPTIGA_KEY_LEN] = {0}; - optiga_result ret = optiga_get_random(secret, sizeof(secret)); - if (OPTIGA_SUCCESS != ret) { - vcp_println("ERROR optiga_get_random error %d,", ret); - return false; - } - - // Store pairing secret. - ret = optiga_set_data_object(OID_KEY_PAIRING, false, secret, sizeof(secret)); - /* - * TODO: Uncomment. Right now this code will render the device unusable with - * unofficial firmware. We need to be able to call AttestationDelete before - * this code is enabled. - * - if (OPTIGA_SUCCESS == ret) { - secret_erase(); - secret_write_header(); - secret_write(secret, SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN); - } - - // Verify whether the secret was stored correctly in flash and OPTIGA. - memzero(secret, sizeof(secret)); - if (secret_read(secret, SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN) != - sectrue) { - vcp_println("ERROR Failed to read pairing secret."); - return false; - } - */ - - ret = optiga_sec_chan_handshake(secret, sizeof(secret)); - memzero(secret, sizeof(secret)); - if (OPTIGA_SUCCESS != ret) { - vcp_println("ERROR optiga_sec_chan_handshake error %d.", ret); - return false; - } + secret_erase(); + secret_write_header(); + + // // The pairing key may already be written and locked. The success of the + // // pairing procedure is determined by optiga_sec_chan_handshake(). + // Therefore + // // it is OK for some of the intermediate operations to fail. + // + // // Enable writing the pairing secret to OPTIGA. + // optiga_metadata metadata = {0}; + // metadata.change = OPTIGA_ACCESS_ALWAYS; + // set_metadata(OID_KEY_PAIRING, &metadata); // Ignore result. + // + // // Generate pairing secret. + // uint8_t secret[SECRET_OPTIGA_KEY_LEN] = {0}; + // optiga_result ret = optiga_get_random(secret, sizeof(secret)); + // if (OPTIGA_SUCCESS != ret) { + // vcp_println("ERROR optiga_get_random error %d,", ret); + // return false; + // } + // + // // Store pairing secret. + // ret = optiga_set_data_object(OID_KEY_PAIRING, false, secret, + // sizeof(secret)); + // /* + // * TODO: Uncomment. Right now this code will render the device unusable + // with + // * unofficial firmware. We need to be able to call AttestationDelete + // before + // * this code is enabled. + // * + // if (OPTIGA_SUCCESS == ret) { + // secret_erase(); + // secret_write_header(); + // secret_write(secret, SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN); + // } + // + // // Verify whether the secret was stored correctly in flash and OPTIGA. + // memzero(secret, sizeof(secret)); + // if (secret_read(secret, SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN) + // != + // sectrue) { + // vcp_println("ERROR Failed to read pairing secret."); + // return false; + // } + // */ + // + // ret = optiga_sec_chan_handshake(secret, sizeof(secret)); + // memzero(secret, sizeof(secret)); + // if (OPTIGA_SUCCESS != ret) { + // vcp_println("ERROR optiga_sec_chan_handshake error %d.", ret); + // return false; + // } return true; } @@ -1065,6 +1073,7 @@ int main(void) { #ifdef USE_OPTIGA optiga_init(); optiga_open_application(); + pair_optiga(); #endif display_reinit(); diff --git a/core/embed/rust/rust_ui.h b/core/embed/rust/rust_ui.h index 685bf02cd..b76c670b2 100644 --- a/core/embed/rust/rust_ui.h +++ b/core/embed/rust/rust_ui.h @@ -26,4 +26,5 @@ void screen_welcome_model(void); void screen_welcome(void); void screen_boot_empty(bool fading); uint32_t screen_attestation_delete_confirm(void); +void screen_attestation_delete_success(void); void display_image(int16_t x, int16_t y, const uint8_t* data, uint32_t datalen); diff --git a/core/embed/rust/src/ui/display/mod.rs b/core/embed/rust/src/ui/display/mod.rs index a2e218f8a..898245c48 100644 --- a/core/embed/rust/src/ui/display/mod.rs +++ b/core/embed/rust/src/ui/display/mod.rs @@ -858,9 +858,8 @@ pub fn marquee(area: Rect, text: &str, offset: i16, font: Font, fg: Color, bg: C pixeldata_dirty(); } -// Used on T1 only. -pub fn dotted_line(start: Point, width: i16, color: Color) { - for x in (start.x..width).step_by(2) { +pub fn dotted_line(start: Point, width: i16, color: Color, step: i16) { + for x in (start.x..width).step_by(step as usize) { display::bar(x, start.y, 1, 1, color.into()); } } diff --git a/core/embed/rust/src/ui/model_tr/bootloader/mod.rs b/core/embed/rust/src/ui/model_tr/bootloader/mod.rs index a3169081d..48e096a6c 100644 --- a/core/embed/rust/src/ui/model_tr/bootloader/mod.rs +++ b/core/embed/rust/src/ui/model_tr/bootloader/mod.rs @@ -167,14 +167,28 @@ extern "C" fn screen_wipe_confirm() -> u32 { #[no_mangle] extern "C" fn screen_attestation_delete_confirm() -> u32 { - let message = Label::left_aligned("Delete attestation from the device?", theme::TEXT_NORMAL) - .vertically_centered(); + let message = Label::left_aligned( + "Are you sure you want to delete the attestation from this device?", + theme::TEXT_NORMAL, + ) + .vertically_centered(); - let mut frame = Confirm::new(BLD_BG, "ATTESTATION ERASE", message, None, "ERASE"); + let mut frame = Confirm::new(BLD_BG, "DELETE ATTESTATION", message, None, "DELETE"); run(&mut frame) } +#[no_mangle] +extern "C" fn screen_attestation_delete_success() { + let title = Label::centered("Attestation deleted", theme::TEXT_BOLD).vertically_centered(); + + let content = + Label::centered("Please reconnect the\ndevice", theme::TEXT_NORMAL).vertically_centered(); + + let mut frame = ResultScreen::new(BLD_FG, BLD_BG, ICON_SPINNER, title, content, true); + show(&mut frame); +} + #[no_mangle] extern "C" fn screen_menu(_bld_version: *const cty::c_char) -> u32 { run(&mut Menu::new()) diff --git a/core/embed/rust/src/ui/model_tr/component/error.rs b/core/embed/rust/src/ui/model_tr/component/error.rs index 43cc3857b..29624f40b 100644 --- a/core/embed/rust/src/ui/model_tr/component/error.rs +++ b/core/embed/rust/src/ui/model_tr/component/error.rs @@ -1,6 +1,6 @@ use crate::ui::{ component::{Child, Component, Event, EventCtx, Label, Never, Pad}, - constant::screen, + constant::{screen, WIDTH}, display, geometry::{Alignment2D, Offset, Point, Rect}, }; @@ -11,7 +11,6 @@ use super::super::{ }; const FOOTER_AREA_HEIGHT: i16 = 20; -const MESSAGE_AREA_HEIGHT: i16 = 32; const DIVIDER_POSITION: i16 = 43; pub struct ErrorScreen { @@ -55,9 +54,15 @@ impl> Component for ErrorScreen { self.show_icons = false; } + let top_offset = if self.show_icons { + Offset::y(11) + } else { + Offset::y(8) + }; + let message_area = Rect::new( - title_area.bottom_left(), - title_area.bottom_right() + Offset::y(MESSAGE_AREA_HEIGHT), + title_area.top_left() + top_offset, + Point::new(title_area.bottom_right().x, DIVIDER_POSITION), ); self.message.place(message_area); @@ -84,12 +89,9 @@ impl> Component for ErrorScreen { } self.title.paint(); self.message.paint(); - // divider line - let bar = Rect::from_center_and_size( - Point::new(self.area.center().x, DIVIDER_POSITION), - Offset::new(self.area.width(), 1), - ); - display::rect_fill(bar, FG); + + // // divider line + display::dotted_line(Point::new(0, DIVIDER_POSITION), WIDTH, FG, 3); self.footer.paint(); }