Parcourir la source

bootloader: Adds bootloader_sha256_flash_contents()

KonstantinKondrashov il y a 5 ans
Parent
commit
9ce137139b

+ 2 - 1
components/bootloader_support/include_bootloader/bootloader_flash.h

@@ -22,6 +22,7 @@
 
 #define FLASH_SECTOR_SIZE 0x1000
 #define FLASH_BLOCK_SIZE 0x10000
+#define MMAP_ALIGNED_MASK 0x0000FFFF
 
 /* Provide a Flash API for bootloader_support code,
    that can be used from bootloader or app code.
@@ -35,7 +36,7 @@
  *
  * @return Number of free pages
  */
-uint32_t bootloader_mmap_get_free_pages();
+uint32_t bootloader_mmap_get_free_pages(void);
 
 /**
  * @brief Map a region of flash to data memory

+ 1 - 1
components/bootloader_support/include_bootloader/bootloader_sha.h

@@ -26,7 +26,7 @@
 
 typedef void *bootloader_sha256_handle_t;
 
-bootloader_sha256_handle_t bootloader_sha256_start();
+bootloader_sha256_handle_t bootloader_sha256_start(void);
 
 void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data, size_t data_len);
 

+ 14 - 0
components/bootloader_support/include_bootloader/bootloader_utility.h

@@ -62,3 +62,17 @@ __attribute__((noreturn)) void bootloader_utility_load_boot_image(const bootload
  * It is not recommended to call this function from an app (if called, the app will abort).
  */
 __attribute__((noreturn)) void bootloader_reset(void);
+
+/** @brief Generates the digest of the data between offset & offset+length.
+ *
+ * This function should be used when the size of the data is larger than 3.2MB.
+ * The MMU capacity is 3.2MB (50 pages - 64KB each). This function generates the SHA-256 
+ * of the data in chunks of 3.2MB, considering the MMU capacity. 
+ * 
+ * @param[in]  flash_offset  Offset of the data in flash.
+ * @param[in]  len           Length of data in bytes.
+ * @param[out] digest        Pointer to buffer where the digest is written, if ESP_OK is returned. 
+ * 
+ * @return ESP_OK if secure boot digest is generated successfully.
+ */
+esp_err_t bootloader_sha256_flash_contents(uint32_t flash_offset, uint32_t len, uint8_t *digest);

+ 1 - 0
components/bootloader_support/src/bootloader_common.c

@@ -26,6 +26,7 @@
 #include "esp_flash_partitions.h"
 #include "bootloader_flash.h"
 #include "bootloader_common.h"
+#include "bootloader_config.h"
 #include "bootloader_utility.h"
 #include "soc/gpio_periph.h"
 #include "soc/efuse_reg.h"

+ 3 - 2
components/bootloader_support/src/bootloader_sha.c

@@ -21,7 +21,7 @@
 // App version is a wrapper around mbedTLS SHA API
 #include <mbedtls/sha256.h>
 
-bootloader_sha256_handle_t bootloader_sha256_start()
+bootloader_sha256_handle_t bootloader_sha256_start(void)
 {
     mbedtls_sha256_context *ctx = (mbedtls_sha256_context *)malloc(sizeof(mbedtls_sha256_context));
     if (!ctx) {
@@ -53,6 +53,7 @@ void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest
     }
     mbedtls_sha256_free(ctx);
     free(handle);
+    handle = NULL;
 }
 
 #else // Bootloader version
@@ -70,7 +71,7 @@ static const size_t BLOCK_WORDS = (64/sizeof(uint32_t));
 // Words in final SHA256 digest
 static const size_t DIGEST_WORDS = (32/sizeof(uint32_t));
 
-bootloader_sha256_handle_t bootloader_sha256_start()
+bootloader_sha256_handle_t bootloader_sha256_start(void)
 {
     // Enable SHA hardware
     ets_sha_enable();

+ 36 - 0
components/bootloader_support/src/bootloader_utility.c

@@ -703,3 +703,39 @@ void bootloader_reset(void)
     abort();            /* This function should really not be called from application code */
 #endif
 }
+
+
+esp_err_t bootloader_sha256_flash_contents(uint32_t flash_offset, uint32_t len, uint8_t *digest)
+{
+
+    if (digest == NULL) {
+        return ESP_ERR_INVALID_ARG;
+    }
+
+    /* Handling firmware images larger than MMU capacity */
+    uint32_t mmu_free_pages_count = bootloader_mmap_get_free_pages();
+    bootloader_sha256_handle_t sha_handle = NULL;
+
+    sha_handle = bootloader_sha256_start();
+    if (sha_handle == NULL) {
+        return ESP_ERR_NO_MEM;
+    }
+
+    while (len > 0) {
+        uint32_t mmu_page_offset = ((flash_offset & MMAP_ALIGNED_MASK) != 0) ? 1 : 0; /* Skip 1st MMU Page if it is already populated */
+        uint32_t partial_image_len = MIN(len, ((mmu_free_pages_count - mmu_page_offset) * SPI_FLASH_MMU_PAGE_SIZE)); /* Read the image that fits in the free MMU pages */
+
+        const void * image = bootloader_mmap(flash_offset, partial_image_len);
+        if (image == NULL) {
+            bootloader_sha256_finish(sha_handle, NULL);
+            return ESP_FAIL;
+        }
+        bootloader_sha256_data(sha_handle, image, partial_image_len);
+        bootloader_munmap(image);
+
+        flash_offset += partial_image_len;
+        len -= partial_image_len;
+    }
+    bootloader_sha256_finish(sha_handle, digest);
+    return ESP_OK;
+}

+ 1 - 0
components/spi_flash/test/test_partitions.c

@@ -24,6 +24,7 @@
 #include <test_utils.h>
 #include <esp_partition.h>
 #include <esp_attr.h>
+#include "esp_log.h"
 
 TEST_CASE("Test erase partition", "[spi_flash]")
 {