1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-07-08 15:48:08 +00:00

bootloader: check chunk hash before flashing

This commit is contained in:
Pavol Rusnak 2017-10-27 05:09:35 +02:00
parent 36143033c4
commit d0e81edc8f
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
3 changed files with 24 additions and 8 deletions

View File

@ -334,6 +334,7 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *bu
return -1; return -1;
} }
uint32_t firstskip = 0;
if (firmware_block == 0) { if (firmware_block == 0) {
vendor_header vhdr; vendor_header vhdr;
if (sectrue != load_vendor_header_keys(chunk_buffer, &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); MSG_SEND(Failure);
return -3; 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()) { 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_VALUE(code, FailureType_Failure_ProcessError);
MSG_SEND_ASSIGN_STRING(message, "Could not unlock flash"); MSG_SEND_ASSIGN_STRING(message, "Could not unlock flash");
MSG_SEND(Failure); MSG_SEND(Failure);
return -4; return -5;
} }
// TODO: fix writing to non-continous area // 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_ASSIGN_STRING(message, "Could not write data");
MSG_SEND(Failure); MSG_SEND(Failure);
flash_lock(); flash_lock();
return -5; return -6;
} }
} }

View File

@ -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)); 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]; uint8_t h[BLAKE2S_DIGEST_LENGTH];
blake2s(data, len, 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); const void *data = (const void *)(FLASH_SECTOR_TABLE[sectors[0]] + firstskip);
int remaining = hdr->codelen; 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; return secfalse;
} }
int block = 1; int block = 1;
@ -156,7 +156,7 @@ secbool check_image_contents(const image_header * const hdr, uint32_t firstskip,
return secfalse; return secfalse;
} }
data = (const void *)FLASH_SECTOR_TABLE[sectors[block]]; 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; return secfalse;
} }
block++; block++;

View File

@ -13,10 +13,11 @@
#define IMAGE_CHUNK_SIZE (128 * 1024) #define IMAGE_CHUNK_SIZE (128 * 1024)
#define BOOTLOADER_IMAGE_MAGIC 0x425A5254 // TRZB #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_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 { typedef struct {
uint32_t magic; 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 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); secbool check_image_contents(const image_header * const hdr, uint32_t firstskip, const uint8_t *sectors, int blocks);
#endif #endif