diff --git a/embed/bootloader/messages.c b/embed/bootloader/messages.c index b1008a5ce3..d27bcc3f28 100644 --- a/embed/bootloader/messages.c +++ b/embed/bootloader/messages.c @@ -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; } } diff --git a/embed/trezorhal/image.c b/embed/trezorhal/image.c index 74cee0480f..c20e0ebaa6 100644 --- a/embed/trezorhal/image.c +++ b/embed/trezorhal/image.c @@ -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++; diff --git a/embed/trezorhal/image.h b/embed/trezorhal/image.h index 04570bbebb..87bc75bedc 100644 --- a/embed/trezorhal/image.h +++ b/embed/trezorhal/image.h @@ -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_MAGIC 0x465A5254 // TRZF +#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