Explorar el Código

Merge branch 'bugfix/sec_boot_ota_fail' into 'master'

Bugfix: ota fails with secure boot on for image size greater than 3.2MB

See merge request idf/esp-idf!5263
Ivan Grokhotkov hace 6 años
padre
commit
240192f9fa

+ 7 - 0
components/bootloader_support/include_bootloader/bootloader_flash.h

@@ -30,6 +30,13 @@
    bootloader_support components only.
 */
 
+/**
+ * @brief Get number of free pages
+ *
+ * @return Number of free pages
+ */
+uint32_t bootloader_mmap_get_free_pages();
+
 /**
  * @brief Map a region of flash to data memory
  *

+ 15 - 0
components/bootloader_support/src/bootloader_flash.c

@@ -25,6 +25,11 @@ static const char *TAG = "bootloader_mmap";
 
 static spi_flash_mmap_handle_t map;
 
+uint32_t bootloader_mmap_get_free_pages()
+{
+    return spi_flash_mmap_get_free_pages(SPI_FLASH_MMAP_DATA);
+}
+
 const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
 {
     if (map) {
@@ -91,12 +96,22 @@ static const char *TAG = "bootloader_flash";
 */
 #define MMU_BLOCK0_VADDR  0x3f400000
 #define MMU_BLOCK50_VADDR 0x3f720000
+#define MMU_FREE_PAGES    ((MMU_BLOCK50_VADDR - MMU_BLOCK0_VADDR) / FLASH_BLOCK_SIZE)
 
 static bool mapped;
 
 // Current bootloader mapping (ab)used for bootloader_read()
 static uint32_t current_read_mapping = UINT32_MAX;
 
+uint32_t bootloader_mmap_get_free_pages()
+{
+    /**
+     * Allow mapping up to 50 of the 51 available MMU blocks (last one used for reads)
+     * Since, bootloader_mmap function below assumes it to be 0x320000 (50 pages), we can safely do this.
+     */
+    return MMU_FREE_PAGES;
+}
+
 const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
 {
     if (mapped) {

+ 37 - 11
components/bootloader_support/src/esp32/secure_boot_signatures.c

@@ -21,7 +21,7 @@
 #include "esp32/rom/sha.h"
 #include "uECC.h"
 
-typedef SHA_CTX sha_context;
+#include <sys/param.h>
 
 static const char *TAG = "secure_boot";
 
@@ -32,6 +32,9 @@ extern const uint8_t signature_verification_key_end[] asm("_binary_signature_ver
 
 #define DIGEST_LEN 32
 
+/* Mmap source address mask */
+#define MMAP_ALIGNED_MASK 0x0000FFFF
+
 esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
 {
     uint8_t digest[DIGEST_LEN];
@@ -40,21 +43,44 @@ esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
 
     ESP_LOGD(TAG, "verifying signature src_addr 0x%x length 0x%x", src_addr, length);
 
-    data = bootloader_mmap(src_addr, length + sizeof(esp_secure_boot_sig_block_t));
-    if (data == NULL) {
-        ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr, length + sizeof(esp_secure_boot_sig_block_t));
-        return ESP_FAIL;
+    bootloader_sha256_handle_t handle = bootloader_sha256_start();
+
+    uint32_t free_page_count = bootloader_mmap_get_free_pages();
+    ESP_LOGD(TAG, "free data page_count 0x%08x", free_page_count);
+
+    int32_t data_len_remain = length;
+    uint32_t data_addr = src_addr;
+    while (data_len_remain > 0) {
+        uint32_t offset_page = ((data_addr & MMAP_ALIGNED_MASK) != 0) ? 1 : 0;
+        /* Data we could map in case we are not aligned to PAGE boundary is one page size lesser. */
+        uint32_t data_len = MIN(data_len_remain, ((free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE));
+        data = (const uint8_t *) bootloader_mmap(data_addr, data_len);
+        if(!data) {
+            ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", data_addr, data_len);
+            bootloader_sha256_finish(handle, NULL);
+            return ESP_FAIL;
+        }
+        bootloader_sha256_data(handle, data, data_len);
+        bootloader_munmap(data);
+
+        data_addr += data_len;
+        data_len_remain -= data_len;
     }
 
-    // Calculate digest of main image
-    bootloader_sha256_handle_t handle = bootloader_sha256_start();
-    bootloader_sha256_data(handle, data, length);
+    /* Done! Get the digest */
     bootloader_sha256_finish(handle, digest);
 
-    // Map the signature block and verify the signature
-    sigblock = (const esp_secure_boot_sig_block_t *)(data + length);
+    // Map the signature block
+    sigblock = (const esp_secure_boot_sig_block_t *) bootloader_mmap(src_addr + length, sizeof(esp_secure_boot_sig_block_t));
+    if(!sigblock) {
+        ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr + length, sizeof(esp_secure_boot_sig_block_t));
+        return ESP_FAIL;
+    }
+    // Verify the signature
     esp_err_t err = esp_secure_boot_verify_signature_block(sigblock, digest);
-    bootloader_munmap(data);
+    // Unmap
+    bootloader_munmap(sigblock);
+
     return err;
 }
 

+ 12 - 14
components/bootloader_support/src/esp_image_format.c

@@ -368,24 +368,22 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme
     }
 #endif // BOOTLOADER_BUILD
 
-#ifndef BOOTLOADER_BUILD
-    uint32_t free_page_count = spi_flash_mmap_get_free_pages(SPI_FLASH_MMAP_DATA);
-    ESP_LOGD(TAG, "free data page_count 0x%08x",free_page_count);
-    uint32_t offset_page = 0;
-    while (data_len >= free_page_count * SPI_FLASH_MMU_PAGE_SIZE) {
-        offset_page = ((data_addr & MMAP_ALIGNED_MASK) != 0)?1:0;
-        err = process_segment_data(load_addr, data_addr, (free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE, do_load, sha_handle, checksum);
+    uint32_t free_page_count = bootloader_mmap_get_free_pages();
+    ESP_LOGD(TAG, "free data page_count 0x%08x", free_page_count);
+
+    int32_t data_len_remain = data_len;
+    while (data_len_remain > 0) {
+        uint32_t offset_page = ((data_addr & MMAP_ALIGNED_MASK) != 0) ? 1 : 0;
+        /* Data we could map in case we are not aligned to PAGE boundary is one page size lesser. */
+        data_len = MIN(data_len_remain, ((free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE));
+        err = process_segment_data(load_addr, data_addr, data_len, do_load, sha_handle, checksum);
         if (err != ESP_OK) {
             return err;
         }
-        data_addr += (free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE;
-        data_len -= (free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE;
-    }
-#endif
-    err = process_segment_data(load_addr, data_addr, data_len, do_load, sha_handle, checksum);
-    if (err != ESP_OK) {
-        return err;
+        data_addr += data_len;
+        data_len_remain -= data_len;
     }
+
     return ESP_OK;
 
 err:

+ 1 - 1
components/driver/spi_master.c

@@ -872,7 +872,7 @@ static SPI_MASTER_ISR_ATTR esp_err_t setup_priv_desc(spi_transaction_t *trans_de
     }
     if (send_ptr && isdma && !esp_ptr_dma_capable( send_ptr )) {
         //if txbuf in the desc not DMA-capable, malloc a new one
-        ESP_LOGI( SPI_TAG, "Allocate TX buffer for DMA" );
+        ESP_LOGD( SPI_TAG, "Allocate TX buffer for DMA" );
         uint32_t *temp = heap_caps_malloc((trans_desc->length + 7) / 8, MALLOC_CAP_DMA);
         if (temp == NULL) goto clean_up;