Explorar o código

Merge branch 'bugfix/bootloader_gen_secure_boot_digest' into 'master'

bootloader: Fix secure boot digest generation for image length where (len%128 < 32)

See merge request idf/esp-idf!3410
Angus Gratton %!s(int64=7) %!d(string=hai) anos
pai
achega
4faa2a8e52

+ 12 - 0
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;

+ 17 - 8
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;

+ 9 - 3
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;