fixup! feat(core): add prodtest and secret handling for T2B1

tychovrahe 10 months ago
parent 0be5e81115
commit 1994ae1f1e

@ -518,10 +518,10 @@ message ShowDeviceTutorial {
} }
/** /**
* Request: Delete attestation from the device, !irreversible! * Request: Unlocks bootloader, !irreversible!
* @start * @start
* @next Success * @next Success
* @next Failure * @next Failure
*/ */
message AttestationDelete { message UnlockBootloader {
} }

@ -121,7 +121,7 @@ enum MessageType {
MessageType_UnlockPath = 93 [(bitcoin_only) = true, (wire_in) = true]; MessageType_UnlockPath = 93 [(bitcoin_only) = true, (wire_in) = true];
MessageType_UnlockedPathRequest = 94 [(bitcoin_only) = true, (wire_out) = true]; MessageType_UnlockedPathRequest = 94 [(bitcoin_only) = true, (wire_out) = true];
MessageType_ShowDeviceTutorial = 95 [(bitcoin_only) = true, (wire_in) = 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_SetU2FCounter = 63 [(wire_in) = true];
MessageType_GetNextU2FCounter = 80 [(wire_in) = true]; MessageType_GetNextU2FCounter = 80 [(wire_in) = true];

@ -236,8 +236,8 @@ void ui_screen_boot_empty(bool fading) { screen_boot_empty(fading); }
void ui_screen_fail(void) { screen_install_fail(); } void ui_screen_fail(void) { screen_install_fail(); }
#ifdef USE_OPTIGA #ifdef USE_OPTIGA
uint32_t ui_screen_attestation_delete_confirm(void) { uint32_t ui_screen_unlock_bootloader_confirm(void) {
return screen_attestation_delete_confirm(); return screen_unlock_bootloader_confirm();
} }
#endif #endif

@ -70,7 +70,7 @@ void ui_set_initial_setup(bool initial);
void ui_screen_boot_empty(bool fading); void ui_screen_boot_empty(bool fading);
#ifdef USE_OPTIGA #ifdef USE_OPTIGA
uint32_t ui_screen_attestation_delete_confirm(void); uint32_t ui_screen_unlock_bootloader_confirm(void);
#endif #endif
// clang-format off // clang-format off

@ -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); process_msg_GetFeatures(USB_IFACE_NUM, msg_size, buf, vhdr, hdr);
break; break;
#ifdef USE_OPTIGA #ifdef USE_OPTIGA
case MessageType_MessageType_AttestationDelete: case MessageType_MessageType_UnlockBootloader:
response = ui_screen_attestation_delete_confirm(); response = ui_screen_unlock_bootloader_confirm();
if (INPUT_CANCEL == response) { 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); hal_delay(100);
usb_stop(); usb_stop();
usb_deinit(); usb_deinit();
return RETURN; return RETURN;
} }
process_msg_AttestationDelete(USB_IFACE_NUM, msg_size, buf); process_msg_AttestationDelete(USB_IFACE_NUM, msg_size, buf);
screen_attestation_delete_success(); screen_unlock_bootloader_success();
hal_delay(100); hal_delay(100);
usb_stop(); usb_stop();
usb_deinit(); usb_deinit();
@ -545,10 +545,10 @@ int bootloader_main(void) {
#ifdef USE_OPTIGA #ifdef USE_OPTIGA
if (((vhdr.vtrust & VTRUST_SECRET) != 0) && (sectrue != secret_wiped())) { if (((vhdr.vtrust & VTRUST_SECRET) != 0) && (sectrue != secret_wiped())) {
display_clear(); display_clear();
screen_fatal_error_rust("ATTESTATION PRESENT", screen_fatal_error_rust(
"On-device attestation must be deleted before " "INSTALL RESTRICTED",
"installing unofficial firmware.", "Installation of custom firmware is currently restricted.",
"PLEASE RECONNECT THE DEVICE"); "Please visit\ntrezor.io/bootloader");
display_refresh(); display_refresh();
return 1; return 1;

@ -39,7 +39,7 @@ PB_BIND(FirmwareRequest, FirmwareRequest, AUTO)
PB_BIND(FirmwareUpload, FirmwareUpload, AUTO) PB_BIND(FirmwareUpload, FirmwareUpload, AUTO)
PB_BIND(AttestationDelete, AttestationDelete, AUTO) PB_BIND(UnlockBootloader, UnlockBootloader, AUTO)

@ -23,7 +23,7 @@ typedef enum _MessageType {
MessageType_MessageType_ButtonRequest = 26, MessageType_MessageType_ButtonRequest = 26,
MessageType_MessageType_ButtonAck = 27, MessageType_MessageType_ButtonAck = 27,
MessageType_MessageType_GetFeatures = 55, MessageType_MessageType_GetFeatures = 55,
MessageType_MessageType_AttestationDelete = 96 MessageType_MessageType_UnlockBootloader = 96
} MessageType; } MessageType;
typedef enum _FailureType { typedef enum _FailureType {
@ -38,10 +38,6 @@ typedef enum _ButtonRequestType {
} ButtonRequestType; } ButtonRequestType;
/* Struct definitions */ /* Struct definitions */
typedef struct _AttestationDelete {
char dummy_field;
} AttestationDelete;
typedef struct _ButtonAck { typedef struct _ButtonAck {
char dummy_field; char dummy_field;
} ButtonAck; } ButtonAck;
@ -54,6 +50,10 @@ typedef struct _Initialize {
char dummy_field; char dummy_field;
} Initialize; } Initialize;
typedef struct _UnlockBootloader {
char dummy_field;
} UnlockBootloader;
typedef struct _ButtonRequest { typedef struct _ButtonRequest {
bool has_code; bool has_code;
ButtonRequestType code; ButtonRequestType code;
@ -135,8 +135,8 @@ typedef struct _Success {
/* Helper constants for enums */ /* Helper constants for enums */
#define _MessageType_MIN MessageType_MessageType_Initialize #define _MessageType_MIN MessageType_MessageType_Initialize
#define _MessageType_MAX MessageType_MessageType_AttestationDelete #define _MessageType_MAX MessageType_MessageType_UnlockBootloader
#define _MessageType_ARRAYSIZE ((MessageType)(MessageType_MessageType_AttestationDelete+1)) #define _MessageType_ARRAYSIZE ((MessageType)(MessageType_MessageType_UnlockBootloader+1))
#define _FailureType_MIN FailureType_Failure_UnexpectedMessage #define _FailureType_MIN FailureType_Failure_UnexpectedMessage
#define _FailureType_MAX FailureType_Failure_ProcessError #define _FailureType_MAX FailureType_Failure_ProcessError
@ -163,7 +163,7 @@ extern "C" {
#define FirmwareErase_init_default {false, 0} #define FirmwareErase_init_default {false, 0}
#define FirmwareRequest_init_default {0, 0} #define FirmwareRequest_init_default {0, 0}
#define FirmwareUpload_init_default {{{NULL}, NULL}, false, {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 Initialize_init_zero {0}
#define GetFeatures_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} #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 FirmwareErase_init_zero {false, 0}
#define FirmwareRequest_init_zero {0, 0} #define FirmwareRequest_init_zero {0, 0}
#define FirmwareUpload_init_zero {{{NULL}, NULL}, false, {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) */ /* Field tags (for use in manual encoding/decoding) */
#define ButtonRequest_code_tag 1 #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_CALLBACK pb_default_field_callback
#define FirmwareUpload_DEFAULT NULL #define FirmwareUpload_DEFAULT NULL
#define AttestationDelete_FIELDLIST(X, a) \ #define UnlockBootloader_FIELDLIST(X, a) \
#define AttestationDelete_CALLBACK NULL #define UnlockBootloader_CALLBACK NULL
#define AttestationDelete_DEFAULT NULL #define UnlockBootloader_DEFAULT NULL
extern const pb_msgdesc_t Initialize_msg; extern const pb_msgdesc_t Initialize_msg;
extern const pb_msgdesc_t GetFeatures_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 FirmwareErase_msg;
extern const pb_msgdesc_t FirmwareRequest_msg; extern const pb_msgdesc_t FirmwareRequest_msg;
extern const pb_msgdesc_t FirmwareUpload_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 */ /* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define Initialize_fields &Initialize_msg #define Initialize_fields &Initialize_msg
@ -315,11 +315,10 @@ extern const pb_msgdesc_t AttestationDelete_msg;
#define FirmwareErase_fields &FirmwareErase_msg #define FirmwareErase_fields &FirmwareErase_msg
#define FirmwareRequest_fields &FirmwareRequest_msg #define FirmwareRequest_fields &FirmwareRequest_msg
#define FirmwareUpload_fields &FirmwareUpload_msg #define FirmwareUpload_fields &FirmwareUpload_msg
#define AttestationDelete_fields &AttestationDelete_msg #define UnlockBootloader_fields &UnlockBootloader_msg
/* Maximum encoded size of messages (where known) */ /* Maximum encoded size of messages (where known) */
/* FirmwareUpload_size depends on runtime parameters */ /* FirmwareUpload_size depends on runtime parameters */
#define AttestationDelete_size 0
#define ButtonAck_size 0 #define ButtonAck_size 0
#define ButtonRequest_size 2 #define ButtonRequest_size 2
#define Failure_size 260 #define Failure_size 260
@ -330,6 +329,7 @@ extern const pb_msgdesc_t AttestationDelete_msg;
#define Initialize_size 0 #define Initialize_size 0
#define Ping_size 258 #define Ping_size 258
#define Success_size 258 #define Success_size 258
#define UnlockBootloader_size 0
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

@ -17,7 +17,7 @@ enum MessageType {
MessageType_ButtonRequest = 26; MessageType_ButtonRequest = 26;
MessageType_ButtonAck = 27; MessageType_ButtonAck = 27;
MessageType_GetFeatures = 55; 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 * @start
* @next Success * @next Success
* @next Failure * @next Failure
*/ */
message AttestationDelete { message UnlockBootloader {
} }

@ -25,6 +25,6 @@ uint32_t screen_install_fail(void);
void screen_welcome_model(void); void screen_welcome_model(void);
void screen_welcome(void); void screen_welcome(void);
void screen_boot_empty(bool fading); void screen_boot_empty(bool fading);
uint32_t screen_attestation_delete_confirm(void); uint32_t screen_unlock_bootloader_confirm(void);
void screen_attestation_delete_success(void); void screen_unlock_bootloader_success(void);
void display_image(int16_t x, int16_t y, const uint8_t* data, uint32_t datalen); void display_image(int16_t x, int16_t y, const uint8_t* data, uint32_t datalen);

@ -39,6 +39,7 @@ pub struct Confirm<'a> {
buttons: ButtonController<&'static str>, buttons: ButtonController<&'static str>,
/// Whether we are on the info screen (optional extra screen) /// Whether we are on the info screen (optional extra screen)
showing_info_screen: bool, showing_info_screen: bool,
two_btn_confirm: bool,
} }
impl<'a> Confirm<'a> { impl<'a> Confirm<'a> {
@ -48,8 +49,10 @@ impl<'a> Confirm<'a> {
message: Label<&'a str>, message: Label<&'a str>,
alert: Option<Label<&'a str>>, alert: Option<Label<&'a str>>,
button_text: &'static str, button_text: &'static str,
two_btn_confirm: bool,
) -> Self { ) -> 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 { Self {
bg: Pad::with_background(bg_color).with_clear(), bg: Pad::with_background(bg_color).with_clear(),
bg_color, bg_color,
@ -61,6 +64,7 @@ impl<'a> Confirm<'a> {
button_text, button_text,
buttons: ButtonController::new(btn_layout), buttons: ButtonController::new(btn_layout),
showing_info_screen: false, showing_info_screen: false,
two_btn_confirm,
} }
} }
@ -81,6 +85,7 @@ impl<'a> Confirm<'a> {
self.showing_info_screen, self.showing_info_screen,
self.button_text, self.button_text,
self.has_info_screen(), self.has_info_screen(),
self.two_btn_confirm,
) )
} }
@ -89,11 +94,14 @@ impl<'a> Confirm<'a> {
showing_info_screen: bool, showing_info_screen: bool,
button_text: &'static str, button_text: &'static str,
has_info_screen: bool, has_info_screen: bool,
two_btn_confirm: bool,
) -> ButtonLayout<&'static str> { ) -> ButtonLayout<&'static str> {
if showing_info_screen { if showing_info_screen {
ButtonLayout::arrow_none_none() ButtonLayout::arrow_none_none()
} else if has_info_screen { } else if has_info_screen {
ButtonLayout::cancel_armed_info(button_text) ButtonLayout::cancel_armed_info(button_text)
} else if two_btn_confirm {
ButtonLayout::cancel_armed_none(button_text)
} else { } else {
ButtonLayout::cancel_none_text(button_text) ButtonLayout::cancel_none_text(button_text)
} }
@ -166,6 +174,14 @@ impl<'a> Component for Confirm<'a> {
} }
_ => None, _ => 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 { } else {
// There is just one main screen without info screen // There is just one main screen without info screen
match msg { match msg {

@ -150,7 +150,7 @@ extern "C" fn screen_install_confirm(
theme::TEXT_NORMAL, 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); .with_info_screen("FW FINGERPRINT", fingerprint);
run(&mut frame) 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) let message = Label::left_aligned("Seed and firmware will be erased!", theme::TEXT_NORMAL)
.vertically_centered(); .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) run(&mut frame)
} }
#[no_mangle] #[no_mangle]
extern "C" fn screen_attestation_delete_confirm() -> u32 { extern "C" fn screen_unlock_bootloader_confirm() -> u32 {
let message = Label::left_aligned( let message = Label::left_aligned("This action cannot be undone!", theme::TEXT_NORMAL)
"Are you sure you want to delete the attestation from this device?", .vertically_centered();
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) run(&mut frame)
} }
#[no_mangle] #[no_mangle]
extern "C" fn screen_attestation_delete_success() { extern "C" fn screen_unlock_bootloader_success() {
let title = Label::centered("Attestation deleted", theme::TEXT_BOLD).vertically_centered(); let title = Label::centered("Bootloader unlocked", theme::TEXT_BOLD).vertically_centered();
let content = let content =
Label::centered("Please reconnect the\ndevice", theme::TEXT_NORMAL).vertically_centered(); Label::centered("Please reconnect the\ndevice", theme::TEXT_NORMAL).vertically_centered();

@ -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. /// Left back arrow and middle armed text.
pub fn arrow_armed_none(text: T) -> Self { pub fn arrow_armed_none(text: T) -> Self {
Self::new( Self::new(

@ -47,7 +47,7 @@ FirmwareHash = 89
UnlockPath = 93 UnlockPath = 93
UnlockedPathRequest = 94 UnlockedPathRequest = 94
ShowDeviceTutorial = 95 ShowDeviceTutorial = 95
AttestationDelete = 96 UnlockBootloader = 96
FirmwareErase = 6 FirmwareErase = 6
FirmwareUpload = 7 FirmwareUpload = 7
FirmwareRequest = 8 FirmwareRequest = 8

@ -64,7 +64,7 @@ if TYPE_CHECKING:
UnlockPath = 93 UnlockPath = 93
UnlockedPathRequest = 94 UnlockedPathRequest = 94
ShowDeviceTutorial = 95 ShowDeviceTutorial = 95
AttestationDelete = 96 UnlockBootloader = 96
SetU2FCounter = 63 SetU2FCounter = 63
GetNextU2FCounter = 80 GetNextU2FCounter = 80
NextU2FCounter = 81 NextU2FCounter = 81

@ -2628,10 +2628,10 @@ if TYPE_CHECKING:
def is_type_of(cls, msg: Any) -> TypeGuard["ShowDeviceTutorial"]: def is_type_of(cls, msg: Any) -> TypeGuard["ShowDeviceTutorial"]:
return isinstance(msg, cls) return isinstance(msg, cls)
class AttestationDelete(protobuf.MessageType): class UnlockBootloader(protobuf.MessageType):
@classmethod @classmethod
def is_type_of(cls, msg: Any) -> TypeGuard["AttestationDelete"]: def is_type_of(cls, msg: Any) -> TypeGuard["UnlockBootloader"]:
return isinstance(msg, cls) return isinstance(msg, cls)
class DebugLinkDecision(protobuf.MessageType): class DebugLinkDecision(protobuf.MessageType):

@ -8,7 +8,7 @@ SKIPPED_MESSAGES := Binance Cardano DebugMonero Eos Monero Ontology Ripple SdPro
TxAckInput TxAckOutput TxAckPrev TxAckPaymentRequest \ TxAckInput TxAckOutput TxAckPrev TxAckPaymentRequest \
EthereumSignTypedData EthereumTypedDataStructRequest EthereumTypedDataStructAck \ EthereumSignTypedData EthereumTypedDataStructRequest EthereumTypedDataStructAck \
EthereumTypedDataValueRequest EthereumTypedDataValueAck ShowDeviceTutorial \ EthereumTypedDataValueRequest EthereumTypedDataValueAck ShowDeviceTutorial \
AttestationDelete UnlockBootloader
ifeq ($(BITCOIN_ONLY), 1) ifeq ($(BITCOIN_ONLY), 1)
SKIPPED_MESSAGES += Ethereum NEM Stellar SKIPPED_MESSAGES += Ethereum NEM Stellar

@ -301,9 +301,9 @@ def tutorial(client: "TrezorClient") -> str:
@cli.command() @cli.command()
@with_client @with_client
def attestation_delete(client: "TrezorClient") -> str: def unlock_bootloader(client: "TrezorClient") -> str:
"""Delete device attestation. Irreversible.""" """Unlocks bootloader. Irreversible."""
return device.attestation_delete(client) return device.unlock_bootloader(client)
@cli.command() @cli.command()

@ -250,8 +250,8 @@ def show_device_tutorial(client: "TrezorClient") -> "MessageType":
@session @session
@expect(messages.Success, field="message", ret_type=str) @expect(messages.Success, field="message", ret_type=str)
def attestation_delete(client: "TrezorClient") -> "MessageType": def unlock_bootloader(client: "TrezorClient") -> "MessageType":
return client.call(messages.AttestationDelete()) return client.call(messages.UnlockBootloader())
@expect(messages.Success, field="message", ret_type=str) @expect(messages.Success, field="message", ret_type=str)

@ -72,7 +72,7 @@ class MessageType(IntEnum):
UnlockPath = 93 UnlockPath = 93
UnlockedPathRequest = 94 UnlockedPathRequest = 94
ShowDeviceTutorial = 95 ShowDeviceTutorial = 95
AttestationDelete = 96 UnlockBootloader = 96
SetU2FCounter = 63 SetU2FCounter = 63
GetNextU2FCounter = 80 GetNextU2FCounter = 80
NextU2FCounter = 81 NextU2FCounter = 81
@ -3738,7 +3738,7 @@ class ShowDeviceTutorial(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 95 MESSAGE_WIRE_TYPE = 95
class AttestationDelete(protobuf.MessageType): class UnlockBootloader(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 96 MESSAGE_WIRE_TYPE = 96

Loading…
Cancel
Save