Explorar el Código

Merge branch 'bugfix/sec_boot_ota_fail_v33' into 'release/v3.3'

Bugfix: ota fails with secure boot on for image size greater than 3.2MB (backport v3.3)

See merge request espressif/esp-idf!5581
Angus Gratton hace 6 años
padre
commit
a6fb161309

+ 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) {

+ 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:

+ 37 - 21
components/bootloader_support/src/secure_boot_signatures.c

@@ -21,12 +21,7 @@
 
 #include "uECC.h"
 
-#ifdef BOOTLOADER_BUILD
-#include "rom/sha.h"
-typedef SHA_CTX sha_context;
-#else
-#include "mbedtls/sha256.h"
-#endif
+#include <sys/param.h>
 
 static const char* TAG = "secure_boot";
 
@@ -37,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];
@@ -45,26 +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
-#ifdef BOOTLOADER_BUILD
-    bootloader_sha256_handle_t handle = bootloader_sha256_start();
-    bootloader_sha256_data(handle, data, length);
+    /* Done! Get the digest */
     bootloader_sha256_finish(handle, digest);
-#else
-    /* Use thread-safe mbedTLS version */
-    mbedtls_sha256_ret(data, length, digest, 0);
-#endif
 
-    // 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;
 }
 

+ 1 - 1
components/driver/spi_master.c

@@ -1174,7 +1174,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;