diff --git a/components/bootloader_support/include/esp_image_format.h b/components/bootloader_support/include/esp_image_format.h index 6d92a35b0..bce3b1d7f 100644 --- a/components/bootloader_support/include/esp_image_format.h +++ b/components/bootloader_support/include/esp_image_format.h @@ -81,6 +81,8 @@ typedef struct { _Static_assert(sizeof(esp_image_header_t) == 24, "binary image header should be 24 bytes"); +#define ESP_IMAGE_HASH_LEN 32 /* Length of the appended SHA-256 digest */ + /* Header of binary image segment */ typedef struct { uint32_t load_addr; @@ -201,6 +203,16 @@ esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metad */ esp_err_t esp_image_verify_bootloader(uint32_t *length); +/** + * @brief Verify the bootloader image. + * + * @param[out] Metadata for the image. Only valid if result is ESP_OK. + * + * @return As per esp_image_load_metadata(). + */ +esp_err_t esp_image_verify_bootloader_data(esp_image_metadata_t *data); + + typedef struct { uint32_t drom_addr; uint32_t drom_load_addr; diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c index 98d5a341b..9fa7c0d76 100644 --- a/components/bootloader_support/src/esp_image_format.c +++ b/components/bootloader_support/src/esp_image_format.c @@ -40,7 +40,7 @@ static const char *TAG = "esp_image"; -#define HASH_LEN 32 /* SHA-256 digest length */ +#define HASH_LEN ESP_IMAGE_HASH_LEN #define SIXTEEN_MB 0x1000000 #define ESP_ROM_CHECKSUM_INITIAL 0xEF @@ -487,19 +487,28 @@ static bool should_load(uint32_t load_addr) esp_err_t esp_image_verify_bootloader(uint32_t *length) { esp_image_metadata_t data; - const esp_partition_pos_t bootloader_part = { - .offset = ESP_BOOTLOADER_OFFSET, - .size = ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET, - }; - esp_err_t err = esp_image_verify(ESP_IMAGE_VERIFY, - &bootloader_part, - &data); + esp_err_t err = esp_image_verify_bootloader_data(&data); if (length != NULL) { *length = (err == ESP_OK) ? data.image_len : 0; } return err; } +esp_err_t esp_image_verify_bootloader_data(esp_image_metadata_t *data) +{ + if (data == NULL) { + return ESP_ERR_INVALID_ARG; + } + const esp_partition_pos_t bootloader_part = { + .offset = ESP_BOOTLOADER_OFFSET, + .size = ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET, + }; + return esp_image_verify(ESP_IMAGE_VERIFY, + &bootloader_part, + data); +} + + static esp_err_t verify_checksum(bootloader_sha256_handle_t sha_handle, uint32_t checksum_word, esp_image_metadata_t *data) { uint32_t unpadded_length = data->image_len; diff --git a/components/bootloader_support/src/secure_boot.c b/components/bootloader_support/src/secure_boot.c index 6355bcd7c..36f9ea8c6 100644 --- a/components/bootloader_support/src/secure_boot.c +++ b/components/bootloader_support/src/secure_boot.c @@ -50,7 +50,7 @@ static bool secure_boot_generate(uint32_t image_len){ const uint32_t *image; /* hardware secure boot engine only takes full blocks, so round up the - image length. The additional data should all be 0xFF. + image length. The additional data should all be 0xFF (or the appended SHA, if it falls in the same block). */ if (image_len % sizeof(digest.iv) != 0) { image_len = (image_len / sizeof(digest.iv) + 1) * sizeof(digest.iv); @@ -104,7 +104,6 @@ static inline void burn_efuses() esp_err_t esp_secure_boot_permanently_enable(void) { esp_err_t err; - uint32_t image_len = 0; if (esp_secure_boot_enabled()) { ESP_LOGI(TAG, "bootloader secure boot is already enabled, continuing.."); @@ -116,7 +115,9 @@ esp_err_t esp_secure_boot_permanently_enable(void) { return ESP_ERR_NOT_SUPPORTED; } - err = esp_image_verify_bootloader(&image_len); + /* Verify the bootloader */ + esp_image_metadata_t bootloader_data = { 0 }; + err = esp_image_verify_bootloader_data(&bootloader_data); if (err != ESP_OK) { ESP_LOGE(TAG, "bootloader image appears invalid! error %d", err); return err; @@ -155,6 +156,11 @@ esp_err_t esp_secure_boot_permanently_enable(void) { } ESP_LOGI(TAG, "Generating secure boot digest..."); + uint32_t image_len = bootloader_data.image_len; + if(bootloader_data.image.hash_appended) { + /* Secure boot digest doesn't cover the hash */ + image_len -= ESP_IMAGE_HASH_LEN; + } if (false == secure_boot_generate(image_len)){ ESP_LOGE(TAG, "secure boot generation failed"); return ESP_FAIL;