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

[no changelog]
tychovrahe 10 months ago committed by Andrew Kozlik
parent 74759310bb
commit 324502cc17

@ -516,3 +516,12 @@ message UnlockedPathRequest {
*/
message ShowDeviceTutorial {
}
/**
* Request: Delete attestation from the device, !irreversible!
* @start
* @next Success
* @next Failure
*/
message AttestationDelete {
}

@ -121,6 +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_SetU2FCounter = 63 [(wire_in) = true];
MessageType_GetNextU2FCounter = 80 [(wire_in) = true];

@ -20,7 +20,7 @@ if TREZOR_MODEL in ('1', ):
)
Return()
FEATURES_WANTED = ["input", "rgb_led", "consumption_mask", "usb"]
FEATURES_WANTED = ["input", "rgb_led", "consumption_mask", "usb", "optiga"]
CCFLAGS_MOD = ''
CPPPATH_MOD = []

@ -92,6 +92,20 @@ SOURCE_MOD += [
'vendor/trezor-storage/flash_common.c',
]
if TREZOR_MODEL in ('1', ):
SOURCE_MOD += [
'embed/models/model_T1B1_layout.c',
]
elif TREZOR_MODEL in ('T', ):
SOURCE_MOD += [
'embed/models/model_T2T1_layout.c',
]
elif TREZOR_MODEL in ('R', ):
SOURCE_MOD += [
'embed/models/model_T2B1_layout.c',
]
SOURCE_NANOPB = [
'vendor/nanopb/pb_common.c',
'vendor/nanopb/pb_decode.c',
@ -114,6 +128,7 @@ SOURCE_TREZORHAL = [
'embed/trezorhal/unix/rng.c',
'embed/trezorhal/unix/usb.c',
'embed/trezorhal/unix/random_delays.c',
'embed/trezorhal/unix/secret.c',
]
SOURCE_UNIX = [

@ -17,7 +17,7 @@ if TREZOR_MODEL in ('DISC1', ):
action=build_prodtest)
Return()
FEATURES_WANTED = ["input", "sbu", "sd_card", "rdb_led", "usb"]
FEATURES_WANTED = ["input", "sbu", "sd_card", "rdb_led", "usb", "consumption_mask", "optiga"]
CCFLAGS_MOD = ''
CPPPATH_MOD = []

@ -26,6 +26,7 @@
#include "image.h"
#include "random_delays.h"
#include "secbool.h"
#include "secret.h"
#ifdef USE_DMA2D
#include "dma2d.h"
@ -522,6 +523,19 @@ int bootloader_main(void) {
&FIRMWARE_AREA),
"Firmware is corrupted");
#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");
display_refresh();
return 1;
}
#endif
// if all VTRUST flags are unset = ultimate trust => skip the procedure
if ((vhdr.vtrust & VTRUST_ALL) != VTRUST_ALL) {

@ -11,4 +11,8 @@
#define FIX_VERSION_PATCH 0
#define FIX_VERSION_BUILD 0
#ifdef TREZOR_MODEL_R
#define VERSION_MONOTONIC 2
#else
#define VERSION_MONOTONIC 1
#endif

@ -165,10 +165,7 @@ int main(void) {
#endif
#if !defined TREZOR_MODEL_1
// jump to unprivileged mode
// http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/CHDBIBGJ.html
__asm__ volatile("msr control, %0" ::"r"(0x1));
__asm__ volatile("isb");
drop_privileges();
#endif
#ifdef USE_SECP256K1_ZKP

@ -56,6 +56,8 @@ typedef struct {
#define VTRUST_RED 0x0010
#define VTRUST_CLICK 0x0020
#define VTRUST_STRING 0x0040
#define VTRUST_SECRET \
0x0080 // inverse logic, if set, don't allow to run with secret present
#define VTRUST_ALL (VTRUST_WAIT | VTRUST_RED | VTRUST_CLICK | VTRUST_STRING)
typedef struct {

@ -14,6 +14,7 @@
extern const flash_area_t STORAGE_AREAS[STORAGE_AREAS_COUNT];
extern const flash_area_t BOARDLOADER_AREA;
extern const flash_area_t SECRET_AREA;
extern const flash_area_t BOOTLOADER_AREA;
extern const flash_area_t FIRMWARE_AREA;
extern const flash_area_t WIPE_AREA;

@ -0,0 +1,87 @@
#include "flash.h"
#include "model.h"
const flash_area_t STORAGE_AREAS[STORAGE_AREAS_COUNT] = {
{
.num_subareas = 1,
.subarea[0] =
{
.first_sector = 4,
.num_sectors = 1,
},
},
{
.num_subareas = 1,
.subarea[0] =
{
.first_sector = 16,
.num_sectors = 1,
},
},
};
const flash_area_t BOARDLOADER_AREA = {
.num_subareas = 1,
.subarea[0] =
{
.first_sector = 0,
.num_sectors = 3,
},
};
const flash_area_t SECRET_AREA = {
.num_subareas = 1,
.subarea[0] =
{
.first_sector = 12,
.num_sectors = 1,
},
};
const flash_area_t BOOTLOADER_AREA = {
.num_subareas = 1,
.subarea[0] =
{
.first_sector = 5,
.num_sectors = 1,
},
};
const flash_area_t FIRMWARE_AREA = {
.num_subareas = 2,
.subarea[0] =
{
.first_sector = 6,
.num_sectors = 6,
},
.subarea[1] =
{
.first_sector = 17,
.num_sectors = 7,
},
};
const flash_area_t WIPE_AREA = {
.num_subareas = 4,
.subarea[0] =
{
.first_sector = 4,
.num_sectors = 1,
},
.subarea[1] =
{
.first_sector = 6,
.num_sectors = 6,
},
.subarea[2] =
{
.first_sector = 13,
.num_sectors = 2, // sector 15 skipped due to bootloader MPU
// settings, sector 12 is secret
},
.subarea[3] =
{
.first_sector = 16,
.num_sectors = 8,
},
};

@ -30,15 +30,24 @@
#include "i2c.h"
#include "mini_printf.h"
#include "model.h"
#include "mpu.h"
#include "random_delays.h"
#include "rng.h"
#include "sbu.h"
#include "sdcard.h"
#include "secbool.h"
#include "secret.h"
#include "touch.h"
#include "usb.h"
#ifdef USE_OPTIGA
#include "optiga_commands.h"
#include "optiga_hal.h"
#include "optiga_transport.h"
#endif
#include "memzero.h"
#include "stm32f4xx_ll_utils.h"
#ifdef TREZOR_MODEL_T
#define MODEL_IDENTIFIER "TREZOR2-"
@ -91,6 +100,15 @@ static void vcp_readline(char *buf, size_t len) {
}
}
static void vcp_printf_ex(const char *fmt, ...) {
static char buf[128];
va_list va;
va_start(va, fmt);
int r = mini_vsnprintf(buf, sizeof(buf), fmt, va);
va_end(va);
vcp_puts(buf, r);
}
static void vcp_printf(const char *fmt, ...) {
static char buf[128];
va_list va;
@ -101,6 +119,45 @@ static void vcp_printf(const char *fmt, ...) {
vcp_puts("\r\n", 2);
}
static void vcp_write_as_hex(uint8_t *data, uint16_t len) {
for (int i = 0; i < len; i++) {
vcp_printf_ex("%02X", data[i]);
}
vcp_puts("\r\n", 2);
}
#ifdef USE_OPTIGA
static uint8_t get_byte_from_hex(const char *hex) {
uint8_t result = 0;
for (int i = 0; i < 2; i++) {
result <<= 4;
if (hex[i] >= '0' && hex[i] <= '9') {
result |= hex[i] - '0';
} else if (hex[i] >= 'A' && hex[i] <= 'F') {
result |= hex[i] - 'A' + 10;
} else if (hex[i] >= 'a' && hex[i] <= 'f') {
result |= hex[i] - 'a' + 10;
} else {
return 0;
}
}
return result;
}
static int get_from_hex(uint8_t *buf, uint16_t buf_len, const char *hex) {
int len = 0;
for (int i = 0; i < buf_len; i++) {
uint8_t b = get_byte_from_hex(hex + i * 2);
if (b == 0) {
break;
}
buf[i] = b;
len++;
}
return len;
}
#endif
static void usb_init_all(void) {
enum {
VCP_PACKET_LEN = 64,
@ -185,7 +242,7 @@ static void test_display(const char *colors) {
c = 0xFFFF;
break;
}
display_bar(i * w, 0, i * w + w, 240, c);
display_bar(i * w, 0, i * w + w, DISPLAY_RESY, c);
}
display_refresh();
vcp_printf("OK");
@ -481,6 +538,13 @@ static void test_otp_write(const char *args) {
}
static void test_otp_write_device_variant(const char *args) {
#ifdef USE_OPTIGA
// if (sectrue != is_optiga_locked()) {
// vcp_printf("ERROR: NOT LOCKED");
// return;
// }
#endif
volatile char data[32];
memzero((char *)data, sizeof(data));
data[0] = 1;
@ -516,6 +580,100 @@ static void test_otp_write_device_variant(const char *args) {
vcp_printf("OK");
}
void cpuid_read(void) {
uint32_t cpuid[3];
cpuid[0] = LL_GetUID_Word0();
cpuid[1] = LL_GetUID_Word1();
cpuid[2] = LL_GetUID_Word2();
vcp_write_as_hex((uint8_t *)cpuid, sizeof(cpuid));
}
#ifdef USE_OPTIGA
void pair_optiga(void) {
if (secret_wiped()) {
// secret_write_header();
//
// uint8_t data[] = {0, 0, 0, 0}; // todo replace by real key
//
// secret_write(data, SECRET_OPTIGA_KEY_OFFSET, sizeof(data));
}
}
void optiga_lock(void) {}
void optigaid_read(void) {
uint8_t optiga_id[27];
size_t data_size = 0;
optiga_open_application();
optiga_get_data_object(0xE0C2, false, optiga_id, sizeof(optiga_id),
&data_size);
vcp_write_as_hex(optiga_id, sizeof(optiga_id));
}
void certinf_read(void) {
uint8_t cert[507];
// todo feed real data
for (int i = 0; i < sizeof(cert); i++) {
cert[i] = i;
}
vcp_write_as_hex(cert, sizeof(cert));
}
void certdev_write(char *data) {
// expected 507
uint8_t data_bytes[1024];
int len = get_from_hex(data_bytes, sizeof(data_bytes), data);
(void)len;
// TODO: write to optiga
vcp_printf("OK");
}
void keyfido_handshake(char *data) {
// expected 97
uint8_t data_bytes[1024];
int len = get_from_hex(data_bytes, sizeof(data_bytes), data);
(void)len;
// todo
vcp_printf("OK");
}
void keyfido_write(char *data) {
// expected 81
uint8_t data_bytes[1024];
int len = get_from_hex(data_bytes, sizeof(data_bytes), data);
(void)len;
// todo
vcp_printf("OK");
}
void certfido_write(char *data) {
// expected 465
uint8_t data_bytes[1024];
int len = get_from_hex(data_bytes, sizeof(data_bytes), data);
(void)len;
// todo
vcp_printf("OK");
}
#endif
#define BACKLIGHT_NORMAL 150
int main(void) {
@ -527,8 +685,10 @@ int main(void) {
#ifdef USE_BUTTON
button_init();
#endif
#ifdef USE_TOUCH
#ifdef USE_I2C
i2c_init();
#endif
#ifdef USE_TOUCH
touch_init();
#endif
#ifdef USE_SBU
@ -536,7 +696,18 @@ int main(void) {
#endif
usb_init_all();
#ifdef USE_OPTIGA
optiga_init();
pair_optiga();
// todo authenticate optiga communication
// todo delete optiga pairing key from RAM
#endif
display_reinit();
mpu_config_prodtest();
drop_privileges();
display_clear();
draw_border(1, 3);
@ -551,7 +722,8 @@ int main(void) {
display_fade(0, BACKLIGHT_NORMAL, 1000);
char line[128];
char line[2048]; // expecting hundreds of bytes represented as hexadecimal
// characters
for (;;) {
vcp_readline(line, sizeof(line));
@ -559,6 +731,9 @@ int main(void) {
if (startswith(line, "PING")) {
vcp_printf("OK");
} else if (startswith(line, "CPUID READ")) {
cpuid_read();
} else if (startswith(line, "BORDER")) {
test_border();
@ -584,6 +759,23 @@ int main(void) {
#ifdef USE_SBU
} else if (startswith(line, "SBU ")) {
test_sbu(line + 4);
#endif
#ifdef USE_OPTIGA
} else if (startswith(line, "OPTIGAID READ")) {
optigaid_read();
} else if (startswith(line, "CERTINF READ")) {
certinf_read();
} else if (startswith(line, "CERTDEV WRITE ")) {
certdev_write(line + 14);
} else if (startswith(line, "KEYFIDO HANDSHAKE ")) {
keyfido_handshake(line + 18);
} else if (startswith(line, "KEYFIDO WRITE ")) {
keyfido_write(line + 14);
} else if (startswith(line, "CERTFIDO WRITE ")) {
certfido_write(line + 15);
} else if (startswith(line, "LOCK")) {
optiga_lock();
#endif
} else if (startswith(line, "OTP READ")) {

@ -23,5 +23,6 @@
void mpu_config_off(void);
void mpu_config_bootloader(void);
void mpu_config_firmware(void);
void mpu_config_prodtest(void);
#endif

@ -0,0 +1,18 @@
#include <stdint.h>
#include "secbool.h"
#define SECRET_HEADER_MAGIC "TRZS"
#define SECRET_HEADER_LEN 16
#define SECRET_OPTIGA_KEY_OFFSET 16
#define SECRET_OPTIGA_KEY_LEN 32
void secret_write(uint8_t* data, uint32_t offset, uint32_t len);
secbool secret_read(uint8_t* data, uint32_t offset, uint32_t len);
secbool secret_wiped(void);
void secret_erase(void);
void secret_write_header(void);

@ -125,12 +125,13 @@ void mpu_config_firmware(void) {
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH |
LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS |
MPU_RASR_XN_Msk;
// Storage#2 (0x08110000 - 0x0811FFFF, 64 KiB, read-write, execute never)
// Secret + Storage#2 (0x08100000 - 0x0811FFFF, 16 Kib + 64 KiB, read-write,
// execute never)
MPU->RNR = MPU_REGION_NUMBER2;
MPU->RBAR = FLASH_BASE + 0x110000;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH |
LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS |
MPU_RASR_XN_Msk;
LL_MPU_REGION_SIZE_128KB | LL_MPU_REGION_FULL_ACCESS |
MPU_RASR_XN_Msk | MPU_SUBREGION_DISABLE(0x0E);
// Firmware (0x08040000 - 0x080FFFFF, 6 * 128 KiB = 1024 KiB except 2/8 at
// start = 768 KiB, read-only)
@ -193,3 +194,98 @@ void mpu_config_firmware(void) {
__asm__ volatile("dsb");
__asm__ volatile("isb");
}
void mpu_config_prodtest(void) {
// Disable MPU
HAL_MPU_Disable();
// Note: later entries overwrite previous ones
// // Boardloader (0x08000000 - 0x0800BFFF, 48 KiB, read-only, execute never)
// MPU->RNR = MPU_REGION_NUMBER0;
// MPU->RBAR = FLASH_BASE;
// MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH |
// LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_PRIV_RO_URO |
// MPU_RASR_XN_Msk | MPU_SUBREGION_DISABLE(0xC0);
// Secret area (0x08100000 - 0x08103FFF, 16 KiB, read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER0;
MPU->RBAR = FLASH_BASE + 0x100000;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH |
LL_MPU_REGION_SIZE_16KB | LL_MPU_REGION_FULL_ACCESS |
MPU_RASR_XN_Msk;
// Bootloader (0x08020000 - 0x0803FFFF, 64 KiB, read-only)
MPU->RNR = MPU_REGION_NUMBER1;
MPU->RBAR = FLASH_BASE + 0x20000;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH |
LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_PRIV_RO_URO;
// Firmware (0x08040000 - 0x080FFFFF, 6 * 128 KiB = 1024 KiB except 2/8 at
// start = 768 KiB, read-only)
MPU->RNR = MPU_REGION_NUMBER2;
MPU->RBAR = FLASH_BASE;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH |
LL_MPU_REGION_SIZE_1MB | LL_MPU_REGION_FULL_ACCESS |
MPU_SUBREGION_DISABLE(0x03);
// Firmware extra (0x08120000 - 0x081FFFFF, 7 * 128 KiB = 1024 KiB except 1/8
// at start = 896 KiB, read-only)
MPU->RNR = MPU_REGION_NUMBER3;
MPU->RBAR = FLASH_BASE + 0x100000;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH |
LL_MPU_REGION_SIZE_1MB | LL_MPU_REGION_FULL_ACCESS |
MPU_SUBREGION_DISABLE(0x01);
// SRAM (0x20000000 - 0x2002FFFF, 192 KiB = 256 KiB except 2/8 at end,
// read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER4;
MPU->RBAR = SRAM_BASE;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM |
LL_MPU_REGION_SIZE_256KB | LL_MPU_REGION_FULL_ACCESS |
MPU_RASR_XN_Msk | MPU_SUBREGION_DISABLE(0xC0);
#ifdef USE_SDRAM
// Peripherals (0x40000000 - 0x5FFFFFFF, read-write, execute never)
// SDRAM (0xC0000000 - 0xDFFFFFFF, read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER5;
MPU->RBAR = 0;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_PERIPH |
LL_MPU_REGION_SIZE_4GB | LL_MPU_REGION_FULL_ACCESS |
MPU_RASR_XN_Msk | MPU_SUBREGION_DISABLE(0xBB);
#else
// Peripherals (0x40000000 - 0x5FFFFFFF, read-write, execute never)
// External RAM (0x60000000 - 0x7FFFFFFF, read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER5;
MPU->RBAR = PERIPH_BASE;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_PERIPH |
LL_MPU_REGION_SIZE_1GB | LL_MPU_REGION_FULL_ACCESS |
MPU_RASR_XN_Msk;
#endif
#if defined STM32F427xx || defined STM32F429xx
// CCMRAM (0x10000000 - 0x1000FFFF, read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER6;
MPU->RBAR = CCMDATARAM_BASE;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM |
LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS |
MPU_RASR_XN_Msk;
#elif STM32F405xx
// no CCMRAM
#else
#error Unsupported MCU
#endif
// OTP (0x1FFF7800 - 0x1FFF7C00, read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER7;
MPU->RBAR = FLASH_OTP_BASE;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH |
LL_MPU_REGION_SIZE_1KB | LL_MPU_REGION_FULL_ACCESS |
MPU_RASR_XN_Msk;
// Enable MPU
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
__asm__ volatile("dsb");
__asm__ volatile("isb");
}

@ -195,6 +195,13 @@ void set_core_clock(clock_settings_t settings) {
}
#endif
void drop_privileges(void) {
// jump to unprivileged mode
// http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/CHDBIBGJ.html
__asm__ volatile("msr control, %0" ::"r"(0x1));
__asm__ volatile("isb");
}
// from util.s
extern void shutdown_privileged(void);

@ -40,6 +40,7 @@ void jump_to_unprivileged(uint32_t address);
void jump_to_with_flag(uint32_t address, uint32_t register_flag);
void ensure_compatible_settings(void);
void clear_otg_hs_memory(void);
void drop_privileges(void);
extern uint32_t __stack_chk_guard;

@ -0,0 +1,59 @@
#include "secret.h"
#include <string.h>
#include "common.h"
#include "flash.h"
#include "model.h"
static secbool verify_header(void) {
uint8_t header[SECRET_HEADER_LEN] = {0};
memcpy(header, flash_area_get_address(&SECRET_AREA, 0, SECRET_HEADER_LEN),
SECRET_HEADER_LEN);
return memcmp(header, SECRET_HEADER_MAGIC, 4) == 0 ? sectrue : secfalse;
}
void secret_write_header(void) {
uint8_t header[SECRET_HEADER_LEN] = {0};
memcpy(header, SECRET_HEADER_MAGIC, 4);
secret_write(header, 0, SECRET_HEADER_LEN);
}
void secret_write(uint8_t* data, uint32_t offset, uint32_t len) {
ensure(flash_unlock_write(), "secret write");
for (int i = 0; i < len; i++) {
ensure(flash_area_write_byte(&SECRET_AREA, offset + i, data[i]),
"secret write");
}
ensure(flash_lock_write(), "secret write");
}
secbool secret_read(uint8_t* data, uint32_t offset, uint32_t len) {
if (sectrue != verify_header()) {
return secfalse;
}
memcpy(data, flash_area_get_address(&SECRET_AREA, offset, len), len);
return sectrue;
}
secbool secret_wiped(void) {
flash_area_get_address(&SECRET_AREA, 0, 1);
flash_area_get_size(&SECRET_AREA);
uint32_t size = flash_area_get_size(&SECRET_AREA);
for (int i = 0; i < size; i += 4) {
uint32_t* addr = (uint32_t*)flash_area_get_address(&SECRET_AREA, i, 4);
if (*addr != 0xFFFFFFFF) {
return secfalse;
}
}
return sectrue;
}
void secret_erase(void) {
ensure(flash_area_erase(&SECRET_AREA, NULL), "secret erase");
}

@ -0,0 +1,9 @@
#include "secret.h"
void secret_write(uint8_t* data, uint32_t offset, uint32_t len) {}
void secret_read(uint8_t* data, uint32_t offset, uint32_t len) {}
secbool secret_wiped(void) { return secfalse; }
void secret_erase(void) {}

@ -6,6 +6,7 @@
"version": [0, 1],
"sig_m": 2,
"trust": {
"allow_run_with_secret": false,
"show_vendor_string": true,
"require_user_click": true,
"red_background": true,

@ -0,0 +1,19 @@
{
"header_len": 4608,
"text": "UNSAFE, FACTORY TEST ONLY",
"hw_model": null,
"expiry": 0,
"version": [0, 0],
"sig_m": 2,
"trust": {
"allow_run_with_secret": true,
"show_vendor_string": false,
"require_user_click": false,
"red_background": false,
"delay": 0
},
"pubkeys": [
"c17d221529b70da08aa42ccb1b2cef773736a7d48434209f6eb16b1b474716d2",
"6622ee8403464acfc2fe1e20311937b115e60771f3ee6e70f22bf2921977e534"
]
}

@ -6,6 +6,7 @@
"version": [0, 0],
"sig_m": 2,
"trust": {
"allow_run_with_secret": true,
"show_vendor_string": false,
"require_user_click": false,
"red_background": false,

@ -6,6 +6,7 @@
"version": [0, 0],
"sig_m": 2,
"trust": {
"allow_run_with_secret": true,
"show_vendor_string": false,
"require_user_click": false,
"red_background": false,

@ -6,6 +6,7 @@
"version": [0, 0],
"sig_m": 2,
"trust": {
"allow_run_with_secret": false,
"show_vendor_string": true,
"require_user_click": true,
"red_background": true,

@ -6,6 +6,7 @@
"version": [0, 0],
"sig_m": 2,
"trust": {
"allow_run_with_secret": false,
"show_vendor_string": false,
"require_user_click": false,
"red_background": false,

@ -6,6 +6,7 @@
"version": [0, 0],
"sig_m": 2,
"trust": {
"allow_run_with_secret": false,
"show_vendor_string": false,
"require_user_click": false,
"red_background": false,

@ -6,6 +6,7 @@
"version": [0, 1],
"sig_m": 2,
"trust": {
"allow_run_with_secret": false,
"show_vendor_string": false,
"require_user_click": false,
"red_background": false,

@ -6,6 +6,7 @@
"version": [0, 1],
"sig_m": 2,
"trust": {
"allow_run_with_secret": false,
"show_vendor_string": true,
"require_user_click": true,
"red_background": true,

@ -70,6 +70,7 @@ def configure(
sources += ["embed/trezorhal/stm32f4/optiga_hal.c"]
sources += ["embed/trezorhal/optiga/optiga_commands.c"]
sources += ["embed/trezorhal/optiga/optiga_transport.c"]
sources += ["embed/trezorhal/stm32f4/secret.c"]
env.get("ENV")["TREZOR_BOARD"] = board
env.get("ENV")["MCU_TYPE"] = mcu

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

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

@ -2628,6 +2628,12 @@ if TYPE_CHECKING:
def is_type_of(cls, msg: Any) -> TypeGuard["ShowDeviceTutorial"]:
return isinstance(msg, cls)
class AttestationDelete(protobuf.MessageType):
@classmethod
def is_type_of(cls, msg: Any) -> TypeGuard["AttestationDelete"]:
return isinstance(msg, cls)
class DebugLinkDecision(protobuf.MessageType):
button: "DebugButton | None"
swipe: "DebugSwipeDirection | None"

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

@ -299,6 +299,13 @@ def tutorial(client: "TrezorClient") -> str:
return device.show_device_tutorial(client)
@cli.command()
@with_client
def attestation_delete(client: "TrezorClient") -> str:
"""Delete device attestation. Irreversible."""
return device.attestation_delete(client)
@cli.command()
@click.argument("enable", type=ChoiceType({"on": True, "off": False}), required=False)
@click.option(

@ -248,6 +248,12 @@ def show_device_tutorial(client: "TrezorClient") -> "MessageType":
return client.call(messages.ShowDeviceTutorial())
@session
@expect(messages.Success, field="message", ret_type=str)
def attestation_delete(client: "TrezorClient") -> "MessageType":
return client.call(messages.AttestationDelete())
@expect(messages.Success, field="message", ret_type=str)
@session
def set_busy(client: "TrezorClient", expiry_ms: Optional[int]) -> "MessageType":

@ -47,6 +47,7 @@ def _transform_vendor_trust(data: bytes) -> bytes:
class VendorTrust(Struct):
allow_run_with_secret: bool
show_vendor_string: bool
require_user_click: bool
red_background: bool
@ -56,7 +57,8 @@ class VendorTrust(Struct):
SUBCON = c.Transformed(
c.BitStruct(
"_reserved" / c.Default(c.BitsInteger(9), 0),
"_reserved" / c.Default(c.BitsInteger(8), 0),
"allow_run_with_secret" / c.Flag,
"show_vendor_string" / c.Flag,
"require_user_click" / c.Flag,
"red_background" / c.Flag,

@ -72,6 +72,7 @@ class MessageType(IntEnum):
UnlockPath = 93
UnlockedPathRequest = 94
ShowDeviceTutorial = 95
AttestationDelete = 96
SetU2FCounter = 63
GetNextU2FCounter = 80
NextU2FCounter = 81
@ -3737,6 +3738,10 @@ class ShowDeviceTutorial(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 95
class AttestationDelete(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 96
class DebugLinkDecision(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 100
FIELDS = {

Loading…
Cancel
Save