1
0
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:
tychovrahe 2024-08-15 12:48:39 +02:00 committed by TychoVrahe
parent 5417ec15df
commit a265b0f176
5 changed files with 33 additions and 2 deletions

View File

@ -0,0 +1 @@
Fix incorrect error message when installing firmware for different model.

View File

@ -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);

View File

@ -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,

View File

@ -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) {

View File

@ -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);