diff --git a/embed/bootloader/main.c b/embed/bootloader/main.c index d04b97f921..00d18042d5 100644 --- a/embed/bootloader/main.c +++ b/embed/bootloader/main.c @@ -362,23 +362,8 @@ int main(void) load_image_header((const uint8_t *)(FIRMWARE_START + vhdr.hdrlen), FIRMWARE_IMAGE_MAGIC, FIRMWARE_IMAGE_MAXSIZE, vhdr.vsig_m, vhdr.vsig_n, vhdr.vpub, &hdr), "invalid firmware header"); - const uint8_t sectors[] = { - FLASH_SECTOR_FIRMWARE_START, - 7, - 8, - 9, - 10, - FLASH_SECTOR_FIRMWARE_END, - FLASH_SECTOR_FIRMWARE_EXTRA_START, - 18, - 19, - 20, - 21, - 22, - FLASH_SECTOR_FIRMWARE_EXTRA_END, - }; ensure( - check_image_contents(&hdr, IMAGE_HEADER_SIZE + vhdr.hdrlen, sectors, 13), + check_image_contents(&hdr, IMAGE_HEADER_SIZE + vhdr.hdrlen, firmware_sectors, FIRMWARE_SECTORS_COUNT), "invalid firmware hash"); // if all VTRUST flags are unset = ultimate trust => skip the procedure diff --git a/embed/bootloader/messages.c b/embed/bootloader/messages.c index debd6d7c2c..fdbc09bc94 100644 --- a/embed/bootloader/messages.c +++ b/embed/bootloader/messages.c @@ -19,6 +19,22 @@ #define MSG_HEADER1_LEN 9 #define MSG_HEADER2_LEN 1 +const uint8_t firmware_sectors[FIRMWARE_SECTORS_COUNT] = { + FLASH_SECTOR_FIRMWARE_START, + 7, + 8, + 9, + 10, + FLASH_SECTOR_FIRMWARE_END, + FLASH_SECTOR_FIRMWARE_EXTRA_START, + 18, + 19, + 20, + 21, + 22, + FLASH_SECTOR_FIRMWARE_EXTRA_END, +}; + secbool msg_parse_header(const uint8_t *buf, uint16_t *msg_id, uint32_t *msg_size) { if (buf[0] != '?' || buf[1] != '#' || buf[2] != '#') { @@ -260,24 +276,9 @@ void process_msg_FirmwareErase(uint8_t iface_num, uint32_t msg_size, uint8_t *bu MSG_RECV(FirmwareErase); firmware_remaining = msg_recv.has_length ? msg_recv.length : 0; - if (firmware_remaining > 0 && firmware_remaining % 4 == 0) { + if ((firmware_remaining > 0) && ((firmware_remaining % 4) == 0) && (firmware_remaining <= (FIRMWARE_SECTORS_COUNT * IMAGE_CHUNK_SIZE))) { // erase flash - const uint8_t sectors[] = { - FLASH_SECTOR_FIRMWARE_START, - 7, - 8, - 9, - 10, - FLASH_SECTOR_FIRMWARE_END, - FLASH_SECTOR_FIRMWARE_EXTRA_START, - 18, - 19, - 20, - 21, - 22, - FLASH_SECTOR_FIRMWARE_EXTRA_END, - }; - if (sectrue != flash_erase_sectors(sectors, sizeof(sectors), progress_erase)) { + if (sectrue != flash_erase_sectors(firmware_sectors, FIRMWARE_SECTORS_COUNT, progress_erase)) { MSG_SEND_INIT(Failure); MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError); MSG_SEND_ASSIGN_STRING(message, "Could not erase flash"); @@ -418,6 +419,15 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *bu firstskip = IMAGE_HEADER_SIZE + vhdr.hdrlen; } + // should not happen, but double-check + if (firmware_block >= FIRMWARE_SECTORS_COUNT) { + MSG_SEND_INIT(Failure); + MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError); + MSG_SEND_ASSIGN_STRING(message, "Firmware too big"); + MSG_SEND(Failure); + return -3; + } + 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); @@ -428,10 +438,9 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *bu ensure(flash_unlock(), NULL); - // TODO: fix writing to non-continous area const uint32_t * const src = (const uint32_t * const)chunk_buffer; for (int i = 0; i < chunk_size / sizeof(uint32_t); i++) { - ensure(flash_write_word(FIRMWARE_START + firmware_block * IMAGE_CHUNK_SIZE + i * sizeof(uint32_t), src[i]), NULL); + ensure(flash_write_word_rel(firmware_sectors[firmware_block], i * sizeof(uint32_t), src[i]), NULL); } ensure(flash_lock(), NULL); diff --git a/embed/bootloader/messages.h b/embed/bootloader/messages.h index 16534db91b..279b07bbeb 100644 --- a/embed/bootloader/messages.h +++ b/embed/bootloader/messages.h @@ -10,6 +10,9 @@ #define USB_PACKET_SIZE 64 #define USB_IFACE_NUM 0 +#define FIRMWARE_SECTORS_COUNT 13 +extern const uint8_t firmware_sectors[FIRMWARE_SECTORS_COUNT]; + secbool msg_parse_header(const uint8_t *buf, uint16_t *msg_id, uint32_t *msg_size); void process_msg_Initialize(uint8_t iface_num, uint32_t msg_size, uint8_t *buf, secbool firmware_present);