diff --git a/common/protob/messages-management.proto b/common/protob/messages-management.proto index e3d933880..4656ebd5d 100644 --- a/common/protob/messages-management.proto +++ b/common/protob/messages-management.proto @@ -518,10 +518,10 @@ message ShowDeviceTutorial { } /** - * Request: Delete attestation from the device, !irreversible! + * Request: Unlocks bootloader, !irreversible! * @start * @next Success * @next Failure */ -message AttestationDelete { +message UnlockBootloader { } diff --git a/common/protob/messages.proto b/common/protob/messages.proto index 71c2b582a..632c733c0 100644 --- a/common/protob/messages.proto +++ b/common/protob/messages.proto @@ -121,7 +121,7 @@ enum MessageType { MessageType_UnlockPath = 93 [(bitcoin_only) = true, (wire_in) = true]; MessageType_UnlockedPathRequest = 94 [(bitcoin_only) = true, (wire_out) = true]; MessageType_ShowDeviceTutorial = 95 [(bitcoin_only) = true, (wire_in) = true]; - MessageType_AttestationDelete = 96 [(bitcoin_only) = true, (wire_in) = true]; + MessageType_UnlockBootloader = 96 [(bitcoin_only) = true, (wire_in) = true]; MessageType_SetU2FCounter = 63 [(wire_in) = true]; MessageType_GetNextU2FCounter = 80 [(wire_in) = true]; diff --git a/core/embed/bootloader/bootui.c b/core/embed/bootloader/bootui.c index 8f8ff2fc3..a2f13beee 100644 --- a/core/embed/bootloader/bootui.c +++ b/core/embed/bootloader/bootui.c @@ -236,8 +236,8 @@ void ui_screen_boot_empty(bool fading) { screen_boot_empty(fading); } void ui_screen_fail(void) { screen_install_fail(); } #ifdef USE_OPTIGA -uint32_t ui_screen_attestation_delete_confirm(void) { - return screen_attestation_delete_confirm(); +uint32_t ui_screen_unlock_bootloader_confirm(void) { + return screen_unlock_bootloader_confirm(); } #endif diff --git a/core/embed/bootloader/bootui.h b/core/embed/bootloader/bootui.h index 5af65f4d0..ba318adcd 100644 --- a/core/embed/bootloader/bootui.h +++ b/core/embed/bootloader/bootui.h @@ -70,7 +70,7 @@ void ui_set_initial_setup(bool initial); void ui_screen_boot_empty(bool fading); #ifdef USE_OPTIGA -uint32_t ui_screen_attestation_delete_confirm(void); +uint32_t ui_screen_unlock_bootloader_confirm(void); #endif // clang-format off diff --git a/core/embed/bootloader/main.c b/core/embed/bootloader/main.c index cf1488bfb..b22b75361 100644 --- a/core/embed/bootloader/main.c +++ b/core/embed/bootloader/main.c @@ -216,17 +216,17 @@ static usb_result_t bootloader_usb_loop(const vendor_header *const vhdr, process_msg_GetFeatures(USB_IFACE_NUM, msg_size, buf, vhdr, hdr); break; #ifdef USE_OPTIGA - case MessageType_MessageType_AttestationDelete: - response = ui_screen_attestation_delete_confirm(); + case MessageType_MessageType_UnlockBootloader: + response = ui_screen_unlock_bootloader_confirm(); if (INPUT_CANCEL == response) { - send_user_abort(USB_IFACE_NUM, "Attestation delete cancelled"); + send_user_abort(USB_IFACE_NUM, "Bootloader unlock cancelled"); hal_delay(100); usb_stop(); usb_deinit(); return RETURN; } process_msg_AttestationDelete(USB_IFACE_NUM, msg_size, buf); - screen_attestation_delete_success(); + screen_unlock_bootloader_success(); hal_delay(100); usb_stop(); usb_deinit(); @@ -545,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", - "On-device attestation must be deleted before " - "installing unofficial firmware.", - "PLEASE RECONNECT THE DEVICE"); + screen_fatal_error_rust( + "INSTALL RESTRICTED", + "Installation of custom firmware is currently restricted.", + "Please visit\ntrezor.io/bootloader"); display_refresh(); return 1; diff --git a/core/embed/bootloader/protob/messages.pb.c b/core/embed/bootloader/protob/messages.pb.c index e43a4fd84..087828cf7 100644 --- a/core/embed/bootloader/protob/messages.pb.c +++ b/core/embed/bootloader/protob/messages.pb.c @@ -39,7 +39,7 @@ PB_BIND(FirmwareRequest, FirmwareRequest, AUTO) PB_BIND(FirmwareUpload, FirmwareUpload, AUTO) -PB_BIND(AttestationDelete, AttestationDelete, AUTO) +PB_BIND(UnlockBootloader, UnlockBootloader, AUTO) diff --git a/core/embed/bootloader/protob/messages.pb.h b/core/embed/bootloader/protob/messages.pb.h index 64ebbbd42..9b85a9f31 100644 --- a/core/embed/bootloader/protob/messages.pb.h +++ b/core/embed/bootloader/protob/messages.pb.h @@ -23,7 +23,7 @@ typedef enum _MessageType { MessageType_MessageType_ButtonRequest = 26, MessageType_MessageType_ButtonAck = 27, MessageType_MessageType_GetFeatures = 55, - MessageType_MessageType_AttestationDelete = 96 + MessageType_MessageType_UnlockBootloader = 96 } MessageType; typedef enum _FailureType { @@ -38,10 +38,6 @@ typedef enum _ButtonRequestType { } ButtonRequestType; /* Struct definitions */ -typedef struct _AttestationDelete { - char dummy_field; -} AttestationDelete; - typedef struct _ButtonAck { char dummy_field; } ButtonAck; @@ -54,6 +50,10 @@ typedef struct _Initialize { char dummy_field; } Initialize; +typedef struct _UnlockBootloader { + char dummy_field; +} UnlockBootloader; + typedef struct _ButtonRequest { bool has_code; ButtonRequestType code; @@ -135,8 +135,8 @@ typedef struct _Success { /* Helper constants for enums */ #define _MessageType_MIN MessageType_MessageType_Initialize -#define _MessageType_MAX MessageType_MessageType_AttestationDelete -#define _MessageType_ARRAYSIZE ((MessageType)(MessageType_MessageType_AttestationDelete+1)) +#define _MessageType_MAX MessageType_MessageType_UnlockBootloader +#define _MessageType_ARRAYSIZE ((MessageType)(MessageType_MessageType_UnlockBootloader+1)) #define _FailureType_MIN FailureType_Failure_UnexpectedMessage #define _FailureType_MAX FailureType_Failure_ProcessError @@ -163,7 +163,7 @@ extern "C" { #define FirmwareErase_init_default {false, 0} #define FirmwareRequest_init_default {0, 0} #define FirmwareUpload_init_default {{{NULL}, NULL}, false, {0, {0}}} -#define AttestationDelete_init_default {0} +#define UnlockBootloader_init_default {0} #define Initialize_init_zero {0} #define GetFeatures_init_zero {0} #define Features_init_zero {false, "", 0, 0, 0, false, 0, false, "", false, "", false, "", false, 0, false, {0, {0}}, false, 0, false, "", false, 0, false, 0, false, 0, false, "", false, "", false, 0, false, 0} @@ -175,7 +175,7 @@ extern "C" { #define FirmwareErase_init_zero {false, 0} #define FirmwareRequest_init_zero {0, 0} #define FirmwareUpload_init_zero {{{NULL}, NULL}, false, {0, {0}}} -#define AttestationDelete_init_zero {0} +#define UnlockBootloader_init_zero {0} /* Field tags (for use in manual encoding/decoding) */ #define ButtonRequest_code_tag 1 @@ -285,10 +285,10 @@ X(a, STATIC, OPTIONAL, BYTES, hash, 2) #define FirmwareUpload_CALLBACK pb_default_field_callback #define FirmwareUpload_DEFAULT NULL -#define AttestationDelete_FIELDLIST(X, a) \ +#define UnlockBootloader_FIELDLIST(X, a) \ -#define AttestationDelete_CALLBACK NULL -#define AttestationDelete_DEFAULT NULL +#define UnlockBootloader_CALLBACK NULL +#define UnlockBootloader_DEFAULT NULL extern const pb_msgdesc_t Initialize_msg; extern const pb_msgdesc_t GetFeatures_msg; @@ -301,7 +301,7 @@ extern const pb_msgdesc_t ButtonAck_msg; extern const pb_msgdesc_t FirmwareErase_msg; extern const pb_msgdesc_t FirmwareRequest_msg; extern const pb_msgdesc_t FirmwareUpload_msg; -extern const pb_msgdesc_t AttestationDelete_msg; +extern const pb_msgdesc_t UnlockBootloader_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define Initialize_fields &Initialize_msg @@ -315,11 +315,10 @@ extern const pb_msgdesc_t AttestationDelete_msg; #define FirmwareErase_fields &FirmwareErase_msg #define FirmwareRequest_fields &FirmwareRequest_msg #define FirmwareUpload_fields &FirmwareUpload_msg -#define AttestationDelete_fields &AttestationDelete_msg +#define UnlockBootloader_fields &UnlockBootloader_msg /* Maximum encoded size of messages (where known) */ /* FirmwareUpload_size depends on runtime parameters */ -#define AttestationDelete_size 0 #define ButtonAck_size 0 #define ButtonRequest_size 2 #define Failure_size 260 @@ -330,6 +329,7 @@ extern const pb_msgdesc_t AttestationDelete_msg; #define Initialize_size 0 #define Ping_size 258 #define Success_size 258 +#define UnlockBootloader_size 0 #ifdef __cplusplus } /* extern "C" */ diff --git a/core/embed/bootloader/protob/messages.proto b/core/embed/bootloader/protob/messages.proto index 9d40db589..4149460d6 100644 --- a/core/embed/bootloader/protob/messages.proto +++ b/core/embed/bootloader/protob/messages.proto @@ -17,7 +17,7 @@ enum MessageType { MessageType_ButtonRequest = 26; MessageType_ButtonAck = 27; MessageType_GetFeatures = 55; - MessageType_AttestationDelete = 96; + MessageType_UnlockBootloader = 96; } /** @@ -147,10 +147,10 @@ message FirmwareUpload { } /** - * Request: Delete attestation from the device, !irreversible! + * Request: Unlock bootloader, !irreversible! * @start * @next Success * @next Failure */ -message AttestationDelete { +message UnlockBootloader { } diff --git a/core/embed/rust/rust_ui.h b/core/embed/rust/rust_ui.h index b76c670b2..da3c566c1 100644 --- a/core/embed/rust/rust_ui.h +++ b/core/embed/rust/rust_ui.h @@ -25,6 +25,6 @@ uint32_t screen_install_fail(void); 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); +uint32_t screen_unlock_bootloader_confirm(void); +void screen_unlock_bootloader_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/model_tr/bootloader/confirm.rs b/core/embed/rust/src/ui/model_tr/bootloader/confirm.rs index 36508cc51..6b8aa10cd 100644 --- a/core/embed/rust/src/ui/model_tr/bootloader/confirm.rs +++ b/core/embed/rust/src/ui/model_tr/bootloader/confirm.rs @@ -39,6 +39,7 @@ pub struct Confirm<'a> { buttons: ButtonController<&'static str>, /// Whether we are on the info screen (optional extra screen) showing_info_screen: bool, + two_btn_confirm: bool, } impl<'a> Confirm<'a> { @@ -48,8 +49,10 @@ impl<'a> Confirm<'a> { message: Label<&'a str>, alert: Option>, button_text: &'static str, + two_btn_confirm: bool, ) -> Self { - let btn_layout = Self::get_button_layout_general(false, button_text, false); + let btn_layout = + Self::get_button_layout_general(false, button_text, false, two_btn_confirm); Self { bg: Pad::with_background(bg_color).with_clear(), bg_color, @@ -61,6 +64,7 @@ impl<'a> Confirm<'a> { button_text, buttons: ButtonController::new(btn_layout), showing_info_screen: false, + two_btn_confirm, } } @@ -81,6 +85,7 @@ impl<'a> Confirm<'a> { self.showing_info_screen, self.button_text, self.has_info_screen(), + self.two_btn_confirm, ) } @@ -89,11 +94,14 @@ impl<'a> Confirm<'a> { showing_info_screen: bool, button_text: &'static str, has_info_screen: bool, + two_btn_confirm: bool, ) -> ButtonLayout<&'static str> { if showing_info_screen { ButtonLayout::arrow_none_none() } else if has_info_screen { ButtonLayout::cancel_armed_info(button_text) + } else if two_btn_confirm { + ButtonLayout::cancel_armed_none(button_text) } else { ButtonLayout::cancel_none_text(button_text) } @@ -166,6 +174,14 @@ impl<'a> Component for Confirm<'a> { } _ => None, } + } else if self.two_btn_confirm { + match msg { + Some(ButtonControllerMsg::Triggered(ButtonPos::Left)) => Some(ConfirmMsg::Cancel), + Some(ButtonControllerMsg::Triggered(ButtonPos::Middle)) => { + Some(ConfirmMsg::Confirm) + } + _ => None, + } } else { // There is just one main screen without info screen match msg { 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 48e096a6c..3214001cf 100644 --- a/core/embed/rust/src/ui/model_tr/bootloader/mod.rs +++ b/core/embed/rust/src/ui/model_tr/bootloader/mod.rs @@ -150,7 +150,7 @@ extern "C" fn screen_install_confirm( theme::TEXT_NORMAL, )); - let mut frame = Confirm::new(BLD_BG, title_str, message, alert, "INSTALL") + let mut frame = Confirm::new(BLD_BG, title_str, message, alert, "INSTALL", false) .with_info_screen("FW FINGERPRINT", fingerprint); run(&mut frame) } @@ -160,27 +160,24 @@ extern "C" fn screen_wipe_confirm() -> u32 { let message = Label::left_aligned("Seed and firmware will be erased!", theme::TEXT_NORMAL) .vertically_centered(); - let mut frame = Confirm::new(BLD_BG, "FACTORY RESET", message, None, "RESET"); + let mut frame = Confirm::new(BLD_BG, "FACTORY RESET", message, None, "RESET", false); run(&mut frame) } #[no_mangle] -extern "C" fn screen_attestation_delete_confirm() -> u32 { - let message = Label::left_aligned( - "Are you sure you want to delete the attestation from this device?", - theme::TEXT_NORMAL, - ) - .vertically_centered(); +extern "C" fn screen_unlock_bootloader_confirm() -> u32 { + let message = Label::left_aligned("This action cannot be undone!", theme::TEXT_NORMAL) + .vertically_centered(); - let mut frame = Confirm::new(BLD_BG, "DELETE ATTESTATION", message, None, "DELETE"); + let mut frame = Confirm::new(BLD_BG, "UNLOCK BOOTLOADER?", message, None, "UNLOCK", true); run(&mut frame) } #[no_mangle] -extern "C" fn screen_attestation_delete_success() { - let title = Label::centered("Attestation deleted", theme::TEXT_BOLD).vertically_centered(); +extern "C" fn screen_unlock_bootloader_success() { + let title = Label::centered("Bootloader unlocked", theme::TEXT_BOLD).vertically_centered(); let content = Label::centered("Please reconnect the\ndevice", theme::TEXT_NORMAL).vertically_centered(); diff --git a/core/embed/rust/src/ui/model_tr/component/button.rs b/core/embed/rust/src/ui/model_tr/component/button.rs index 0f8df1404..25bace910 100644 --- a/core/embed/rust/src/ui/model_tr/component/button.rs +++ b/core/embed/rust/src/ui/model_tr/component/button.rs @@ -538,6 +538,15 @@ where ) } + /// Left cancel, armed text and blank on right. + pub fn cancel_armed_none(middle: T) -> Self { + Self::new( + Some(ButtonDetails::cancel_icon()), + Some(ButtonDetails::armed_text(middle)), + None, + ) + } + /// Left back arrow and middle armed text. pub fn arrow_armed_none(text: T) -> Self { Self::new( diff --git a/core/src/trezor/enums/MessageType.py b/core/src/trezor/enums/MessageType.py index 027eb82f6..205e64875 100644 --- a/core/src/trezor/enums/MessageType.py +++ b/core/src/trezor/enums/MessageType.py @@ -47,7 +47,7 @@ FirmwareHash = 89 UnlockPath = 93 UnlockedPathRequest = 94 ShowDeviceTutorial = 95 -AttestationDelete = 96 +UnlockBootloader = 96 FirmwareErase = 6 FirmwareUpload = 7 FirmwareRequest = 8 diff --git a/core/src/trezor/enums/__init__.py b/core/src/trezor/enums/__init__.py index d528c7de5..b2b3981f7 100644 --- a/core/src/trezor/enums/__init__.py +++ b/core/src/trezor/enums/__init__.py @@ -64,7 +64,7 @@ if TYPE_CHECKING: UnlockPath = 93 UnlockedPathRequest = 94 ShowDeviceTutorial = 95 - AttestationDelete = 96 + UnlockBootloader = 96 SetU2FCounter = 63 GetNextU2FCounter = 80 NextU2FCounter = 81 diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py index 768432c0c..095c04e94 100644 --- a/core/src/trezor/messages.py +++ b/core/src/trezor/messages.py @@ -2628,10 +2628,10 @@ if TYPE_CHECKING: def is_type_of(cls, msg: Any) -> TypeGuard["ShowDeviceTutorial"]: return isinstance(msg, cls) - class AttestationDelete(protobuf.MessageType): + class UnlockBootloader(protobuf.MessageType): @classmethod - def is_type_of(cls, msg: Any) -> TypeGuard["AttestationDelete"]: + def is_type_of(cls, msg: Any) -> TypeGuard["UnlockBootloader"]: return isinstance(msg, cls) class DebugLinkDecision(protobuf.MessageType): diff --git a/legacy/firmware/protob/Makefile b/legacy/firmware/protob/Makefile index cca46f500..911296422 100644 --- a/legacy/firmware/protob/Makefile +++ b/legacy/firmware/protob/Makefile @@ -8,7 +8,7 @@ SKIPPED_MESSAGES := Binance Cardano DebugMonero Eos Monero Ontology Ripple SdPro TxAckInput TxAckOutput TxAckPrev TxAckPaymentRequest \ EthereumSignTypedData EthereumTypedDataStructRequest EthereumTypedDataStructAck \ EthereumTypedDataValueRequest EthereumTypedDataValueAck ShowDeviceTutorial \ - AttestationDelete + UnlockBootloader ifeq ($(BITCOIN_ONLY), 1) SKIPPED_MESSAGES += Ethereum NEM Stellar diff --git a/python/src/trezorlib/cli/device.py b/python/src/trezorlib/cli/device.py index 92c920721..c8f6e6104 100644 --- a/python/src/trezorlib/cli/device.py +++ b/python/src/trezorlib/cli/device.py @@ -301,9 +301,9 @@ def tutorial(client: "TrezorClient") -> str: @cli.command() @with_client -def attestation_delete(client: "TrezorClient") -> str: - """Delete device attestation. Irreversible.""" - return device.attestation_delete(client) +def unlock_bootloader(client: "TrezorClient") -> str: + """Unlocks bootloader. Irreversible.""" + return device.unlock_bootloader(client) @cli.command() diff --git a/python/src/trezorlib/device.py b/python/src/trezorlib/device.py index 51147438a..4ed5cbbfa 100644 --- a/python/src/trezorlib/device.py +++ b/python/src/trezorlib/device.py @@ -250,8 +250,8 @@ def show_device_tutorial(client: "TrezorClient") -> "MessageType": @session @expect(messages.Success, field="message", ret_type=str) -def attestation_delete(client: "TrezorClient") -> "MessageType": - return client.call(messages.AttestationDelete()) +def unlock_bootloader(client: "TrezorClient") -> "MessageType": + return client.call(messages.UnlockBootloader()) @expect(messages.Success, field="message", ret_type=str) diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py index d948822ad..e1b90f79a 100644 --- a/python/src/trezorlib/messages.py +++ b/python/src/trezorlib/messages.py @@ -72,7 +72,7 @@ class MessageType(IntEnum): UnlockPath = 93 UnlockedPathRequest = 94 ShowDeviceTutorial = 95 - AttestationDelete = 96 + UnlockBootloader = 96 SetU2FCounter = 63 GetNextU2FCounter = 80 NextU2FCounter = 81 @@ -3738,7 +3738,7 @@ class ShowDeviceTutorial(protobuf.MessageType): MESSAGE_WIRE_TYPE = 95 -class AttestationDelete(protobuf.MessageType): +class UnlockBootloader(protobuf.MessageType): MESSAGE_WIRE_TYPE = 96