mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-02 10:51:06 +00:00
bootloader: check chunk hash before flashing
This commit is contained in:
parent
36143033c4
commit
d0e81edc8f
@ -334,6 +334,7 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *bu
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t firstskip = 0;
|
||||
if (firmware_block == 0) {
|
||||
vendor_header vhdr;
|
||||
if (sectrue != load_vendor_header_keys(chunk_buffer, &vhdr)) {
|
||||
@ -350,6 +351,18 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *bu
|
||||
MSG_SEND(Failure);
|
||||
return -3;
|
||||
}
|
||||
|
||||
// TODO: erase storage if vendor is being changed
|
||||
|
||||
firstskip = IMAGE_HEADER_SIZE + vhdr.hdrlen;
|
||||
}
|
||||
|
||||
if (sectrue != check_single_hash(hdr.hashes + firmware_block * 32, chunk_buffer + firstskip, chunk_size - firstskip)) {
|
||||
MSG_SEND_INIT(Failure);
|
||||
MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError);
|
||||
MSG_SEND_ASSIGN_STRING(message, "Invalid chunk hash");
|
||||
MSG_SEND(Failure);
|
||||
return -4;
|
||||
}
|
||||
|
||||
if (sectrue != flash_unlock()) {
|
||||
@ -357,7 +370,7 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *bu
|
||||
MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError);
|
||||
MSG_SEND_ASSIGN_STRING(message, "Could not unlock flash");
|
||||
MSG_SEND(Failure);
|
||||
return -4;
|
||||
return -5;
|
||||
}
|
||||
|
||||
// TODO: fix writing to non-continous area
|
||||
@ -369,7 +382,7 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *bu
|
||||
MSG_SEND_ASSIGN_STRING(message, "Could not write data");
|
||||
MSG_SEND(Failure);
|
||||
flash_lock();
|
||||
return -5;
|
||||
return -6;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,7 +130,7 @@ secbool load_vendor_header(const uint8_t * const data, uint8_t key_m, uint8_t ke
|
||||
return sectrue * (0 == ed25519_sign_open(hash, BLAKE2S_DIGEST_LENGTH, pub, *(const ed25519_signature *)vhdr->sig));
|
||||
}
|
||||
|
||||
static secbool check_hash(const uint8_t * const hash, const uint8_t * const data, int len)
|
||||
secbool check_single_hash(const uint8_t * const hash, const uint8_t * const data, int len)
|
||||
{
|
||||
uint8_t h[BLAKE2S_DIGEST_LENGTH];
|
||||
blake2s(data, len, h, BLAKE2S_DIGEST_LENGTH);
|
||||
@ -146,7 +146,7 @@ secbool check_image_contents(const image_header * const hdr, uint32_t firstskip,
|
||||
}
|
||||
const void *data = (const void *)(FLASH_SECTOR_TABLE[sectors[0]] + firstskip);
|
||||
int remaining = hdr->codelen;
|
||||
if (sectrue != check_hash(hdr->hashes, data, MIN(remaining, IMAGE_CHUNK_SIZE - firstskip))) {
|
||||
if (sectrue != check_single_hash(hdr->hashes, data, MIN(remaining, IMAGE_CHUNK_SIZE - firstskip))) {
|
||||
return secfalse;
|
||||
}
|
||||
int block = 1;
|
||||
@ -156,7 +156,7 @@ secbool check_image_contents(const image_header * const hdr, uint32_t firstskip,
|
||||
return secfalse;
|
||||
}
|
||||
data = (const void *)FLASH_SECTOR_TABLE[sectors[block]];
|
||||
if (sectrue != check_hash(hdr->hashes + block * 32, data, MIN(remaining, IMAGE_CHUNK_SIZE))) {
|
||||
if (sectrue != check_single_hash(hdr->hashes + block * 32, data, MIN(remaining, IMAGE_CHUNK_SIZE))) {
|
||||
return secfalse;
|
||||
}
|
||||
block++;
|
||||
|
@ -13,10 +13,11 @@
|
||||
#define IMAGE_CHUNK_SIZE (128 * 1024)
|
||||
|
||||
#define BOOTLOADER_IMAGE_MAGIC 0x425A5254 // TRZB
|
||||
#define BOOTLOADER_IMAGE_MAXSIZE (1 * 128 * 1024)
|
||||
#define BOOTLOADER_IMAGE_MAXSIZE (1 * IMAGE_CHUNK_SIZE)
|
||||
|
||||
#define FIRMWARE_IMAGE_MAGIC 0x465A5254 // TRZF
|
||||
#define FIRMWARE_IMAGE_MAXSIZE (6 * 128 * 1024)
|
||||
#define FIRMWARE_IMAGE_MAXSIZE (6 * IMAGE_CHUNK_SIZE)
|
||||
// TODO: change above limitation to 13 blocks after fixing writing to non-continuous area
|
||||
|
||||
typedef struct {
|
||||
uint32_t magic;
|
||||
@ -54,6 +55,8 @@ secbool load_image_header(const uint8_t * const data, const uint32_t magic, cons
|
||||
|
||||
secbool load_vendor_header(const uint8_t * const data, uint8_t key_m, uint8_t key_n, const uint8_t * const *keys, vendor_header * const vhdr);
|
||||
|
||||
secbool check_single_hash(const uint8_t * const hash, const uint8_t * const data, int len);
|
||||
|
||||
secbool check_image_contents(const image_header * const hdr, uint32_t firstskip, const uint8_t *sectors, int blocks);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user