From dc276d1520f91c44ac7ba22aa2a591510f76469b Mon Sep 17 00:00:00 2001 From: tychovrahe Date: Tue, 6 Aug 2024 13:15:24 +0200 Subject: [PATCH] fix(core/bootloader): fix firmware update on stm32u5a [no changelog] --- core/embed/boardloader/main.c | 16 +++++++++++++--- core/embed/bootloader/messages.c | 15 ++++++++++++++- core/embed/bootloader/messages.h | 1 + core/embed/bootloader_ci/messages.c | 2 +- core/embed/lib/image.c | 2 +- 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/core/embed/boardloader/main.c b/core/embed/boardloader/main.c index 6f5d3eee3..321297d4d 100644 --- a/core/embed/boardloader/main.c +++ b/core/embed/boardloader/main.c @@ -175,9 +175,19 @@ static uint32_t check_sdcard(void) { _Static_assert(IMAGE_CHUNK_SIZE >= BOOTLOADER_IMAGE_MAXSIZE, "BOOTLOADER IMAGE MAXSIZE too large for IMAGE_CHUNK_SIZE"); - if (sectrue != (check_single_hash( - hdr->hashes, ((const uint8_t *)sdcard_buf) + hdr->hdrlen, - hdr->codelen))) { + const uint32_t headers_end_offset = hdr->hdrlen; + const uint32_t code_start_offset = IMAGE_CODE_ALIGN(headers_end_offset); + + for (uint32_t i = headers_end_offset; i < code_start_offset; i++) { + if (((uint8_t *)sdcard_buf)[i] != 0) { + return 0; + } + } + + if (sectrue != + (check_single_hash(hdr->hashes, + (const uint8_t *)sdcard_buf + code_start_offset, + hdr->codelen))) { return 0; } diff --git a/core/embed/bootloader/messages.c b/core/embed/bootloader/messages.c index 77477d012..9e9f92af2 100644 --- a/core/embed/bootloader/messages.c +++ b/core/embed/bootloader/messages.c @@ -576,6 +576,20 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, memcpy(&hdr, received_hdr, sizeof(hdr)); + size_t headers_end = IMAGE_HEADER_SIZE + vhdr.hdrlen; + headers_offset = IMAGE_CODE_ALIGN(IMAGE_HEADER_SIZE + vhdr.hdrlen); + + // check padding between headers and the code + for (size_t i = headers_end; i < headers_offset; i++) { + if (CHUNK_BUFFER_PTR[i] != 0) { + MSG_SEND_INIT(Failure); + MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError); + MSG_SEND_ASSIGN_STRING(message, "Invalid chunk padding"); + MSG_SEND(Failure); + return UPLOAD_ERR_INVALID_CHUNK_PADDING; + } + } + vendor_header current_vhdr; secbool is_new = secfalse; @@ -684,7 +698,6 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, NULL); } - headers_offset = IMAGE_HEADER_SIZE + vhdr.hdrlen; read_offset = IMAGE_INIT_CHUNK_SIZE; // request the rest of the first chunk diff --git a/core/embed/bootloader/messages.h b/core/embed/bootloader/messages.h index 0113982e2..d1ff9a2f0 100644 --- a/core/embed/bootloader/messages.h +++ b/core/embed/bootloader/messages.h @@ -46,6 +46,7 @@ enum { UPLOAD_ERR_FIRMWARE_MISMATCH = -11, UPLOAD_ERR_NOT_FIRMWARE_UPGRADE = -12, UPLOAD_ERR_NOT_FULLTRUST_IMAGE = -13, + UPLOAD_ERR_INVALID_CHUNK_PADDING = -14, }; enum { diff --git a/core/embed/bootloader_ci/messages.c b/core/embed/bootloader_ci/messages.c index 2a7c37278..ee177017a 100644 --- a/core/embed/bootloader_ci/messages.c +++ b/core/embed/bootloader_ci/messages.c @@ -558,7 +558,7 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, // no user confirmations, go directly to upload - headers_offset = IMAGE_HEADER_SIZE + vhdr.hdrlen; + headers_offset = IMAGE_CODE_ALIGN(IMAGE_HEADER_SIZE + vhdr.hdrlen); read_offset = IMAGE_INIT_CHUNK_SIZE; // request the rest of the first chunk diff --git a/core/embed/lib/image.c b/core/embed/lib/image.c index 6712c7076..0dc6a6f22 100644 --- a/core/embed/lib/image.c +++ b/core/embed/lib/image.c @@ -270,7 +270,7 @@ secbool check_image_contents(const image_header *const hdr, uint32_t firstskip, const uint8_t *addr = (uint8_t *)flash_area_get_address(area, firstskip, padding_size); for (size_t i = 0; i < padding_size; i++) { - if (*addr != 0) { + if (*addr++ != 0) { return secfalse; } }