From 9ce137139be58e87eb0ab86c808ed2a6604bb3bf Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Thu, 6 Aug 2020 15:22:26 +0800 Subject: [PATCH] bootloader: Adds bootloader_sha256_flash_contents() --- .../include_bootloader/bootloader_flash.h | 3 +- .../include_bootloader/bootloader_sha.h | 2 +- .../include_bootloader/bootloader_utility.h | 14 ++++++++ .../src/bootloader_common.c | 1 + .../bootloader_support/src/bootloader_sha.c | 5 +-- .../src/bootloader_utility.c | 36 +++++++++++++++++++ components/spi_flash/test/test_partitions.c | 1 + 7 files changed, 58 insertions(+), 4 deletions(-) diff --git a/components/bootloader_support/include_bootloader/bootloader_flash.h b/components/bootloader_support/include_bootloader/bootloader_flash.h index 6ac7246462..705fa44e91 100644 --- a/components/bootloader_support/include_bootloader/bootloader_flash.h +++ b/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 diff --git a/components/bootloader_support/include_bootloader/bootloader_sha.h b/components/bootloader_support/include_bootloader/bootloader_sha.h index 079a457917..48f65feedb 100644 --- a/components/bootloader_support/include_bootloader/bootloader_sha.h +++ b/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); diff --git a/components/bootloader_support/include_bootloader/bootloader_utility.h b/components/bootloader_support/include_bootloader/bootloader_utility.h index 31213a0160..227a328a87 100644 --- a/components/bootloader_support/include_bootloader/bootloader_utility.h +++ b/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); \ No newline at end of file diff --git a/components/bootloader_support/src/bootloader_common.c b/components/bootloader_support/src/bootloader_common.c index 3ab2af7922..3b5a0497e1 100644 --- a/components/bootloader_support/src/bootloader_common.c +++ b/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" diff --git a/components/bootloader_support/src/bootloader_sha.c b/components/bootloader_support/src/bootloader_sha.c index 1f7c1b4934..aed31396b2 100644 --- a/components/bootloader_support/src/bootloader_sha.c +++ b/components/bootloader_support/src/bootloader_sha.c @@ -21,7 +21,7 @@ // App version is a wrapper around mbedTLS SHA API #include -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(); diff --git a/components/bootloader_support/src/bootloader_utility.c b/components/bootloader_support/src/bootloader_utility.c index 99bae94554..e5c6dad5b8 100644 --- a/components/bootloader_support/src/bootloader_utility.c +++ b/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; +} \ No newline at end of file diff --git a/components/spi_flash/test/test_partitions.c b/components/spi_flash/test/test_partitions.c index aa065d794b..d280f26255 100644 --- a/components/spi_flash/test/test_partitions.c +++ b/components/spi_flash/test/test_partitions.c @@ -24,6 +24,7 @@ #include #include #include +#include "esp_log.h" TEST_CASE("Test erase partition", "[spi_flash]") {