Merge branch 'bugfix/bootloader_common_get_sha256_of_partition_v3.3' into 'release/v3.3'
bootloader_support: Fix bootloader_common_get_sha256_of_partition(), can handle a long image (v3.3) See merge request espressif/esp-idf!9955
This commit is contained in:
commit
0f6b7ad3cf
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
|
@ -26,6 +26,8 @@
|
|||
#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"
|
||||
#include "soc/rtc.h"
|
||||
|
@ -186,22 +188,7 @@ esp_err_t bootloader_common_get_sha256_of_partition (uint32_t address, uint32_t
|
|||
size = data.image_len;
|
||||
}
|
||||
// If image is type by data then hash is calculated for entire image.
|
||||
const void *partition_bin = bootloader_mmap(address, size);
|
||||
if (partition_bin == NULL) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", address, size);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
bootloader_sha256_handle_t sha_handle = bootloader_sha256_start();
|
||||
if (sha_handle == NULL) {
|
||||
bootloader_munmap(partition_bin);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
bootloader_sha256_data(sha_handle, partition_bin, size);
|
||||
bootloader_sha256_finish(sha_handle, out_sha_256);
|
||||
|
||||
bootloader_munmap(partition_bin);
|
||||
|
||||
return ESP_OK;
|
||||
return bootloader_sha256_flash_contents(address, size, out_sha_256);
|
||||
}
|
||||
|
||||
int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata, bool *valid_two_otadata, bool max)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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]")
|
||||
{
|
||||
|
@ -66,3 +67,27 @@ TEST_CASE("Test erase partition", "[spi_flash]")
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Test esp_partition_get_sha256() that it can handle a big partition", "[spi_flash]")
|
||||
{
|
||||
esp_partition_t partition;
|
||||
const void *ptr;
|
||||
spi_flash_mmap_handle_t handle;
|
||||
|
||||
uint8_t sha256[32] = { 0 };
|
||||
size_t size_flash_chip = spi_flash_get_chip_size();
|
||||
|
||||
printf("size_flash_chip = %d bytes\n", size_flash_chip);
|
||||
|
||||
ESP_ERROR_CHECK(spi_flash_mmap(0x00000000, size_flash_chip * 7 / 10, SPI_FLASH_MMAP_DATA, &ptr, &handle));
|
||||
TEST_ASSERT_NOT_NULL(ptr);
|
||||
|
||||
partition.address = 0x00000000;
|
||||
partition.size = size_flash_chip;
|
||||
partition.type = ESP_PARTITION_TYPE_DATA;
|
||||
|
||||
ESP_ERROR_CHECK(esp_partition_get_sha256(&partition, sha256));
|
||||
ESP_LOG_BUFFER_HEX("sha", sha256, sizeof(sha256));
|
||||
|
||||
spi_flash_munmap(handle);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue