]> 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>
Tue, 2 Oct 2018 05:17:14 +0000 (15:17 +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 6d92a35b0061e7ee50423e8175e5e9661e6a52ea..bce3b1d7fad00159e0d8c503ddc4258e13dbd64d 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;
@@ -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;
index 98d5a341b2ac8f26f150b60dbc77e454c4f7c9b7..9fa7c0d76582e0bf7e12966d16b39978c15bde83 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
@@ -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;
index 6355bcd7c530b3f1cf027e71016ff00a90ce9839..36f9ea8c6c09524ce40f9509cad406d75589afd5 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,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;