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) {
*/
#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) {
#include "esp32/rom/sha.h"
#include "uECC.h"
-typedef SHA_CTX sha_context;
+#include <sys/param.h>
static const char *TAG = "secure_boot";
#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];
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;
}