mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-21 23:18:13 +00:00
embed/bootloader: add information about firmware (version, vendor, etc.) to Features message
This commit is contained in:
parent
548b8cb25b
commit
1c5beb1c12
@ -150,6 +150,9 @@ static secbool bootloader_usb_loop(const vendor_header * const vhdr, const image
|
||||
return sectrue; // jump to firmware
|
||||
}
|
||||
break;
|
||||
case 55: // GetFeatures
|
||||
process_msg_GetFeatures(USB_IFACE_NUM, msg_size, buf, vhdr, hdr);
|
||||
break;
|
||||
default:
|
||||
process_msg_unknown(USB_IFACE_NUM, msg_size, buf);
|
||||
break;
|
||||
|
@ -140,9 +140,13 @@ static secbool _send_msg(uint8_t iface_num, uint16_t msg_id, const pb_field_t fi
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
#define MSG_SEND_INIT(TYPE) TYPE msg_send = TYPE##_init_default
|
||||
#define MSG_SEND_ASSIGN_VALUE(FIELD, VALUE) { msg_send.has_##FIELD = true; msg_send.FIELD = VALUE; }
|
||||
#define MSG_SEND_ASSIGN_STRING(FIELD, VALUE) { msg_send.has_##FIELD = true; memset(msg_send.FIELD, 0, sizeof(msg_send.FIELD)); strncpy(msg_send.FIELD, VALUE, sizeof(msg_send.FIELD) - 1); }
|
||||
#define MSG_SEND_ASSIGN_STRING_LEN(FIELD, VALUE, LEN) { msg_send.has_##FIELD = true; memset(msg_send.FIELD, 0, sizeof(msg_send.FIELD)); strncpy(msg_send.FIELD, VALUE, MIN(LEN, sizeof(msg_send.FIELD) - 1)); }
|
||||
#define MSG_SEND_ASSIGN_BYTES(FIELD, VALUE, LEN) { msg_send.has_##FIELD = true; memset(msg_send.FIELD.bytes, 0, sizeof(msg_send.FIELD.bytes)); memcpy(msg_send.FIELD.bytes, VALUE, MIN(LEN, sizeof(msg_send.FIELD.bytes))); msg_send.FIELD.size = MIN(LEN, sizeof(msg_send.FIELD.bytes)); }
|
||||
#define MSG_SEND(TYPE) _send_msg(iface_num, MessageType_MessageType_##TYPE, TYPE##_fields, &msg_send)
|
||||
|
||||
typedef struct {
|
||||
@ -227,23 +231,46 @@ void send_user_abort(uint8_t iface_num, const char *msg)
|
||||
MSG_SEND(Failure);
|
||||
}
|
||||
|
||||
void process_msg_Initialize(uint8_t iface_num, uint32_t msg_size, uint8_t *buf, const vendor_header * const vhdr, const image_header * const hdr)
|
||||
static void send_msg_features(uint8_t iface_num, const vendor_header * const vhdr, const image_header * const hdr)
|
||||
{
|
||||
MSG_RECV_INIT(Initialize);
|
||||
MSG_RECV(Initialize);
|
||||
|
||||
MSG_SEND_INIT(Features);
|
||||
MSG_SEND_ASSIGN_STRING(vendor, "trezor.io");
|
||||
MSG_SEND_ASSIGN_VALUE(major_version, VERSION_MAJOR);
|
||||
MSG_SEND_ASSIGN_VALUE(minor_version, VERSION_MINOR);
|
||||
MSG_SEND_ASSIGN_VALUE(patch_version, VERSION_PATCH);
|
||||
MSG_SEND_ASSIGN_VALUE(bootloader_mode, true);
|
||||
MSG_SEND_ASSIGN_VALUE(firmware_present, (vhdr && hdr));
|
||||
MSG_SEND_ASSIGN_STRING(model, "T");
|
||||
if (vhdr && hdr) {
|
||||
MSG_SEND_ASSIGN_VALUE(firmware_present, true);
|
||||
MSG_SEND_ASSIGN_VALUE(fw_major, (hdr->version & 0xFF));
|
||||
MSG_SEND_ASSIGN_VALUE(fw_minor, ((hdr->version >> 8) & 0xFF));
|
||||
MSG_SEND_ASSIGN_VALUE(fw_patch, ((hdr->version >> 16) & 0xFF));
|
||||
MSG_SEND_ASSIGN_STRING_LEN(fw_vendor, vhdr->vstr, vhdr->vstr_len);
|
||||
uint8_t hash[32];
|
||||
vendor_keys_hash(vhdr, hash);
|
||||
MSG_SEND_ASSIGN_BYTES(fw_vendor_keys, hash, 32);
|
||||
} else {
|
||||
MSG_SEND_ASSIGN_VALUE(firmware_present, false);
|
||||
}
|
||||
|
||||
// TODO: pass info about installed firmware (vendor, version, etc.)
|
||||
MSG_SEND(Features);
|
||||
}
|
||||
|
||||
void process_msg_Initialize(uint8_t iface_num, uint32_t msg_size, uint8_t *buf, const vendor_header * const vhdr, const image_header * const hdr)
|
||||
{
|
||||
MSG_RECV_INIT(Initialize);
|
||||
MSG_RECV(Initialize);
|
||||
send_msg_features(iface_num, vhdr, hdr);
|
||||
}
|
||||
|
||||
void process_msg_GetFeatures(uint8_t iface_num, uint32_t msg_size, uint8_t *buf, const vendor_header * const vhdr, const image_header * const hdr)
|
||||
{
|
||||
MSG_RECV_INIT(GetFeatures);
|
||||
MSG_RECV(GetFeatures);
|
||||
send_msg_features(iface_num, vhdr, hdr);
|
||||
}
|
||||
|
||||
void process_msg_Ping(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
|
||||
{
|
||||
MSG_RECV_INIT(Ping);
|
||||
|
@ -17,6 +17,7 @@ secbool msg_parse_header(const uint8_t *buf, uint16_t *msg_id, uint32_t *msg_siz
|
||||
void send_user_abort(uint8_t iface_num, const char *msg);
|
||||
|
||||
void process_msg_Initialize(uint8_t iface_num, uint32_t msg_size, uint8_t *buf, const vendor_header * const vhdr, const image_header * const hdr);
|
||||
void process_msg_GetFeatures(uint8_t iface_num, uint32_t msg_size, uint8_t *buf, const vendor_header * const vhdr, const image_header * const hdr);
|
||||
void process_msg_Ping(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
|
||||
void process_msg_FirmwareErase(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
|
||||
int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
|
||||
|
@ -5,6 +5,8 @@ Features.label max_size:33
|
||||
Features.revision max_size:20
|
||||
Features.bootloader_hash max_size:32
|
||||
Features.model max_size:17
|
||||
Features.fw_vendor max_size:256
|
||||
Features.fw_vendor_keys max_size:32
|
||||
|
||||
Ping.message max_size:256
|
||||
|
||||
|
@ -18,25 +18,24 @@ const pb_field_t GetFeatures_fields[1] = {
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
const pb_field_t Features_fields[19] = {
|
||||
const pb_field_t Features_fields[18] = {
|
||||
PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, Features, vendor, vendor, 0),
|
||||
PB_FIELD( 2, UINT32 , OPTIONAL, STATIC , OTHER, Features, major_version, vendor, 0),
|
||||
PB_FIELD( 3, UINT32 , OPTIONAL, STATIC , OTHER, Features, minor_version, major_version, 0),
|
||||
PB_FIELD( 4, UINT32 , OPTIONAL, STATIC , OTHER, Features, patch_version, minor_version, 0),
|
||||
PB_FIELD( 5, BOOL , OPTIONAL, STATIC , OTHER, Features, bootloader_mode, patch_version, 0),
|
||||
PB_FIELD( 6, STRING , OPTIONAL, STATIC , OTHER, Features, device_id, bootloader_mode, 0),
|
||||
PB_FIELD( 7, BOOL , OPTIONAL, STATIC , OTHER, Features, pin_protection, device_id, 0),
|
||||
PB_FIELD( 8, BOOL , OPTIONAL, STATIC , OTHER, Features, passphrase_protection, pin_protection, 0),
|
||||
PB_FIELD( 9, STRING , OPTIONAL, STATIC , OTHER, Features, language, passphrase_protection, 0),
|
||||
PB_FIELD( 9, STRING , OPTIONAL, STATIC , OTHER, Features, language, device_id, 0),
|
||||
PB_FIELD( 10, STRING , OPTIONAL, STATIC , OTHER, Features, label, language, 0),
|
||||
PB_FIELD( 12, BOOL , OPTIONAL, STATIC , OTHER, Features, initialized, label, 0),
|
||||
PB_FIELD( 13, BYTES , OPTIONAL, STATIC , OTHER, Features, revision, initialized, 0),
|
||||
PB_FIELD( 14, BYTES , OPTIONAL, STATIC , OTHER, Features, bootloader_hash, revision, 0),
|
||||
PB_FIELD( 15, BOOL , OPTIONAL, STATIC , OTHER, Features, imported, bootloader_hash, 0),
|
||||
PB_FIELD( 16, BOOL , OPTIONAL, STATIC , OTHER, Features, pin_cached, imported, 0),
|
||||
PB_FIELD( 17, BOOL , OPTIONAL, STATIC , OTHER, Features, passphrase_cached, pin_cached, 0),
|
||||
PB_FIELD( 18, BOOL , OPTIONAL, STATIC , OTHER, Features, firmware_present, passphrase_cached, 0),
|
||||
PB_FIELD( 18, BOOL , OPTIONAL, STATIC , OTHER, Features, firmware_present, revision, 0),
|
||||
PB_FIELD( 21, STRING , OPTIONAL, STATIC , OTHER, Features, model, firmware_present, 0),
|
||||
PB_FIELD( 22, UINT32 , OPTIONAL, STATIC , OTHER, Features, fw_major, model, 0),
|
||||
PB_FIELD( 23, UINT32 , OPTIONAL, STATIC , OTHER, Features, fw_minor, fw_major, 0),
|
||||
PB_FIELD( 24, UINT32 , OPTIONAL, STATIC , OTHER, Features, fw_patch, fw_minor, 0),
|
||||
PB_FIELD( 25, STRING , OPTIONAL, STATIC , OTHER, Features, fw_vendor, fw_patch, 0),
|
||||
PB_FIELD( 26, BYTES , OPTIONAL, STATIC , OTHER, Features, fw_vendor_keys, fw_vendor, 0),
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
|
@ -67,7 +67,7 @@ typedef struct _Failure {
|
||||
} Failure;
|
||||
|
||||
typedef PB_BYTES_ARRAY_T(20) Features_revision_t;
|
||||
typedef PB_BYTES_ARRAY_T(32) Features_bootloader_hash_t;
|
||||
typedef PB_BYTES_ARRAY_T(32) Features_fw_vendor_keys_t;
|
||||
typedef struct _Features {
|
||||
bool has_vendor;
|
||||
char vendor[33];
|
||||
@ -81,10 +81,6 @@ typedef struct _Features {
|
||||
bool bootloader_mode;
|
||||
bool has_device_id;
|
||||
char device_id[25];
|
||||
bool has_pin_protection;
|
||||
bool pin_protection;
|
||||
bool has_passphrase_protection;
|
||||
bool passphrase_protection;
|
||||
bool has_language;
|
||||
char language[17];
|
||||
bool has_label;
|
||||
@ -93,18 +89,20 @@ typedef struct _Features {
|
||||
bool initialized;
|
||||
bool has_revision;
|
||||
Features_revision_t revision;
|
||||
bool has_bootloader_hash;
|
||||
Features_bootloader_hash_t bootloader_hash;
|
||||
bool has_imported;
|
||||
bool imported;
|
||||
bool has_pin_cached;
|
||||
bool pin_cached;
|
||||
bool has_passphrase_cached;
|
||||
bool passphrase_cached;
|
||||
bool has_firmware_present;
|
||||
bool firmware_present;
|
||||
bool has_model;
|
||||
char model[17];
|
||||
bool has_fw_major;
|
||||
uint32_t fw_major;
|
||||
bool has_fw_minor;
|
||||
uint32_t fw_minor;
|
||||
bool has_fw_patch;
|
||||
uint32_t fw_patch;
|
||||
bool has_fw_vendor;
|
||||
char fw_vendor[256];
|
||||
bool has_fw_vendor_keys;
|
||||
Features_fw_vendor_keys_t fw_vendor_keys;
|
||||
/* @@protoc_insertion_point(struct:Features) */
|
||||
} Features;
|
||||
|
||||
@ -153,7 +151,7 @@ typedef struct _Success {
|
||||
/* Initializer values for message structs */
|
||||
#define Initialize_init_default {0}
|
||||
#define GetFeatures_init_default {0}
|
||||
#define Features_init_default {false, "", false, 0, false, 0, false, 0, false, 0, false, "", false, 0, false, 0, false, "", false, "", false, 0, false, {0, {0}}, false, {0, {0}}, false, 0, false, 0, false, 0, false, 0, false, ""}
|
||||
#define Features_init_default {false, "", false, 0, false, 0, false, 0, false, 0, false, "", false, "", false, "", false, 0, false, {0, {0}}, false, 0, false, "", false, 0, false, 0, false, 0, false, "", false, {0, {0}}}
|
||||
#define Ping_init_default {false, "", false, 0, false, 0, false, 0}
|
||||
#define Success_init_default {false, ""}
|
||||
#define Failure_init_default {false, (FailureType)0, false, ""}
|
||||
@ -164,7 +162,7 @@ typedef struct _Success {
|
||||
#define FirmwareUpload_init_default {{{NULL}, NULL}, false, {0, {0}}}
|
||||
#define Initialize_init_zero {0}
|
||||
#define GetFeatures_init_zero {0}
|
||||
#define Features_init_zero {false, "", false, 0, false, 0, false, 0, false, 0, false, "", false, 0, false, 0, false, "", false, "", false, 0, false, {0, {0}}, false, {0, {0}}, false, 0, false, 0, false, 0, false, 0, false, ""}
|
||||
#define Features_init_zero {false, "", false, 0, false, 0, false, 0, false, 0, false, "", false, "", false, "", false, 0, false, {0, {0}}, false, 0, false, "", false, 0, false, 0, false, 0, false, "", false, {0, {0}}}
|
||||
#define Ping_init_zero {false, "", false, 0, false, 0, false, 0}
|
||||
#define Success_init_zero {false, ""}
|
||||
#define Failure_init_zero {false, (FailureType)0, false, ""}
|
||||
@ -185,18 +183,17 @@ typedef struct _Success {
|
||||
#define Features_patch_version_tag 4
|
||||
#define Features_bootloader_mode_tag 5
|
||||
#define Features_device_id_tag 6
|
||||
#define Features_pin_protection_tag 7
|
||||
#define Features_passphrase_protection_tag 8
|
||||
#define Features_language_tag 9
|
||||
#define Features_label_tag 10
|
||||
#define Features_initialized_tag 12
|
||||
#define Features_revision_tag 13
|
||||
#define Features_bootloader_hash_tag 14
|
||||
#define Features_imported_tag 15
|
||||
#define Features_pin_cached_tag 16
|
||||
#define Features_passphrase_cached_tag 17
|
||||
#define Features_firmware_present_tag 18
|
||||
#define Features_model_tag 21
|
||||
#define Features_fw_major_tag 22
|
||||
#define Features_fw_minor_tag 23
|
||||
#define Features_fw_patch_tag 24
|
||||
#define Features_fw_vendor_tag 25
|
||||
#define Features_fw_vendor_keys_tag 26
|
||||
#define FirmwareErase_length_tag 1
|
||||
#define FirmwareRequest_offset_tag 1
|
||||
#define FirmwareRequest_length_tag 2
|
||||
@ -211,7 +208,7 @@ typedef struct _Success {
|
||||
/* Struct field encoding specification for nanopb */
|
||||
extern const pb_field_t Initialize_fields[1];
|
||||
extern const pb_field_t GetFeatures_fields[1];
|
||||
extern const pb_field_t Features_fields[19];
|
||||
extern const pb_field_t Features_fields[18];
|
||||
extern const pb_field_t Ping_fields[5];
|
||||
extern const pb_field_t Success_fields[2];
|
||||
extern const pb_field_t Failure_fields[3];
|
||||
@ -224,7 +221,7 @@ extern const pb_field_t FirmwareUpload_fields[3];
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define Initialize_size 0
|
||||
#define GetFeatures_size 0
|
||||
#define Features_size 229
|
||||
#define Features_size 499
|
||||
#define Ping_size 265
|
||||
#define Success_size 259
|
||||
#define Failure_size 270
|
||||
|
@ -37,27 +37,32 @@ message GetFeatures {
|
||||
* @prev GetFeatures
|
||||
*/
|
||||
message Features {
|
||||
optional string vendor = 1; // name of the manufacturer, e.g. "bitcointrezor.com"
|
||||
optional uint32 major_version = 2; // major version of the device, e.g. 1
|
||||
optional uint32 minor_version = 3; // minor version of the device, e.g. 0
|
||||
optional uint32 patch_version = 4; // patch version of the device, e.g. 0
|
||||
optional string vendor = 1; // name of the manufacturer, e.g. "trezor.io"
|
||||
optional uint32 major_version = 2; // major version of the firmware/bootloader, e.g. 1
|
||||
optional uint32 minor_version = 3; // minor version of the firmware/bootloader, e.g. 0
|
||||
optional uint32 patch_version = 4; // patch version of the firmware/bootloader, e.g. 0
|
||||
optional bool bootloader_mode = 5; // is device in bootloader mode?
|
||||
optional string device_id = 6; // device's unique identifier
|
||||
optional bool pin_protection = 7; // is device protected by PIN?
|
||||
optional bool passphrase_protection = 8; // is node/mnemonic encrypted using passphrase?
|
||||
// optional bool pin_protection = 7; // is device protected by PIN?
|
||||
// optional bool passphrase_protection = 8; // is node/mnemonic encrypted using passphrase?
|
||||
optional string language = 9; // device language
|
||||
optional string label = 10; // device description label
|
||||
// repeated CoinType coins = 11; // supported coins
|
||||
optional bool initialized = 12; // does device contain seed?
|
||||
optional bytes revision = 13; // SCM revision of firmware
|
||||
optional bytes bootloader_hash = 14; // hash of the bootloader
|
||||
optional bool imported = 15; // was storage imported from an external source?
|
||||
optional bool pin_cached = 16; // is PIN already cached in session?
|
||||
optional bool passphrase_cached = 17; // is passphrase already cached in session?
|
||||
// optional bytes bootloader_hash = 14; // hash of the bootloader
|
||||
// optional bool imported = 15; // was storage imported from an external source?
|
||||
// optional bool pin_cached = 16; // is PIN already cached in session?
|
||||
// optional bool passphrase_cached = 17; // is passphrase already cached in session?
|
||||
optional bool firmware_present = 18; // is valid firmware loaded?
|
||||
// optional bool needs_backup = 19; // does storage need backup? (equals to Storage.needs_backup)
|
||||
// optional uint32 flags = 20; // device flags (equals to Storage.flags)
|
||||
optional string model = 21; // device hardware model
|
||||
optional uint32 fw_major = 22; // reported firmware version if in bootloader mode
|
||||
optional uint32 fw_minor = 23; // reported firmware version if in bootloader mode
|
||||
optional uint32 fw_patch = 24; // reported firmware version if in bootloader mode
|
||||
optional string fw_vendor = 25; // reported firmware vendor if in bootloader mode
|
||||
optional bytes fw_vendor_keys = 26; // reported firmware vendor keys (their hash)
|
||||
}
|
||||
|
||||
/**
|
||||
|
11
tools/binctl
11
tools/binctl
@ -219,6 +219,7 @@ class VendorHeader(object):
|
||||
for i in range(self.vsig_n):
|
||||
print(' * vpub #%d :' % (i + 1), binascii.hexlify(self.vpub[i]).decode())
|
||||
print(' * vstr :', self.vstr.decode())
|
||||
print(' * vhash :', binascii.hexlify(self.vhash()).decode())
|
||||
print(' * vimg : (%d bytes)' % len(self.vimg))
|
||||
print(' * sigmask :', format_sigmask(self.sigmask))
|
||||
print(' * sig :', binascii.hexlify(self.sig).decode())
|
||||
@ -246,6 +247,16 @@ class VendorHeader(object):
|
||||
def fingerprint(self):
|
||||
return pyblake2.blake2s(self.serialize_header(sig=False)).hexdigest()
|
||||
|
||||
def vhash(self):
|
||||
h = pyblake2.blake2s()
|
||||
h.update(struct.pack('<BB', self.vsig_m, self.vsig_n))
|
||||
for i in range(8):
|
||||
if i < self.vsig_n:
|
||||
h.update(self.vpub[i])
|
||||
else:
|
||||
h.update(b'\x00' * 32)
|
||||
return h.digest()
|
||||
|
||||
def sign(self, sigmask, signature):
|
||||
header = self.serialize_header(sig=False)
|
||||
assert len(header) == self.hdrlen
|
||||
|
2
vendor/trezor-common
vendored
2
vendor/trezor-common
vendored
@ -1 +1 @@
|
||||
Subproject commit 13499e256acfdde662b98ea402146ca105fb03b3
|
||||
Subproject commit 8652df0c692ea4f13042539dcb6bde57b79137bc
|
Loading…
Reference in New Issue
Block a user