mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-31 19:24:33 +02:00
bootloader_support: Used esp_image_get_metadata() instead of esp_image_verify()
- bootloader_common_get_sha256_of_partition will not do any unnecessery verifies. - Used esp_image_get_metadata() instead of esp_image_verify().
This commit is contained in:
committed by
bot
parent
99af5e9a71
commit
54ae758b77
@@ -163,9 +163,7 @@ esp_err_t bootloader_common_get_sha256_of_partition (uint32_t address, uint32_t
|
||||
.size = size,
|
||||
};
|
||||
esp_image_metadata_t data;
|
||||
// Function esp_image_verify() verifies and fills the structure data.
|
||||
// here important to get: image_digest, image_len, hash_appended.
|
||||
if (esp_image_verify(ESP_IMAGE_VERIFY_SILENT, &partition_pos, &data) != ESP_OK) {
|
||||
if (esp_image_get_metadata(&partition_pos, &data) != ESP_OK) {
|
||||
return ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
if (data.image.hash_appended) {
|
||||
|
@@ -112,7 +112,7 @@ static esp_err_t verify_segment_header(int index, const esp_image_segment_header
|
||||
|
||||
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 process_checksum(bootloader_sha256_handle_t sha_handle, uint32_t checksum_word, esp_image_metadata_t *data, bool silent, bool skip_check_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);
|
||||
@@ -137,6 +137,15 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
|
||||
uint8_t image_digest[HASH_LEN] = { [ 0 ... 31] = 0xEE };
|
||||
uint8_t verified_digest[HASH_LEN] = { [ 0 ... 31 ] = 0x01 };
|
||||
#endif
|
||||
#if CONFIG_SECURE_BOOT_V2_ENABLED
|
||||
// For Secure Boot V2, we do verify signature on bootloader which includes the SHA calculation.
|
||||
bool verify_sha = do_verify;
|
||||
#else // Secure boot not enabled
|
||||
// For secure boot V1 on ESP32, we don't calculate SHA or verify signature on bootloaders.
|
||||
// (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 = (data->start_addr != ESP_BOOTLOADER_OFFSET) && do_verify;
|
||||
#endif
|
||||
|
||||
if (data == NULL || part == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
@@ -148,48 +157,34 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
|
||||
}
|
||||
|
||||
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_image_header(data, part->offset, (verify_sha) ? p_sha_handle : NULL, 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));
|
||||
bool skip_check_checksum = !do_verify || esp_cpu_in_ocd_debug_mode();
|
||||
CHECK_ERR(process_checksum(sha_handle, checksum_word, data, silent, skip_check_checksum));
|
||||
CHECK_ERR(process_appended_hash(data, part->size, do_verify, silent));
|
||||
if (do_verify) {
|
||||
/* 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.)
|
||||
*/
|
||||
#if CONFIG_SECURE_BOOT_V2_ENABLED
|
||||
bool verify_sha = true;
|
||||
#else // Secure boot not enabled
|
||||
bool verify_sha = (data->start_addr != ESP_BOOTLOADER_OFFSET);
|
||||
#endif
|
||||
|
||||
if (verify_sha) {
|
||||
if (verify_sha) {
|
||||
#if (SECURE_BOOT_CHECK_SIGNATURE == 1)
|
||||
// secure boot images have a signature appended
|
||||
// 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.
|
||||
bool do_verify_sig = !esp_cpu_in_ocd_debug_mode();
|
||||
// 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.
|
||||
bool do_verify_sig = !esp_cpu_in_ocd_debug_mode();
|
||||
#else // CONFIG_SECURE_BOOT
|
||||
bool do_verify_sig = 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
|
||||
}
|
||||
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
|
||||
}
|
||||
#else // SECURE_BOOT_CHECK_SIGNATURE
|
||||
// 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);
|
||||
sha_handle = NULL; // calling verify_simple_hash finishes sha_handle
|
||||
}
|
||||
// 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);
|
||||
sha_handle = NULL; // calling verify_simple_hash finishes sha_handle
|
||||
}
|
||||
#endif // SECURE_BOOT_CHECK_SIGNATURE
|
||||
} // verify_sha
|
||||
} // do_verify
|
||||
} // verify_sha
|
||||
|
||||
// bootloader may still have a sha256 digest handle open
|
||||
if (sha_handle != NULL) {
|
||||
@@ -290,41 +285,22 @@ esp_err_t esp_image_verify(esp_image_load_mode_t mode, const esp_partition_pos_t
|
||||
|
||||
esp_err_t esp_image_get_metadata(const esp_partition_pos_t *part, esp_image_metadata_t *metadata)
|
||||
{
|
||||
esp_err_t err;
|
||||
if (metadata == NULL || part == NULL || part->size > SIXTEEN_MB) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
memset(metadata, 0, sizeof(esp_image_metadata_t));
|
||||
metadata->start_addr = part->offset;
|
||||
|
||||
esp_err_t err = bootloader_flash_read(metadata->start_addr, &metadata->image, sizeof(esp_image_header_t), true);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
uint32_t next_addr = metadata->start_addr + sizeof(esp_image_header_t);
|
||||
for (int i = 0; i < metadata->image.segment_count; i++) {
|
||||
esp_image_segment_header_t *header = &metadata->segments[i];
|
||||
err = process_segment(i, next_addr, header, true, false, NULL, NULL);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
next_addr += sizeof(esp_image_segment_header_t);
|
||||
metadata->segment_data[i] = next_addr;
|
||||
next_addr += header->data_len;
|
||||
}
|
||||
metadata->image_len = next_addr - metadata->start_addr;
|
||||
|
||||
// checksum
|
||||
uint32_t unpadded_length = metadata->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
|
||||
if (metadata->image.hash_appended) {
|
||||
// Account for the hash in the total image length
|
||||
length += HASH_LEN;
|
||||
}
|
||||
metadata->image_len = length;
|
||||
|
||||
bool silent = true;
|
||||
bool do_verify = false;
|
||||
bool do_load = false;
|
||||
CHECK_ERR(process_image_header(metadata, part->offset, NULL, do_verify, silent));
|
||||
CHECK_ERR(process_segments(metadata, silent, do_load, NULL, NULL));
|
||||
bool skip_check_checksum = true;
|
||||
CHECK_ERR(process_checksum(NULL, 0, metadata, silent, skip_check_checksum));
|
||||
CHECK_ERR(process_appended_hash(metadata, part->size, true, silent));
|
||||
return ESP_OK;
|
||||
err:
|
||||
return err;
|
||||
}
|
||||
|
||||
static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t *image, bool silent)
|
||||
@@ -803,7 +779,7 @@ err:
|
||||
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)
|
||||
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_check_checksum)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
uint32_t unpadded_length = data->image_len;
|
||||
@@ -811,21 +787,18 @@ static esp_err_t process_checksum(bootloader_sha256_handle_t sha_handle, uint32_
|
||||
length = (length + 15) & ~15; // Pad to next full 16 byte block
|
||||
length = length - unpadded_length;
|
||||
|
||||
if (!skip_calc_checksum) {
|
||||
// Verify checksum
|
||||
WORD_ALIGNED_ATTR uint8_t buf[16];
|
||||
// Verify checksum
|
||||
WORD_ALIGNED_ATTR uint8_t buf[16];
|
||||
if (!skip_check_checksum || sha_handle != NULL) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
uint8_t read_checksum = buf[length - 1];
|
||||
uint8_t calc_checksum = (checksum_word >> 24) ^ (checksum_word >> 16) ^ (checksum_word >> 8) ^ (checksum_word >> 0);
|
||||
if (!skip_check_checksum && calc_checksum != read_checksum) {
|
||||
FAIL_LOAD("Checksum failed. Calculated 0x%x read 0x%x", calc_checksum, read_checksum);
|
||||
}
|
||||
if (sha_handle != NULL) {
|
||||
bootloader_sha256_data(sha_handle, buf, length);
|
||||
}
|
||||
data->image_len += length;
|
||||
|
||||
|
Reference in New Issue
Block a user