1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-22 07:28:10 +00:00

feat(core): Add bootloader_locked flag to Features message.

[no changelog]
This commit is contained in:
Andrew Kozlik 2023-09-13 15:36:06 +02:00 committed by Andrew Kozlik
parent f881fab797
commit c48b606867
14 changed files with 85 additions and 6 deletions

View File

@ -129,6 +129,7 @@ message Features {
optional bool unit_btconly = 46; // unit/device is intended as bitcoin only optional bool unit_btconly = 46; // unit/device is intended as bitcoin only
optional uint32 homescreen_width = 47; // homescreen width in pixels optional uint32 homescreen_width = 47; // homescreen width in pixels
optional uint32 homescreen_height = 48; // homescreen height in pixels optional uint32 homescreen_height = 48; // homescreen height in pixels
optional bool bootloader_locked = 49; // bootloader is locked
} }
/** /**

View File

@ -131,6 +131,9 @@ SOURCE_TREZORHAL = [
] ]
if TREZOR_MODEL in ('R', ): if TREZOR_MODEL in ('R', ):
CPPDEFINES_MOD += [
('USE_OPTIGA', '1'),
]
SOURCE_TREZORHAL += [ SOURCE_TREZORHAL += [
'embed/trezorhal/unix/secret.c', 'embed/trezorhal/unix/secret.c',
] ]

View File

@ -44,6 +44,10 @@
#include "emulator.h" #include "emulator.h"
#endif #endif
#if USE_OPTIGA
#include "secret.h"
#endif
#define MSG_HEADER1_LEN 9 #define MSG_HEADER1_LEN 9
#define MSG_HEADER2_LEN 1 #define MSG_HEADER2_LEN 1
@ -311,6 +315,11 @@ static void send_msg_features(uint8_t iface_num,
MSG_SEND_ASSIGN_VALUE(unit_color, unit_variant_get_color()); MSG_SEND_ASSIGN_VALUE(unit_color, unit_variant_get_color());
MSG_SEND_ASSIGN_VALUE(unit_btconly, unit_variant_get_btconly()); MSG_SEND_ASSIGN_VALUE(unit_btconly, unit_variant_get_btconly());
} }
#if USE_OPTIGA
MSG_SEND_ASSIGN_VALUE(bootloader_locked,
(secret_bootloader_locked() == sectrue));
#endif
MSG_SEND(Features); MSG_SEND(Features);
} }

View File

@ -103,6 +103,8 @@ typedef struct _Features {
uint32_t unit_color; uint32_t unit_color;
bool has_unit_btconly; bool has_unit_btconly;
bool unit_btconly; bool unit_btconly;
bool has_bootloader_locked;
bool bootloader_locked;
} Features; } Features;
typedef struct _FirmwareErase { typedef struct _FirmwareErase {
@ -154,7 +156,7 @@ extern "C" {
/* Initializer values for message structs */ /* Initializer values for message structs */
#define Initialize_init_default {0} #define Initialize_init_default {0}
#define GetFeatures_init_default {0} #define GetFeatures_init_default {0}
#define Features_init_default {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_default {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, false, 0}
#define Ping_init_default {false, ""} #define Ping_init_default {false, ""}
#define Success_init_default {false, ""} #define Success_init_default {false, ""}
#define Failure_init_default {false, _FailureType_MIN, false, ""} #define Failure_init_default {false, _FailureType_MIN, false, ""}
@ -166,7 +168,7 @@ extern "C" {
#define UnlockBootloader_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, false, 0}
#define Ping_init_zero {false, ""} #define Ping_init_zero {false, ""}
#define Success_init_zero {false, ""} #define Success_init_zero {false, ""}
#define Failure_init_zero {false, _FailureType_MIN, false, ""} #define Failure_init_zero {false, _FailureType_MIN, false, ""}
@ -200,6 +202,7 @@ extern "C" {
#define Features_internal_model_tag 44 #define Features_internal_model_tag 44
#define Features_unit_color_tag 45 #define Features_unit_color_tag 45
#define Features_unit_btconly_tag 46 #define Features_unit_btconly_tag 46
#define Features_bootloader_locked_tag 49
#define FirmwareErase_length_tag 1 #define FirmwareErase_length_tag 1
#define FirmwareRequest_offset_tag 1 #define FirmwareRequest_offset_tag 1
#define FirmwareRequest_length_tag 2 #define FirmwareRequest_length_tag 2
@ -238,7 +241,8 @@ X(a, STATIC, OPTIONAL, UINT32, fw_patch, 24) \
X(a, STATIC, OPTIONAL, STRING, fw_vendor, 25) \ X(a, STATIC, OPTIONAL, STRING, fw_vendor, 25) \
X(a, STATIC, OPTIONAL, STRING, internal_model, 44) \ X(a, STATIC, OPTIONAL, STRING, internal_model, 44) \
X(a, STATIC, OPTIONAL, UINT32, unit_color, 45) \ X(a, STATIC, OPTIONAL, UINT32, unit_color, 45) \
X(a, STATIC, OPTIONAL, BOOL, unit_btconly, 46) X(a, STATIC, OPTIONAL, BOOL, unit_btconly, 46) \
X(a, STATIC, OPTIONAL, BOOL, bootloader_locked, 49)
#define Features_CALLBACK NULL #define Features_CALLBACK NULL
#define Features_DEFAULT NULL #define Features_DEFAULT NULL
@ -322,7 +326,7 @@ extern const pb_msgdesc_t UnlockBootloader_msg;
#define ButtonAck_size 0 #define ButtonAck_size 0
#define ButtonRequest_size 2 #define ButtonRequest_size 2
#define Failure_size 260 #define Failure_size 260
#define Features_size 487 #define Features_size 490
#define FirmwareErase_size 6 #define FirmwareErase_size 6
#define FirmwareRequest_size 12 #define FirmwareRequest_size 12
#define GetFeatures_size 0 #define GetFeatures_size 0

View File

@ -61,6 +61,7 @@ message Features {
optional string internal_model = 44; // internal model name optional string internal_model = 44; // internal model name
optional uint32 unit_color = 45; // color of the unit/device optional uint32 unit_color = 45; // color of the unit/device
optional bool unit_btconly = 46; // unit/device is intended as bitcoin only optional bool unit_btconly = 46; // unit/device is intended as bitcoin only
optional bool bootloader_locked = 49; // bootloader is locked
} }
/** /**

View File

@ -43,6 +43,10 @@
#include "image.h" #include "image.h"
#endif #endif
#if USE_OPTIGA && !defined(TREZOR_EMULATOR)
#include "secret.h"
#endif
static void ui_progress(mp_obj_t ui_wait_callback, uint32_t current, static void ui_progress(mp_obj_t ui_wait_callback, uint32_t current,
uint32_t total) { uint32_t total) {
if (mp_obj_is_callable(ui_wait_callback)) { if (mp_obj_is_callable(ui_wait_callback)) {
@ -254,6 +258,26 @@ STATIC mp_obj_t mod_trezorutils_reboot_to_bootloader() {
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorutils_reboot_to_bootloader_obj, STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorutils_reboot_to_bootloader_obj,
mod_trezorutils_reboot_to_bootloader); mod_trezorutils_reboot_to_bootloader);
/// def bootloader_locked() -> bool | None:
/// """
/// Returns True/False if the the bootloader is locked/unlocked and None if
/// the feature is not supported.
/// """
STATIC mp_obj_t mod_trezorutils_bootloader_locked() {
#if USE_OPTIGA
#ifdef TREZOR_EMULATOR
return mp_const_true;
#else
return (secret_bootloader_locked() == sectrue) ? mp_const_true
: mp_const_false;
#endif
#else
return mp_const_none;
#endif
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorutils_bootloader_locked_obj,
mod_trezorutils_bootloader_locked);
STATIC mp_obj_str_t mod_trezorutils_revision_obj = { STATIC mp_obj_str_t mod_trezorutils_revision_obj = {
{&mp_type_bytes}, 0, sizeof(SCM_REVISION) - 1, (const byte *)SCM_REVISION}; {&mp_type_bytes}, 0, sizeof(SCM_REVISION) - 1, (const byte *)SCM_REVISION};
@ -280,6 +304,8 @@ STATIC const mp_rom_map_elem_t mp_module_trezorutils_globals_table[] = {
MP_ROM_PTR(&mod_trezorutils_firmware_vendor_obj)}, MP_ROM_PTR(&mod_trezorutils_firmware_vendor_obj)},
{MP_ROM_QSTR(MP_QSTR_reboot_to_bootloader), {MP_ROM_QSTR(MP_QSTR_reboot_to_bootloader),
MP_ROM_PTR(&mod_trezorutils_reboot_to_bootloader_obj)}, MP_ROM_PTR(&mod_trezorutils_reboot_to_bootloader_obj)},
{MP_ROM_QSTR(MP_QSTR_bootloader_locked),
MP_ROM_PTR(&mod_trezorutils_bootloader_locked_obj)},
{MP_ROM_QSTR(MP_QSTR_unit_color), {MP_ROM_QSTR(MP_QSTR_unit_color),
MP_ROM_PTR(&mod_trezorutils_unit_color_obj)}, MP_ROM_PTR(&mod_trezorutils_unit_color_obj)},
{MP_ROM_QSTR(MP_QSTR_unit_btconly), {MP_ROM_QSTR(MP_QSTR_unit_btconly),

View File

@ -7,6 +7,8 @@
#define SECRET_OPTIGA_KEY_OFFSET 16 #define SECRET_OPTIGA_KEY_OFFSET 16
#define SECRET_OPTIGA_KEY_LEN 32 #define SECRET_OPTIGA_KEY_LEN 32
secbool secret_bootloader_locked(void);
void secret_write(uint8_t* data, uint32_t offset, uint32_t len); 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_read(uint8_t* data, uint32_t offset, uint32_t len);

View File

@ -4,13 +4,28 @@
#include "flash.h" #include "flash.h"
#include "model.h" #include "model.h"
static secbool bootloader_locked_set = secfalse;
static secbool bootloader_locked = secfalse;
static secbool verify_header(void) { static secbool verify_header(void) {
uint8_t header[SECRET_HEADER_LEN] = {0}; uint8_t header[SECRET_HEADER_LEN] = {0};
memcpy(header, flash_area_get_address(&SECRET_AREA, 0, SECRET_HEADER_LEN), memcpy(header, flash_area_get_address(&SECRET_AREA, 0, SECRET_HEADER_LEN),
SECRET_HEADER_LEN); SECRET_HEADER_LEN);
return memcmp(header, SECRET_HEADER_MAGIC, 4) == 0 ? sectrue : secfalse; bootloader_locked =
memcmp(header, SECRET_HEADER_MAGIC, 4) == 0 ? sectrue : secfalse;
bootloader_locked_set = sectrue;
return bootloader_locked;
}
secbool secret_bootloader_locked(void) {
if (bootloader_locked_set != sectrue) {
// Set bootloader_locked.
verify_header();
}
return bootloader_locked;
} }
void secret_write_header(void) { void secret_write_header(void) {

View File

@ -79,6 +79,14 @@ def reboot_to_bootloader() -> None:
""" """
Reboots to bootloader. Reboots to bootloader.
""" """
# extmod/modtrezorutils/modtrezorutils.c
def bootloader_locked() -> bool | None:
"""
Returns True/False if the the bootloader is locked/unlocked and None if
the feature is not supported.
"""
SCM_REVISION: bytes SCM_REVISION: bytes
VERSION_MAJOR: int VERSION_MAJOR: int
VERSION_MINOR: int VERSION_MINOR: int

View File

@ -66,6 +66,7 @@ def get_features() -> Features:
homescreen_height=HEIGHT, homescreen_height=HEIGHT,
unit_color=utils.unit_color(), unit_color=utils.unit_color(),
unit_btconly=utils.unit_btconly(), unit_btconly=utils.unit_btconly(),
bootloader_locked=utils.bootloader_locked(),
) )
if utils.INTERNAL_MODEL in ("T1B1", "T2B1"): if utils.INTERNAL_MODEL in ("T1B1", "T2B1"):

View File

@ -11,10 +11,13 @@ async def authenticate_device(msg: AuthenticateDevice) -> AuthenticityProof:
from trezor.crypto.hashlib import sha256 from trezor.crypto.hashlib import sha256
from trezor.messages import AuthenticityProof from trezor.messages import AuthenticityProof
from trezor.ui.layouts import confirm_action from trezor.ui.layouts import confirm_action
from trezor.utils import BufferReader from trezor.utils import BufferReader, bootloader_locked
from apps.common.writers import write_compact_size from apps.common.writers import write_compact_size
if not bootloader_locked():
raise wire.ProcessError("Cannot authenticate since bootloader is unlocked.")
await confirm_action( await confirm_action(
"authenticate_device", "authenticate_device",
"Authenticate device", "Authenticate device",

View File

@ -2128,6 +2128,7 @@ if TYPE_CHECKING:
unit_btconly: "bool | None" unit_btconly: "bool | None"
homescreen_width: "int | None" homescreen_width: "int | None"
homescreen_height: "int | None" homescreen_height: "int | None"
bootloader_locked: "bool | None"
def __init__( def __init__(
self, self,
@ -2177,6 +2178,7 @@ if TYPE_CHECKING:
unit_btconly: "bool | None" = None, unit_btconly: "bool | None" = None,
homescreen_width: "int | None" = None, homescreen_width: "int | None" = None,
homescreen_height: "int | None" = None, homescreen_height: "int | None" = None,
bootloader_locked: "bool | None" = None,
) -> None: ) -> None:
pass pass

View File

@ -12,6 +12,7 @@ from trezorutils import ( # noqa: F401
VERSION_MAJOR, VERSION_MAJOR,
VERSION_MINOR, VERSION_MINOR,
VERSION_PATCH, VERSION_PATCH,
bootloader_locked,
consteq, consteq,
firmware_hash, firmware_hash,
firmware_vendor, firmware_vendor,

View File

@ -3190,6 +3190,7 @@ class Features(protobuf.MessageType):
46: protobuf.Field("unit_btconly", "bool", repeated=False, required=False, default=None), 46: protobuf.Field("unit_btconly", "bool", repeated=False, required=False, default=None),
47: protobuf.Field("homescreen_width", "uint32", repeated=False, required=False, default=None), 47: protobuf.Field("homescreen_width", "uint32", repeated=False, required=False, default=None),
48: protobuf.Field("homescreen_height", "uint32", repeated=False, required=False, default=None), 48: protobuf.Field("homescreen_height", "uint32", repeated=False, required=False, default=None),
49: protobuf.Field("bootloader_locked", "bool", repeated=False, required=False, default=None),
} }
def __init__( def __init__(
@ -3241,6 +3242,7 @@ class Features(protobuf.MessageType):
unit_btconly: Optional["bool"] = None, unit_btconly: Optional["bool"] = None,
homescreen_width: Optional["int"] = None, homescreen_width: Optional["int"] = None,
homescreen_height: Optional["int"] = None, homescreen_height: Optional["int"] = None,
bootloader_locked: Optional["bool"] = None,
) -> None: ) -> None:
self.capabilities: Sequence["Capability"] = capabilities if capabilities is not None else [] self.capabilities: Sequence["Capability"] = capabilities if capabilities is not None else []
self.major_version = major_version self.major_version = major_version
@ -3288,6 +3290,7 @@ class Features(protobuf.MessageType):
self.unit_btconly = unit_btconly self.unit_btconly = unit_btconly
self.homescreen_width = homescreen_width self.homescreen_width = homescreen_width
self.homescreen_height = homescreen_height self.homescreen_height = homescreen_height
self.bootloader_locked = bootloader_locked
class LockDevice(protobuf.MessageType): class LockDevice(protobuf.MessageType):