mirror of
https://github.com/espressif/esp-idf
synced 2025-03-10 09:39:10 -04:00
bootloader: Fixed a case when signed OTA updates fail when debugger is attached due to the wrong image_len.
And it fixed another case for bootloader_common_get_sha256_of_partition() when CHECK_SIGNATURE is on - If RSA signature check is on in Kconfig then sha256 was 0xFFFFF... because image_load gave image_len which pointed to the end of sign blocks. And image_digest was filled from a wrong position. Closes https://github.com/espressif/esp-idf/issues/6873
This commit is contained in:
parent
362c9234dc
commit
99af5e9a71
@ -47,10 +47,14 @@
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
#ifdef CONFIG_SECURE_SIGNED_ON_BOOT
|
||||
#define SECURE_BOOT_CHECK_SIGNATURE 1
|
||||
#else
|
||||
#define SECURE_BOOT_CHECK_SIGNATURE 0
|
||||
#endif
|
||||
#else /* !BOOTLOADER_BUILD */
|
||||
#ifdef CONFIG_SECURE_SIGNED_ON_UPDATE
|
||||
#define SECURE_BOOT_CHECK_SIGNATURE 1
|
||||
#else
|
||||
#define SECURE_BOOT_CHECK_SIGNATURE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -77,6 +81,7 @@ static bool should_load(uint32_t load_addr);
|
||||
/* Return true if load_addr is an address the bootloader should map via flash cache */
|
||||
static bool should_map(uint32_t load_addr);
|
||||
|
||||
static esp_err_t process_segments(esp_image_metadata_t *data, bool silent, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum);
|
||||
/* Load or verify a segment */
|
||||
static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segment_header_t *header, bool silent, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum);
|
||||
|
||||
@ -98,7 +103,16 @@ static esp_err_t verify_segment_header(int index, const esp_image_segment_header
|
||||
} \
|
||||
while(0)
|
||||
|
||||
static esp_err_t verify_checksum(bootloader_sha256_handle_t sha_handle, uint32_t checksum_word, esp_image_metadata_t *data);
|
||||
#define CHECK_ERR(func) do { \
|
||||
if ((err = func) != ESP_OK) { \
|
||||
goto err; \
|
||||
} \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
static esp_err_t process_image_header(esp_image_metadata_t *data, uint32_t part_offset, bootloader_sha256_handle_t *sha_handle, bool do_verify, bool silent);
|
||||
static esp_err_t process_appended_hash(esp_image_metadata_t *data, uint32_t part_len, bool do_verify, bool silent);
|
||||
static esp_err_t process_checksum(bootloader_sha256_handle_t sha_handle, uint32_t checksum_word, esp_image_metadata_t *data, bool silent, bool skip_calc_checksum);
|
||||
|
||||
static esp_err_t __attribute__((unused)) verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data, uint8_t *image_digest, uint8_t *verified_digest);
|
||||
static esp_err_t __attribute__((unused)) verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data);
|
||||
@ -116,9 +130,9 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
|
||||
esp_err_t err = ESP_OK;
|
||||
// checksum the image a word at a time. This shaves 30-40ms per MB of image size
|
||||
uint32_t checksum_word = ESP_ROM_CHECKSUM_INITIAL;
|
||||
uint32_t *checksum = NULL;
|
||||
uint32_t *checksum = (do_verify) ? &checksum_word : NULL;
|
||||
bootloader_sha256_handle_t sha_handle = NULL;
|
||||
#if SECURE_BOOT_CHECK_SIGNATURE
|
||||
#if (SECURE_BOOT_CHECK_SIGNATURE == 1)
|
||||
/* used for anti-FI checks */
|
||||
uint8_t image_digest[HASH_LEN] = { [ 0 ... 31] = 0xEE };
|
||||
uint8_t verified_digest[HASH_LEN] = { [ 0 ... 31 ] = 0x01 };
|
||||
@ -133,107 +147,37 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
|
||||
FAIL_LOAD("partition size 0x%x invalid, larger than 16MB", part->size);
|
||||
}
|
||||
|
||||
bzero(data, sizeof(esp_image_metadata_t));
|
||||
data->start_addr = part->offset;
|
||||
|
||||
ESP_LOGD(TAG, "reading image header @ 0x%x", data->start_addr);
|
||||
err = bootloader_flash_read(data->start_addr, &data->image, sizeof(esp_image_header_t), true);
|
||||
if (err != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
bootloader_sha256_handle_t *p_sha_handle = &sha_handle;
|
||||
CHECK_ERR(process_image_header(data, part->offset, p_sha_handle, do_verify, silent));
|
||||
CHECK_ERR(process_segments(data, silent, do_load, sha_handle, checksum));
|
||||
bool skip_calc_checksum = !do_verify || esp_cpu_in_ocd_debug_mode();
|
||||
CHECK_ERR(process_checksum(sha_handle, checksum_word, data, silent, skip_calc_checksum));
|
||||
CHECK_ERR(process_appended_hash(data, part->size, do_verify, silent));
|
||||
if (do_verify) {
|
||||
checksum = &checksum_word;
|
||||
|
||||
// Calculate SHA-256 of image if secure boot is on, or if image has a hash appended
|
||||
#ifdef SECURE_BOOT_CHECK_SIGNATURE
|
||||
if (1) {
|
||||
#else
|
||||
if (data->image.hash_appended) {
|
||||
#endif
|
||||
sha_handle = bootloader_sha256_start();
|
||||
if (sha_handle == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
bootloader_sha256_data(sha_handle, &data->image, sizeof(esp_image_header_t));
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "image header: 0x%02x 0x%02x 0x%02x 0x%02x %08x",
|
||||
data->image.magic,
|
||||
data->image.segment_count,
|
||||
data->image.spi_mode,
|
||||
data->image.spi_size,
|
||||
data->image.entry_addr);
|
||||
|
||||
err = verify_image_header(data->start_addr, &data->image, silent);
|
||||
if (err != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (data->image.segment_count > ESP_IMAGE_MAX_SEGMENTS) {
|
||||
FAIL_LOAD("image at 0x%x segment count %d exceeds max %d",
|
||||
data->start_addr, data->image.segment_count, ESP_IMAGE_MAX_SEGMENTS);
|
||||
}
|
||||
} // if (do_verify)
|
||||
|
||||
uint32_t next_addr = data->start_addr + sizeof(esp_image_header_t);
|
||||
for (int i = 0; i < data->image.segment_count; i++) {
|
||||
esp_image_segment_header_t *header = &data->segments[i];
|
||||
ESP_LOGV(TAG, "loading segment header %d at offset 0x%x", i, next_addr);
|
||||
|
||||
err = process_segment(i, next_addr, header, silent, do_load, sha_handle, checksum);
|
||||
if (err != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
next_addr += sizeof(esp_image_segment_header_t);
|
||||
data->segment_data[i] = next_addr;
|
||||
next_addr += header->data_len;
|
||||
}
|
||||
|
||||
if (do_verify) {
|
||||
// Segments all loaded, verify length
|
||||
uint32_t end_addr = next_addr;
|
||||
if (end_addr < data->start_addr) {
|
||||
FAIL_LOAD("image offset has wrapped");
|
||||
}
|
||||
|
||||
data->image_len = end_addr - data->start_addr;
|
||||
ESP_LOGV(TAG, "image start 0x%08x end of last section 0x%08x", data->start_addr, end_addr);
|
||||
if (NULL != checksum && !esp_cpu_in_ocd_debug_mode()) {
|
||||
err = verify_checksum(sha_handle, checksum_word, data);
|
||||
if (err != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* For secure boot V1 on ESP32, we don't calculate SHA or verify signature on bootloaders.
|
||||
For Secure Boot V2, we do verify signature on bootloader which includes the SHA calculation.
|
||||
|
||||
(For non-secure boot, we don't verify any SHA-256 hash appended to the bootloader because
|
||||
esptool.py may have rewritten the header - rely on esptool.py having verified the bootloader at flashing time, instead.)
|
||||
*/
|
||||
bool verify_sha;
|
||||
#if CONFIG_SECURE_BOOT_V2_ENABLED
|
||||
verify_sha = true;
|
||||
bool verify_sha = true;
|
||||
#else // Secure boot not enabled
|
||||
verify_sha = (data->start_addr != ESP_BOOTLOADER_OFFSET);
|
||||
bool verify_sha = (data->start_addr != ESP_BOOTLOADER_OFFSET);
|
||||
#endif
|
||||
|
||||
if (verify_sha) {
|
||||
if (data->image_len > part->size) {
|
||||
FAIL_LOAD("Image length %d doesn't fit in partition length %d", data->image_len, part->size);
|
||||
}
|
||||
|
||||
#ifdef SECURE_BOOT_CHECK_SIGNATURE
|
||||
#if (SECURE_BOOT_CHECK_SIGNATURE == 1)
|
||||
// secure boot images have a signature appended
|
||||
#if defined(BOOTLOADER_BUILD) && !defined(CONFIG_SECURE_BOOT)
|
||||
// If secure boot is not enabled in hardware, then
|
||||
// skip the signature check in bootloader when the debugger is attached.
|
||||
// This is done to allow for breakpoints in Flash.
|
||||
if (!esp_cpu_in_ocd_debug_mode()) {
|
||||
bool do_verify_sig = !esp_cpu_in_ocd_debug_mode();
|
||||
#else // CONFIG_SECURE_BOOT
|
||||
if (true) {
|
||||
bool do_verify_sig = true;
|
||||
#endif // end checking for JTAG
|
||||
if (do_verify_sig) {
|
||||
err = verify_secure_boot_signature(sha_handle, data, image_digest, verified_digest);
|
||||
sha_handle = NULL; // verify_secure_boot_signature finishes sha_handle
|
||||
}
|
||||
@ -241,42 +185,25 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
|
||||
// No secure boot, but SHA-256 can be appended for basic corruption detection
|
||||
if (sha_handle != NULL && !esp_cpu_in_ocd_debug_mode()) {
|
||||
err = verify_simple_hash(sha_handle, data);
|
||||
#ifdef CONFIG_IDF_ENV_FPGA
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGW(TAG, "Ignoring invalid SHA-256 as running on FPGA");
|
||||
err = ESP_OK;
|
||||
}
|
||||
#endif
|
||||
sha_handle = NULL; // calling verify_simple_hash finishes sha_handle
|
||||
}
|
||||
#endif // SECURE_BOOT_CHECK_SIGNATURE
|
||||
} else { // verify_sha
|
||||
// bootloader may still have a sha256 digest handle open
|
||||
if (sha_handle != NULL) {
|
||||
bootloader_sha256_finish(sha_handle, NULL);
|
||||
}
|
||||
sha_handle = NULL;
|
||||
} //verify_sha
|
||||
|
||||
// Separately, if there's a hash appended to the image then copy it out to the data->image_digest field
|
||||
if (data->image.hash_appended) {
|
||||
const void *hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN);
|
||||
if (hash == NULL) {
|
||||
err = ESP_FAIL;
|
||||
goto err;
|
||||
}
|
||||
memcpy(data->image_digest, hash, HASH_LEN);
|
||||
bootloader_munmap(hash);
|
||||
}
|
||||
} // verify_sha
|
||||
} // do_verify
|
||||
|
||||
// bootloader may still have a sha256 digest handle open
|
||||
if (sha_handle != NULL) {
|
||||
bootloader_sha256_finish(sha_handle, NULL);
|
||||
sha_handle = NULL;
|
||||
}
|
||||
|
||||
if (err != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
|
||||
#ifdef SECURE_BOOT_CHECK_SIGNATURE
|
||||
#if (SECURE_BOOT_CHECK_SIGNATURE == 1)
|
||||
/* If signature was checked in bootloader build, verified_digest should equal image_digest
|
||||
|
||||
This is to detect any fault injection that caused signature verification to not complete normally.
|
||||
@ -307,7 +234,7 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // BOOTLOADER_BUILD
|
||||
|
||||
// Success!
|
||||
return ESP_OK;
|
||||
@ -404,11 +331,15 @@ static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
ESP_LOGD(TAG, "image header: 0x%02x 0x%02x 0x%02x 0x%02x %08x",
|
||||
image->magic,
|
||||
image->segment_count,
|
||||
image->spi_mode,
|
||||
image->spi_size,
|
||||
image->entry_addr);
|
||||
|
||||
if (image->magic != ESP_IMAGE_HEADER_MAGIC) {
|
||||
if (!silent) {
|
||||
ESP_LOGE(TAG, "image at 0x%x has invalid magic byte", src_addr);
|
||||
}
|
||||
err = ESP_ERR_IMAGE_INVALID;
|
||||
FAIL_LOAD("image at 0x%x has invalid magic byte (nothing flashed here?)", src_addr);
|
||||
}
|
||||
if (!silent) {
|
||||
if (image->spi_mode > ESP_IMAGE_SPI_MODE_SLOW_READ) {
|
||||
@ -422,15 +353,19 @@ static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t
|
||||
}
|
||||
}
|
||||
|
||||
if (err == ESP_OK) {
|
||||
// Checking the chip revision header *will* print a bunch of other info
|
||||
// regardless of silent setting as this may be important, but don't bother checking it
|
||||
// if it looks like the app partition is erased or otherwise garbage
|
||||
if (bootloader_common_check_chip_validity(image, ESP_IMAGE_APPLICATION) != ESP_OK) {
|
||||
err = ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
}
|
||||
// Checking the chip revision header *will* print a bunch of other info
|
||||
// regardless of silent setting as this may be important, but don't bother checking it
|
||||
// if it looks like the app partition is erased or otherwise garbage
|
||||
CHECK_ERR(bootloader_common_check_chip_validity(image, ESP_IMAGE_APPLICATION));
|
||||
|
||||
if (image->segment_count > ESP_IMAGE_MAX_SEGMENTS) {
|
||||
FAIL_LOAD("image at 0x%x segment count %d exceeds max %d", src_addr, image->segment_count, ESP_IMAGE_MAX_SEGMENTS);
|
||||
}
|
||||
return err;
|
||||
err:
|
||||
if (err == ESP_OK) {
|
||||
err = ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -555,6 +490,63 @@ static bool verify_load_addresses(int segment_index, intptr_t load_addr, intptr_
|
||||
}
|
||||
#endif // BOOTLOADER_BUILD
|
||||
|
||||
static esp_err_t process_image_header(esp_image_metadata_t *data, uint32_t part_offset, bootloader_sha256_handle_t *sha_handle, bool do_verify, bool silent)
|
||||
{
|
||||
esp_err_t err;
|
||||
bzero(data, sizeof(esp_image_metadata_t));
|
||||
data->start_addr = part_offset;
|
||||
|
||||
ESP_LOGD(TAG, "reading image header @ 0x%x", data->start_addr);
|
||||
CHECK_ERR(bootloader_flash_read(data->start_addr, &data->image, sizeof(esp_image_header_t), true));
|
||||
|
||||
if (do_verify) {
|
||||
// Calculate SHA-256 of image if secure boot is on, or if image has a hash appended
|
||||
if (SECURE_BOOT_CHECK_SIGNATURE || data->image.hash_appended) {
|
||||
if (sha_handle != NULL) {
|
||||
*sha_handle = bootloader_sha256_start();
|
||||
if (*sha_handle == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
bootloader_sha256_data(*sha_handle, &data->image, sizeof(esp_image_header_t));
|
||||
}
|
||||
}
|
||||
CHECK_ERR(verify_image_header(data->start_addr, &data->image, silent));
|
||||
}
|
||||
data->image_len = sizeof(esp_image_header_t);
|
||||
return ESP_OK;
|
||||
err:
|
||||
return err;
|
||||
}
|
||||
|
||||
static esp_err_t process_segments(esp_image_metadata_t *data, bool silent, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
uint32_t start_segments = data->start_addr + data->image_len;
|
||||
uint32_t next_addr = start_segments;
|
||||
for (int i = 0; i < data->image.segment_count; i++) {
|
||||
esp_image_segment_header_t *header = &data->segments[i];
|
||||
ESP_LOGV(TAG, "loading segment header %d at offset 0x%x", i, next_addr);
|
||||
CHECK_ERR(process_segment(i, next_addr, header, silent, do_load, sha_handle, checksum));
|
||||
next_addr += sizeof(esp_image_segment_header_t);
|
||||
data->segment_data[i] = next_addr;
|
||||
next_addr += header->data_len;
|
||||
}
|
||||
// Segments all loaded, verify length
|
||||
uint32_t end_addr = next_addr;
|
||||
if (end_addr < data->start_addr) {
|
||||
FAIL_LOAD("image offset has wrapped");
|
||||
}
|
||||
|
||||
data->image_len += end_addr - start_segments;
|
||||
ESP_LOGV(TAG, "image start 0x%08x end of last section 0x%08x", data->start_addr, end_addr);
|
||||
return err;
|
||||
err:
|
||||
if (err == ESP_OK) {
|
||||
err = ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segment_header_t *header, bool silent, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum)
|
||||
{
|
||||
esp_err_t err;
|
||||
@ -575,10 +567,7 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme
|
||||
|
||||
ESP_LOGV(TAG, "segment data length 0x%x data starts 0x%x", data_len, data_addr);
|
||||
|
||||
err = verify_segment_header(index, header, data_addr, silent);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
CHECK_ERR(verify_segment_header(index, header, data_addr, silent));
|
||||
|
||||
if (data_len % 4 != 0) {
|
||||
FAIL_LOAD("unaligned segment length 0x%x", data_len);
|
||||
@ -609,17 +598,14 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme
|
||||
|
||||
uint32_t data_len_remain = data_len;
|
||||
while (data_len_remain > 0) {
|
||||
#if SECURE_BOOT_CHECK_SIGNATURE && defined(BOOTLOADER_BUILD)
|
||||
#if (SECURE_BOOT_CHECK_SIGNATURE == 1) && defined(BOOTLOADER_BUILD)
|
||||
/* Double check the address verification done above */
|
||||
ESP_FAULT_ASSERT(!do_load || verify_load_addresses(0, load_addr, load_addr + data_len_remain, false, false));
|
||||
#endif
|
||||
uint32_t offset_page = ((data_addr & MMAP_ALIGNED_MASK) != 0) ? 1 : 0;
|
||||
/* Data we could map in case we are not aligned to PAGE boundary is one page size lesser. */
|
||||
data_len = MIN(data_len_remain, ((free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE));
|
||||
err = process_segment_data(load_addr, data_addr, data_len, do_load, sha_handle, checksum);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
CHECK_ERR(process_segment_data(load_addr, data_addr, data_len, do_load, sha_handle, checksum));
|
||||
data_addr += data_len;
|
||||
data_len_remain -= data_len;
|
||||
}
|
||||
@ -794,41 +780,67 @@ esp_err_t esp_image_verify_bootloader_data(esp_image_metadata_t *data)
|
||||
data);
|
||||
}
|
||||
|
||||
|
||||
static esp_err_t verify_checksum(bootloader_sha256_handle_t sha_handle, uint32_t checksum_word, esp_image_metadata_t *data)
|
||||
static esp_err_t process_appended_hash(esp_image_metadata_t *data, uint32_t part_len, bool do_verify, bool silent)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
if (data->image.hash_appended) {
|
||||
// Account for the hash in the total image length
|
||||
if (do_verify) {
|
||||
CHECK_ERR(bootloader_flash_read(data->start_addr + data->image_len, &data->image_digest, HASH_LEN, true));
|
||||
}
|
||||
data->image_len += HASH_LEN;
|
||||
}
|
||||
|
||||
if (data->image_len > part_len) {
|
||||
FAIL_LOAD("Image length %d doesn't fit in partition length %d", data->image_len, part_len);
|
||||
}
|
||||
return err;
|
||||
err:
|
||||
if (err == ESP_OK) {
|
||||
err = ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static esp_err_t process_checksum(bootloader_sha256_handle_t sha_handle, uint32_t checksum_word, esp_image_metadata_t *data, bool silent, bool skip_calc_checksum)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
uint32_t unpadded_length = data->image_len;
|
||||
uint32_t length = unpadded_length + 1; // Add a byte for the checksum
|
||||
length = (length + 15) & ~15; // Pad to next full 16 byte block
|
||||
length = length - unpadded_length;
|
||||
|
||||
// Verify checksum
|
||||
WORD_ALIGNED_ATTR uint8_t buf[16];
|
||||
esp_err_t err = bootloader_flash_read(data->start_addr + unpadded_length, buf, length - unpadded_length, true);
|
||||
uint8_t calc = buf[length - unpadded_length - 1];
|
||||
uint8_t checksum = (checksum_word >> 24)
|
||||
^ (checksum_word >> 16)
|
||||
^ (checksum_word >> 8)
|
||||
^ (checksum_word >> 0);
|
||||
if (err != ESP_OK || checksum != calc) {
|
||||
ESP_LOGE(TAG, "Checksum failed. Calculated 0x%x read 0x%x", checksum, calc);
|
||||
return ESP_ERR_IMAGE_INVALID;
|
||||
if (!skip_calc_checksum) {
|
||||
// Verify checksum
|
||||
WORD_ALIGNED_ATTR uint8_t buf[16];
|
||||
CHECK_ERR(bootloader_flash_read(data->start_addr + unpadded_length, buf, length, true));
|
||||
uint8_t calc = buf[length - 1];
|
||||
uint8_t checksum = (checksum_word >> 24)
|
||||
^ (checksum_word >> 16)
|
||||
^ (checksum_word >> 8)
|
||||
^ (checksum_word >> 0);
|
||||
if (checksum != calc) {
|
||||
FAIL_LOAD("Checksum failed. Calculated 0x%x read 0x%x", checksum, calc);
|
||||
}
|
||||
if (sha_handle != NULL) {
|
||||
bootloader_sha256_data(sha_handle, buf, length);
|
||||
}
|
||||
}
|
||||
if (sha_handle != NULL) {
|
||||
bootloader_sha256_data(sha_handle, buf, length - unpadded_length);
|
||||
data->image_len += length;
|
||||
|
||||
return err;
|
||||
err:
|
||||
if (err == ESP_OK) {
|
||||
err = ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
|
||||
if (data->image.hash_appended) {
|
||||
// Account for the hash in the total image length
|
||||
length += HASH_LEN;
|
||||
}
|
||||
data->image_len = length;
|
||||
|
||||
return ESP_OK;
|
||||
return err;
|
||||
}
|
||||
|
||||
static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data, uint8_t *image_digest, uint8_t *verified_digest)
|
||||
{
|
||||
#ifdef SECURE_BOOT_CHECK_SIGNATURE
|
||||
#if (SECURE_BOOT_CHECK_SIGNATURE == 1)
|
||||
uint32_t end = data->start_addr + data->image_len;
|
||||
|
||||
ESP_LOGI(TAG, "Verifying image signature...");
|
||||
@ -909,15 +921,16 @@ static esp_err_t verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_i
|
||||
bootloader_debug_buffer(image_hash, HASH_LEN, "Calculated hash");
|
||||
|
||||
// Simple hash for verification only
|
||||
const void *hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN);
|
||||
if (memcmp(hash, image_hash, HASH_LEN) != 0) {
|
||||
if (memcmp(data->image_digest, image_hash, HASH_LEN) != 0) {
|
||||
ESP_LOGE(TAG, "Image hash failed - image is corrupt");
|
||||
bootloader_debug_buffer(hash, HASH_LEN, "Expected hash");
|
||||
bootloader_munmap(hash);
|
||||
bootloader_debug_buffer(data->image_digest, HASH_LEN, "Expected hash");
|
||||
#ifdef CONFIG_IDF_ENV_FPGA
|
||||
ESP_LOGW(TAG, "Ignoring invalid SHA-256 as running on FPGA");
|
||||
return ESP_OK;
|
||||
#endif
|
||||
return ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
|
||||
bootloader_munmap(hash);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user