secure boot: Fix bootloader image verification failure

* Failure prevented secure boot from enabling.
* Also adds unit test cases for esp_image_basic_verify()

Ref https://esp32.com/viewtopic.php?f=2&t=1602
TW11878
This commit is contained in:
Angus Gratton 2017-04-24 16:21:27 +10:00 committed by Angus Gratton
parent b540322dc1
commit e2479b46f7
6 changed files with 71 additions and 22 deletions

View file

@ -22,16 +22,9 @@ extern "C"
#endif
#include "esp_flash_data_types.h"
#include "soc/soc.h"
#define SPI_SEC_SIZE 0x1000
#define IROM_LOW 0x400D0000
#define IROM_HIGH 0x40400000
#define DROM_LOW 0x3F400000
#define DROM_HIGH 0x3F800000
#define RTC_IRAM_LOW 0x400C0000
#define RTC_IRAM_HIGH 0x400C2000
#define RTC_DATA_LOW 0x50000000
#define RTC_DATA_HIGH 0x50002000
#define SPI_ERROR_LOG "spi flash error"

View file

@ -475,7 +475,7 @@ static void unpack_load_app(const esp_partition_pos_t* partition)
// TODO: actually check md5
}
if (address >= DROM_LOW && address < DROM_HIGH) {
if (address >= SOC_DROM_LOW && address < SOC_DROM_HIGH) {
ESP_LOGD(TAG, "found drom segment, map from %08x to %08x", data_offs,
segment_header.load_addr);
drom_addr = data_offs;
@ -485,7 +485,7 @@ static void unpack_load_app(const esp_partition_pos_t* partition)
map = true;
}
if (address >= IROM_LOW && address < IROM_HIGH) {
if (address >= SOC_IROM_LOW && address < SOC_IROM_HIGH) {
ESP_LOGD(TAG, "found irom segment, map from %08x to %08x", data_offs,
segment_header.load_addr);
irom_addr = data_offs;
@ -495,12 +495,12 @@ static void unpack_load_app(const esp_partition_pos_t* partition)
map = true;
}
if (!load_rtc_memory && address >= RTC_IRAM_LOW && address < RTC_IRAM_HIGH) {
if (!load_rtc_memory && address >= SOC_RTC_IRAM_LOW && address < SOC_RTC_IRAM_HIGH) {
ESP_LOGD(TAG, "Skipping RTC code segment at %08x\n", data_offs);
load = false;
}
if (!load_rtc_memory && address >= RTC_DATA_LOW && address < RTC_DATA_HIGH) {
if (!load_rtc_memory && address >= SOC_RTC_DATA_LOW && address < SOC_RTC_DATA_HIGH) {
ESP_LOGD(TAG, "Skipping RTC data segment at %08x\n", data_offs);
load = false;
}

View file

@ -108,16 +108,6 @@ esp_err_t esp_image_basic_verify(uint32_t src_addr, bool log_errors, uint32_t *p
*p_length = 0;
}
if (src_addr % SPI_FLASH_MMU_PAGE_SIZE != 0) {
/* Image must start on a 64KB boundary
(This is not a technical limitation, only the flash mapped regions need to be 64KB aligned. But the most
consistent way to do this is to have all the offsets internal to the image correctly 64KB aligned, and then
start the image on a 64KB boundary also.)
*/
return ESP_ERR_INVALID_ARG;
}
err = esp_image_load_header(src_addr, log_errors, &image_header);
if (err != ESP_OK) {
return err;
@ -133,6 +123,21 @@ esp_err_t esp_image_basic_verify(uint32_t src_addr, bool log_errors, uint32_t *p
return err;
}
uint32_t load_addr = segment_header.load_addr;
bool map_segment = (load_addr >= SOC_DROM_LOW && load_addr < SOC_DROM_HIGH)
|| (load_addr >= SOC_IROM_LOW && load_addr < SOC_IROM_HIGH);
/* Check that flash cache mapped segment aligns correctly from flash it's mapped address,
relative to the 64KB page mapping size.
*/
ESP_LOGV(TAG, "segment %d map_segment %d segment_data_offs 0x%x load_addr 0x%x",
i, map_segment, segment_data_offs, load_addr);
if (map_segment && ((segment_data_offs % SPI_FLASH_MMU_PAGE_SIZE) != (load_addr % SPI_FLASH_MMU_PAGE_SIZE))) {
ESP_LOGE(TAG, "Segment %d has load address 0x%08x, conflict with segment data at 0x%08x",
i, load_addr, segment_data_offs);
}
for (int i = 0; i < segment_header.data_len; i += sizeof(buf)) {
err = bootloader_flash_read(segment_data_offs + i, buf, sizeof(buf), true);
if (err != ESP_OK) {

View file

@ -0,0 +1,4 @@
#
#Component Makefile
#
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive

View file

@ -0,0 +1,37 @@
/*
* Tests for bootloader_support esp_image_basic_verify()
*/
#include <esp_types.h>
#include <stdio.h>
#include "rom/ets_sys.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "freertos/xtensa_api.h"
#include "unity.h"
#include "esp_partition.h"
#include "esp_ota_ops.h"
#include "esp_image_format.h"
TEST_CASE("Verify bootloader image in flash", "[bootloader_support]")
{
uint32_t image_len = 0;
TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_basic_verify(0x1000, true, &image_len));
TEST_ASSERT_NOT_EQUAL(0, image_len);
}
TEST_CASE("Verify unit test app image", "[bootloader_support]")
{
uint32_t image_len = 0;
const esp_partition_t *running = esp_ota_get_running_partition();
TEST_ASSERT_NOT_EQUAL(NULL, running);
TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_basic_verify(running->address, true, &image_len));
TEST_ASSERT_NOT_EQUAL(0, image_len);
TEST_ASSERT_TRUE(image_len <= running->size);
}

View file

@ -149,6 +149,16 @@
#define TICKS_PER_US_ROM 26 // CPU is 80MHz
//}}
/* Overall memory map */
#define SOC_IROM_LOW 0x400D0000
#define SOC_IROM_HIGH 0x40400000
#define SOC_DROM_LOW 0x3F400000
#define SOC_DROM_HIGH 0x3F800000
#define SOC_RTC_IRAM_LOW 0x400C0000
#define SOC_RTC_IRAM_HIGH 0x400C2000
#define SOC_RTC_DATA_LOW 0x50000000
#define SOC_RTC_DATA_HIGH 0x50002000
#define DR_REG_DPORT_BASE 0x3ff00000
#define DR_REG_RSA_BASE 0x3ff02000
#define DR_REG_SHA_BASE 0x3ff03000