mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-23 13:02:03 +00:00
feat(core): add bootloader unlocking functionality to U5 optiga models
This commit is contained in:
parent
cc9e74772b
commit
d334b92073
1
core/embed/bootloader/.changelog.d/4133.changed
Normal file
1
core/embed/bootloader/.changelog.d/4133.changed
Normal file
@ -0,0 +1 @@
|
||||
[T3B1, T3T1] Added bootloader unlock mechanism to U5 models
|
@ -220,7 +220,7 @@ static usb_result_t bootloader_usb_loop(const vendor_header *const vhdr,
|
||||
case MessageType_MessageType_GetFeatures:
|
||||
process_msg_GetFeatures(USB_IFACE_NUM, msg_size, buf, vhdr, hdr);
|
||||
break;
|
||||
#if defined USE_OPTIGA && !defined STM32U5
|
||||
#if defined USE_OPTIGA
|
||||
case MessageType_MessageType_UnlockBootloader:
|
||||
response = ui_screen_unlock_bootloader_confirm();
|
||||
if (INPUT_CANCEL == response) {
|
||||
|
@ -662,8 +662,8 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size,
|
||||
is_ilu = sectrue;
|
||||
}
|
||||
|
||||
#if defined USE_OPTIGA && !defined STM32U5
|
||||
if (sectrue != secret_wiped() &&
|
||||
#if defined USE_OPTIGA
|
||||
if (secfalse != secret_optiga_present() &&
|
||||
((vhdr.vtrust & VTRUST_SECRET_MASK) != VTRUST_SECRET_ALLOW)) {
|
||||
MSG_SEND_INIT(Failure);
|
||||
MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError);
|
||||
@ -868,10 +868,10 @@ void process_msg_unknown(uint8_t iface_num, uint32_t msg_size, uint8_t *buf) {
|
||||
MSG_SEND(Failure);
|
||||
}
|
||||
|
||||
#if defined USE_OPTIGA && !defined STM32U5
|
||||
#if defined USE_OPTIGA
|
||||
void process_msg_UnlockBootloader(uint8_t iface_num, uint32_t msg_size,
|
||||
uint8_t *buf) {
|
||||
secret_erase();
|
||||
secret_optiga_erase();
|
||||
MSG_SEND_INIT(Success);
|
||||
MSG_SEND(Success);
|
||||
}
|
||||
|
@ -315,11 +315,32 @@ impl UIFeaturesBootloader for ModelMercuryFeatures {
|
||||
}
|
||||
|
||||
fn screen_unlock_bootloader_confirm() -> u32 {
|
||||
unimplemented!();
|
||||
let title =
|
||||
Label::left_aligned("UNLOCK BOOTLOADER".into(), TEXT_BOLD).vertically_centered();
|
||||
let msg = Label::centered("This action cannot be undone!".into(), TEXT_NORMAL);
|
||||
|
||||
let right = Button::with_text("UNLOCK".into())
|
||||
.styled(button_confirm())
|
||||
.with_text_align(Alignment::Center);
|
||||
let left = Button::with_text("CANCEL".into())
|
||||
.styled(button_bld())
|
||||
.with_text_align(Alignment::Center);
|
||||
|
||||
let mut frame = Confirm::new(BLD_BG, left, right, ConfirmTitle::Text(title), msg);
|
||||
|
||||
run(&mut frame)
|
||||
}
|
||||
|
||||
fn screen_unlock_bootloader_success() {
|
||||
unimplemented!();
|
||||
let mut frame = ResultScreen::new(
|
||||
&RESULT_FW_INSTALL,
|
||||
Icon::new(CHECK40),
|
||||
"Bootloader unlocked".into(),
|
||||
Label::centered(RECONNECT_MESSAGE.into(), RESULT_FW_INSTALL.title_style())
|
||||
.vertically_centered(),
|
||||
true,
|
||||
);
|
||||
show(&mut frame, true);
|
||||
}
|
||||
|
||||
fn screen_menu(firmware_present: secbool) -> u32 {
|
||||
|
@ -17,7 +17,7 @@ use super::{
|
||||
|
||||
const ICON_TOP: i16 = 23;
|
||||
const TITLE_AREA_START: i16 = 70;
|
||||
const MESSAGE_AREA_START: i16 = 116;
|
||||
const MESSAGE_AREA_START: i16 = 90;
|
||||
|
||||
#[cfg(feature = "bootloader")]
|
||||
const STYLE: &ResultStyle = &crate::ui::model_mercury::theme::bootloader::RESULT_WIPE;
|
||||
@ -34,7 +34,7 @@ pub struct ErrorScreen<'a> {
|
||||
impl<'a> ErrorScreen<'a> {
|
||||
pub fn new(title: TString<'a>, message: TString<'a>, footer: TString<'a>) -> Self {
|
||||
let title = Label::centered(title, STYLE.title_style());
|
||||
let message = Label::centered(message, STYLE.message_style());
|
||||
let message = Label::centered(message, STYLE.message_style()).vertically_centered();
|
||||
let footer = ResultFooter::new(
|
||||
Label::centered(footer, STYLE.title_style()).vertically_centered(),
|
||||
STYLE,
|
||||
|
@ -52,6 +52,12 @@ secbool secret_optiga_set(const uint8_t secret[SECRET_OPTIGA_KEY_LEN]);
|
||||
// was made unavailable by calling secret_optiga_hide
|
||||
secbool secret_optiga_get(uint8_t dest[SECRET_OPTIGA_KEY_LEN]);
|
||||
|
||||
// Checks if the optiga pairing secret is present in the secret storage
|
||||
secbool secret_optiga_present(void);
|
||||
|
||||
// Erases optiga pairing secret from the secret storage
|
||||
void secret_optiga_erase(void);
|
||||
|
||||
// Regenerates the BHK and writes it to the secret storage
|
||||
void secret_bhk_regenerate(void);
|
||||
|
||||
|
@ -98,6 +98,12 @@ secbool secret_optiga_get(uint8_t dest[SECRET_OPTIGA_KEY_LEN]) {
|
||||
return secret_read(dest, SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN);
|
||||
}
|
||||
|
||||
secbool secret_optiga_present(void) {
|
||||
return (sectrue != secret_wiped()) * sectrue;
|
||||
}
|
||||
|
||||
void secret_optiga_erase(void) { secret_erase(); }
|
||||
|
||||
void secret_prepare_fw(secbool allow_run_with_secret, secbool _trust_all) {
|
||||
#ifdef USE_OPTIGA
|
||||
if (sectrue != allow_run_with_secret && sectrue != secret_wiped()) {
|
||||
|
@ -102,7 +102,9 @@ static secbool secret_present(uint32_t offset, uint32_t len) {
|
||||
int secret_empty_bytes = 0;
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (secret[i] == 0xFF) {
|
||||
// 0xFF being the default value of the flash memory (before any write)
|
||||
// 0x00 being the value of the flash memory after manual erase
|
||||
if (secret[i] == 0xFF || secret[i] == 0x00) {
|
||||
secret_empty_bytes++;
|
||||
}
|
||||
}
|
||||
@ -164,7 +166,7 @@ void secret_bhk_regenerate(void) {
|
||||
// This functions only works when software has access to the secret storage,
|
||||
// i.e. in bootloader. Access to secret storage is restricted by calling
|
||||
// secret_hide.
|
||||
static secbool secret_optiga_present(void) {
|
||||
secbool secret_optiga_present(void) {
|
||||
return secret_present(SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN);
|
||||
}
|
||||
|
||||
@ -235,6 +237,11 @@ static void secret_optiga_uncache(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void secret_optiga_erase(void) {
|
||||
uint8_t value[SECRET_OPTIGA_KEY_LEN] = {0};
|
||||
secret_write(value, SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN);
|
||||
}
|
||||
|
||||
void secret_erase(void) {
|
||||
ensure(flash_area_erase(&SECRET_AREA, NULL), "secret erase");
|
||||
}
|
||||
@ -263,6 +270,9 @@ void secret_prepare_fw(secbool allow_run_with_secret, secbool trust_all) {
|
||||
secret_disable_access();
|
||||
}
|
||||
} else {
|
||||
if (secfalse != secret_optiga_present()) {
|
||||
show_install_restricted_screen();
|
||||
}
|
||||
secret_disable_access();
|
||||
}
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user