mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-19 12:58:13 +00:00
fix(core/bootloader): evaluate model before vendor header signature when installing firmware
This commit is contained in:
parent
5417ec15df
commit
a265b0f176
1
core/embed/bootloader/.changelog.d/4081.changed
Normal file
1
core/embed/bootloader/.changelog.d/4081.changed
Normal file
@ -0,0 +1 @@
|
||||
Fix incorrect error message when installing firmware for different model.
|
@ -528,6 +528,14 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size,
|
||||
return UPLOAD_ERR_INVALID_VENDOR_HEADER;
|
||||
}
|
||||
|
||||
if (sectrue != check_vendor_header_model(&vhdr)) {
|
||||
MSG_SEND_INIT(Failure);
|
||||
MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError);
|
||||
MSG_SEND_ASSIGN_STRING(message, "Wrong model");
|
||||
MSG_SEND(Failure);
|
||||
return UPLOAD_ERR_INVALID_VENDOR_HEADER_MODEL;
|
||||
}
|
||||
|
||||
if (sectrue != check_vendor_header_keys(&vhdr)) {
|
||||
MSG_SEND_INIT(Failure);
|
||||
MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError);
|
||||
|
@ -35,6 +35,7 @@ enum {
|
||||
UPLOAD_ERR_INVALID_CHUNK_SIZE = -1,
|
||||
UPLOAD_ERR_INVALID_VENDOR_HEADER = -2,
|
||||
UPLOAD_ERR_INVALID_VENDOR_HEADER_SIG = -3,
|
||||
UPLOAD_ERR_INVALID_VENDOR_HEADER_MODEL = -15,
|
||||
UPLOAD_ERR_INVALID_IMAGE_HEADER = -4,
|
||||
UPLOAD_ERR_INVALID_IMAGE_MODEL = -5,
|
||||
UPLOAD_ERR_INVALID_IMAGE_HEADER_SIG = -6,
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "image.h"
|
||||
#include "model.h"
|
||||
|
||||
_Static_assert(VENDOR_HEADER_MAX_SIZE + IMAGE_HEADER_SIZE <= IMAGE_CHUNK_SIZE);
|
||||
|
||||
const uint8_t BOOTLOADER_KEY_M = 2;
|
||||
const uint8_t BOOTLOADER_KEY_N = 3;
|
||||
static const uint8_t * const BOOTLOADER_KEYS[] = {
|
||||
@ -150,7 +152,7 @@ secbool __wur read_vendor_header(const uint8_t *const data,
|
||||
if (vhdr->magic != 0x565A5254) return secfalse; // TRZV
|
||||
|
||||
memcpy(&vhdr->hdrlen, data + 4, 4);
|
||||
if (vhdr->hdrlen > 64 * 1024) return secfalse;
|
||||
if (vhdr->hdrlen > VENDOR_HEADER_MAX_SIZE) return secfalse;
|
||||
|
||||
memcpy(&vhdr->expiry, data + 8, 4);
|
||||
if (vhdr->expiry != 0) return secfalse;
|
||||
@ -162,6 +164,7 @@ secbool __wur read_vendor_header(const uint8_t *const data,
|
||||
memcpy(&vhdr->vsig_m, data + 14, 1);
|
||||
memcpy(&vhdr->vsig_n, data + 15, 1);
|
||||
memcpy(&vhdr->vtrust, data + 16, 2);
|
||||
memcpy(&vhdr->hw_model, data + 18, 4);
|
||||
|
||||
if (vhdr->vsig_n > MAX_VENDOR_PUBLIC_KEYS) {
|
||||
return secfalse;
|
||||
@ -190,6 +193,20 @@ secbool __wur read_vendor_header(const uint8_t *const data,
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
secbool check_vendor_header_model(const vendor_header *const vhdr) {
|
||||
#ifdef TREZOR_MODEL_T
|
||||
if (vhdr->hw_model == 0) {
|
||||
// vendor headers for model T have this field set to 0
|
||||
return sectrue;
|
||||
}
|
||||
#endif
|
||||
if (vhdr->hw_model == HW_MODEL) {
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
secbool check_vendor_header_sig(const vendor_header *const vhdr, uint8_t key_m,
|
||||
uint8_t key_n, const uint8_t *const *keys) {
|
||||
if (vhdr == NULL) {
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "model.h"
|
||||
#include "secbool.h"
|
||||
|
||||
#define VENDOR_HEADER_MAX_SIZE (64 * 1024)
|
||||
#define IMAGE_HEADER_SIZE 0x400 // size of the bootloader or firmware header
|
||||
#define IMAGE_SIG_SIZE 65
|
||||
#define IMAGE_INIT_CHUNK_SIZE (16 * 1024)
|
||||
@ -88,7 +89,8 @@ typedef struct {
|
||||
uint8_t vsig_m;
|
||||
uint8_t vsig_n;
|
||||
uint16_t vtrust;
|
||||
// uint8_t reserved[14];
|
||||
uint32_t hw_model;
|
||||
// uint8_t reserved[10];
|
||||
const uint8_t *vpub[MAX_VENDOR_PUBLIC_KEYS];
|
||||
uint8_t vstr_len;
|
||||
const char *vstr;
|
||||
@ -127,6 +129,8 @@ secbool __wur check_image_header_sig(const image_header *const hdr,
|
||||
secbool __wur read_vendor_header(const uint8_t *const data,
|
||||
vendor_header *const vhdr);
|
||||
|
||||
secbool __wur check_vendor_header_model(const vendor_header *const vhdr);
|
||||
|
||||
secbool __wur check_vendor_header_sig(const vendor_header *const vhdr,
|
||||
uint8_t key_m, uint8_t key_n,
|
||||
const uint8_t *const *keys);
|
||||
|
Loading…
Reference in New Issue
Block a user