]> granicus.if.org Git - esp-idf/commitdiff
bootloader: Fix secure boot digest generation for image length where (len%128 < 32)
authorAngus Gratton <angus@espressif.com>
Sat, 29 Sep 2018 14:31:58 +0000 (00:31 +1000)
committerAngus Gratton <gus@projectgus.com>
Sat, 29 Sep 2018 14:45:07 +0000 (00:45 +1000)
components/bootloader_support/include/esp_image_format.h
components/bootloader_support/src/esp_image_format.c
components/bootloader_support/src/secure_boot.c

index d2dcfd312cd0ce9e33b3cf91fb2ffd44dc1f1503..6d0a980c0c0aa64b2f7c8d605bda98add89763c5 100644 (file)
@@ -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;
@@ -142,6 +144,16 @@ esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *
  */
 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;
index 965e6398796b66c748f1bd87cc658e3ceb9e6f8c..87b5a94fe675144764b6c10a50ff99a397e236da 100644 (file)
@@ -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
@@ -456,19 +456,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_load(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_load(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;
index ef9744ffc8bf57419be78f12e71c75295c5b3312..6d8bc6107e0500888e2ab93068b6e27527fbc7b1 100644 (file)
@@ -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,14 +104,15 @@ 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..");
         return ESP_OK;
     }
 
-    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;
@@ -150,6 +151,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;