From e37d6e40b0d99679d3687c62b3caea77d853359d Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Thu, 30 Jul 2026 02:06:55 +0530 Subject: [PATCH] refactor(esp_system): deduplicate ROM fast wake RTC digest reservation The digest length and the condition that reserves it at the end of RTC RAM were duplicated in seven places. Hold the reservation in a hidden Kconfig value that is zero when the feature does not apply, so every consumer subtracts it unconditionally, and derive ESP_SECURE_BOOT_DIGEST_LEN from it. --- components/bootloader/Kconfig.projbuild | 21 +++++++++++++++++++ .../include/esp_secure_boot.h | 2 +- .../src/bootloader_common_loader.c | 20 +++++++++--------- .../esp_system/ld/esp32c3/sections.ld.in | 10 +++++++++ .../esp_system/ld/esp32c6/sections.ld.in | 10 +++++++++ .../esp_system/ld/esp32h2/sections.ld.in | 10 +++++++++ .../esp_system/ld/esp32s2/sections.ld.in | 10 +++++++++ .../esp_system/ld/esp32s3/sections.ld.in | 10 +++++++++ components/esp_system/ld/ld.common | 12 ++--------- components/heap/port/esp32c6/memory_layout.c | 14 +------------ components/heap/port/esp32h2/memory_layout.c | 14 +------------ 11 files changed, 86 insertions(+), 47 deletions(-) diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index 7b1ba1588a4..8b9831c5d49 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -646,6 +646,27 @@ menu "Security features" endchoice + config SECURE_BOOT_IMAGE_DIGEST_LEN + int + default 48 if SECURE_BOOT_ECDSA_KEY_LEN_384_BITS + default 32 + help + Length in bytes of the application image digest used by Secure Boot V2. + Kept in sync with ESP_SECURE_BOOT_DIGEST_LEN in esp_secure_boot.h, and + usable from linker scripts and from components that cannot depend on + bootloader_support. + + config SECURE_BOOT_ROM_FAST_WAKE_RESERVE_SIZE + int + default SECURE_BOOT_IMAGE_DIGEST_LEN if SECURE_BOOT && ESP_ROM_SUPPORT_SECURE_BOOT_FAST_WAKEUP + default 0 + help + Number of bytes that must be left untouched at the end of RTC/LP RAM for + the ROM secure boot fast wake up feature, which stores the digest of the + verified application image there and re-checks it on deep sleep wake up. + Zero when the feature is not applicable, so that consumers can subtract + this value unconditionally. + config SECURE_SIGNED_ON_BOOT_NO_SECURE_BOOT bool "Bootloader verifies app signatures" default n diff --git a/components/bootloader_support/include/esp_secure_boot.h b/components/bootloader_support/include/esp_secure_boot.h index 9250ca0bd57..5fbdac11962 100644 --- a/components/bootloader_support/include/esp_secure_boot.h +++ b/components/bootloader_support/include/esp_secure_boot.h @@ -30,7 +30,7 @@ extern "C" { Can be compiled as part of app or bootloader code. */ -#define ESP_SECURE_BOOT_DIGEST_LEN 32 +#define ESP_SECURE_BOOT_DIGEST_LEN CONFIG_SECURE_BOOT_IMAGE_DIGEST_LEN #if CONFIG_IDF_TARGET_ESP32C2 #define ESP_SECURE_BOOT_KEY_DIGEST_LEN 16 diff --git a/components/bootloader_support/src/bootloader_common_loader.c b/components/bootloader_support/src/bootloader_common_loader.c index 864643296ea..45d6c4daa59 100644 --- a/components/bootloader_support/src/bootloader_common_loader.c +++ b/components/bootloader_support/src/bootloader_common_loader.c @@ -14,9 +14,6 @@ #include "esp_rom_crc.h" #include "esp_rom_gpio.h" #include "esp_flash_partitions.h" -#if CONFIG_SECURE_BOOT -#include "esp_secure_boot.h" -#endif #include "bootloader_flash.h" #include "bootloader_common.h" #include "soc/gpio_periph.h" @@ -33,6 +30,14 @@ #define ESP_PARTITION_HASH_LEN 32 /* SHA-256 digest length */ #define IS_FIELD_SET(rev_full) (((rev_full) != 65535) && ((rev_full) != 0)) +#if ESP_ROM_HAS_LP_ROM && CONFIG_SECURE_BOOT_ROM_FAST_WAKE_RESERVE_SIZE > 0 +#error "Retain mem is placed at the start of RTC RAM on this target, while the ROM keeps the secure boot fast wake up digest at the end of it. The layout needs to be re-evaluated." +#endif + +#if CONFIG_SECURE_BOOT && ESP_ROM_SUPPORT_SECURE_BOOT_FAST_WAKEUP && CONFIG_SECURE_BOOT_ROM_FAST_WAKE_RESERVE_SIZE == 0 +#error "esp_rom_caps.h advertises ROM secure boot fast wake up support that Kconfig.soc_caps.in does not, so the digest area is left unreserved." +#endif + static const char* TAG = "boot_comm"; uint32_t bootloader_common_ota_select_crc(const esp_ota_select_entry_t *s) @@ -243,13 +248,8 @@ rtc_retain_mem_t* bootloader_common_get_rtc_retain_mem(void) { #ifdef BOOTLOADER_BUILD #define RTC_RETAIN_MEM_ADDR (SOC_RTC_DRAM_HIGH - sizeof(rtc_retain_mem_t)) -#if CONFIG_SECURE_BOOT && ESP_ROM_SUPPORT_SECURE_BOOT_FAST_WAKEUP - /* ROM stores the verified image digest in the last ESP_SECURE_BOOT_DIGEST_LEN - * bytes of LP/RTC RAM on deep-sleep wake. Keep retain mem below that region. */ - static rtc_retain_mem_t *const s_bootloader_retain_mem = (rtc_retain_mem_t *)((uintptr_t)RTC_RETAIN_MEM_ADDR - ESP_SECURE_BOOT_DIGEST_LEN); -#else - static rtc_retain_mem_t *const s_bootloader_retain_mem = (rtc_retain_mem_t *)RTC_RETAIN_MEM_ADDR; -#endif + static rtc_retain_mem_t *const s_bootloader_retain_mem = + (rtc_retain_mem_t *)((uintptr_t)RTC_RETAIN_MEM_ADDR - CONFIG_SECURE_BOOT_ROM_FAST_WAKE_RESERVE_SIZE); return s_bootloader_retain_mem; #else static __attribute__((section(".bootloader_data_rtc_mem"))) rtc_retain_mem_t s_bootloader_retain_mem; diff --git a/components/esp_system/ld/esp32c3/sections.ld.in b/components/esp_system/ld/esp32c3/sections.ld.in index d602158a7f3..50041156044 100644 --- a/components/esp_system/ld/esp32c3/sections.ld.in +++ b/components/esp_system/ld/esp32c3/sections.ld.in @@ -120,9 +120,19 @@ SECTIONS *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) + _bootloader_data_rtc_mem_end = ABSOLUTE(.); + /* ROM keeps the verified image digest in the last bytes of RTC RAM */ + . = . + CONFIG_SECURE_BOOT_ROM_FAST_WAKE_RESERVE_SIZE; + _rtc_reserved_end = ABSOLUTE(.); } > rtc_reserved_seg +#if CONFIG_SECURE_BOOT_ROM_FAST_WAKE_RESERVE_SIZE > 0 + ASSERT((_bootloader_data_rtc_mem_end == ORIGIN(rtc_reserved_seg) + LENGTH(rtc_reserved_seg) + - CONFIG_SECURE_BOOT_ROM_FAST_WAKE_RESERVE_SIZE), + "The ROM secure boot fast wake up digest must occupy the last bytes of RTC RAM, and the bootloader retain mem must end where it begins. bootloader_common_get_rtc_retain_mem() computes that address.") +#endif + _rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start; ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)), "RTC reserved segment data does not fit.") diff --git a/components/esp_system/ld/esp32c6/sections.ld.in b/components/esp_system/ld/esp32c6/sections.ld.in index 2d06398f6a4..1ab7e5524df 100644 --- a/components/esp_system/ld/esp32c6/sections.ld.in +++ b/components/esp_system/ld/esp32c6/sections.ld.in @@ -122,9 +122,19 @@ SECTIONS *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) + _bootloader_data_rtc_mem_end = ABSOLUTE(.); + /* ROM keeps the verified image digest in the last bytes of RTC RAM */ + . = . + CONFIG_SECURE_BOOT_ROM_FAST_WAKE_RESERVE_SIZE; + _rtc_reserved_end = ABSOLUTE(.); } > rtc_reserved_seg +#if CONFIG_SECURE_BOOT_ROM_FAST_WAKE_RESERVE_SIZE > 0 + ASSERT((_bootloader_data_rtc_mem_end == ORIGIN(rtc_reserved_seg) + LENGTH(rtc_reserved_seg) + - CONFIG_SECURE_BOOT_ROM_FAST_WAKE_RESERVE_SIZE), + "The ROM secure boot fast wake up digest must occupy the last bytes of RTC RAM, and the bootloader retain mem must end where it begins. bootloader_common_get_rtc_retain_mem() computes that address.") +#endif + _rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start; ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)), "RTC reserved segment data does not fit.") diff --git a/components/esp_system/ld/esp32h2/sections.ld.in b/components/esp_system/ld/esp32h2/sections.ld.in index 4e4a529ffc2..535b01196a3 100644 --- a/components/esp_system/ld/esp32h2/sections.ld.in +++ b/components/esp_system/ld/esp32h2/sections.ld.in @@ -122,9 +122,19 @@ SECTIONS *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) + _bootloader_data_rtc_mem_end = ABSOLUTE(.); + /* ROM keeps the verified image digest in the last bytes of RTC RAM */ + . = . + CONFIG_SECURE_BOOT_ROM_FAST_WAKE_RESERVE_SIZE; + _rtc_reserved_end = ABSOLUTE(.); } > rtc_reserved_seg +#if CONFIG_SECURE_BOOT_ROM_FAST_WAKE_RESERVE_SIZE > 0 + ASSERT((_bootloader_data_rtc_mem_end == ORIGIN(rtc_reserved_seg) + LENGTH(rtc_reserved_seg) + - CONFIG_SECURE_BOOT_ROM_FAST_WAKE_RESERVE_SIZE), + "The ROM secure boot fast wake up digest must occupy the last bytes of RTC RAM, and the bootloader retain mem must end where it begins. bootloader_common_get_rtc_retain_mem() computes that address.") +#endif + _rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start; ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)), "RTC reserved segment data does not fit.") diff --git a/components/esp_system/ld/esp32s2/sections.ld.in b/components/esp_system/ld/esp32s2/sections.ld.in index 9b46dbe095a..44525776c15 100644 --- a/components/esp_system/ld/esp32s2/sections.ld.in +++ b/components/esp_system/ld/esp32s2/sections.ld.in @@ -132,9 +132,19 @@ SECTIONS *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) + _bootloader_data_rtc_mem_end = ABSOLUTE(.); + /* ROM keeps the verified image digest in the last bytes of RTC RAM */ + . = . + CONFIG_SECURE_BOOT_ROM_FAST_WAKE_RESERVE_SIZE; + _rtc_reserved_end = ABSOLUTE(.); } > rtc_reserved_seg +#if CONFIG_SECURE_BOOT_ROM_FAST_WAKE_RESERVE_SIZE > 0 + ASSERT((_bootloader_data_rtc_mem_end == ORIGIN(rtc_reserved_seg) + LENGTH(rtc_reserved_seg) + - CONFIG_SECURE_BOOT_ROM_FAST_WAKE_RESERVE_SIZE), + "The ROM secure boot fast wake up digest must occupy the last bytes of RTC RAM, and the bootloader retain mem must end where it begins. bootloader_common_get_rtc_retain_mem() computes that address.") +#endif + _rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start; ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)), "RTC reserved segment data does not fit.") diff --git a/components/esp_system/ld/esp32s3/sections.ld.in b/components/esp_system/ld/esp32s3/sections.ld.in index 3bfe2e1ce8d..2928575bfa1 100644 --- a/components/esp_system/ld/esp32s3/sections.ld.in +++ b/components/esp_system/ld/esp32s3/sections.ld.in @@ -128,9 +128,19 @@ SECTIONS *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) + _bootloader_data_rtc_mem_end = ABSOLUTE(.); + /* ROM keeps the verified image digest in the last bytes of RTC RAM */ + . = . + CONFIG_SECURE_BOOT_ROM_FAST_WAKE_RESERVE_SIZE; + _rtc_reserved_end = ABSOLUTE(.); } > rtc_reserved_seg +#if CONFIG_SECURE_BOOT_ROM_FAST_WAKE_RESERVE_SIZE > 0 + ASSERT((_bootloader_data_rtc_mem_end == ORIGIN(rtc_reserved_seg) + LENGTH(rtc_reserved_seg) + - CONFIG_SECURE_BOOT_ROM_FAST_WAKE_RESERVE_SIZE), + "The ROM secure boot fast wake up digest must occupy the last bytes of RTC RAM, and the bootloader retain mem must end where it begins. bootloader_common_get_rtc_retain_mem() computes that address.") +#endif + _rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start; ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)), "RTC reserved segment data does not fit.") diff --git a/components/esp_system/ld/ld.common b/components/esp_system/ld/ld.common index 7923775fe45..8c5b81b68cf 100644 --- a/components/esp_system/ld/ld.common +++ b/components/esp_system/ld/ld.common @@ -9,13 +9,6 @@ /* CPU instruction prefetch padding size for flash mmap scenario */ _esp_flash_mmap_prefetch_pad_size = 16; -/* Copy from esp_secure_boot.h */ -#ifdef CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS -#define ESP_SECURE_BOOT_DIGEST_LEN 48 -#else /* !CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS */ -#define ESP_SECURE_BOOT_DIGEST_LEN 32 -#endif /* CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS */ - /* CPU instruction prefetch padding size for memory protection scenario */ #ifdef CONFIG_SOC_MEMPROT_CPU_PREFETCH_PAD_SIZE _esp_memprot_prefetch_pad_size = CONFIG_SOC_MEMPROT_CPU_PREFETCH_PAD_SIZE; @@ -52,9 +45,8 @@ _esp_mmu_block_size = (CONFIG_MMU_PAGE_SIZE); #if CONFIG_IDF_TARGET_ESP32 #define RESERVE_RTC_MEM (RTC_TIMER_RESERVE_RTC) - #elif CONFIG_SECURE_BOOT && CONFIG_ESP_ROM_SUPPORT_SECURE_BOOT_FAST_WAKEUP - #define RESERVE_RTC_MEM (ESP_BOOTLOADER_RESERVE_RTC + RTC_TIMER_RESERVE_RTC + ESP_SECURE_BOOT_DIGEST_LEN) #else - #define RESERVE_RTC_MEM (ESP_BOOTLOADER_RESERVE_RTC + RTC_TIMER_RESERVE_RTC) + #define RESERVE_RTC_MEM (ESP_BOOTLOADER_RESERVE_RTC + RTC_TIMER_RESERVE_RTC \ + + CONFIG_SECURE_BOOT_ROM_FAST_WAKE_RESERVE_SIZE) #endif #endif // SOC_RTC_MEM_SUPPORTED diff --git a/components/heap/port/esp32c6/memory_layout.c b/components/heap/port/esp32c6/memory_layout.c index 64169a2d3b3..d69ea75db65 100644 --- a/components/heap/port/esp32c6/memory_layout.c +++ b/components/heap/port/esp32c6/memory_layout.c @@ -11,7 +11,6 @@ #include "soc/soc.h" #include "heap_memory_layout.h" #include "esp_heap_caps.h" -#include "esp_rom_caps.h" /** * @brief Memory type descriptors. These describe the capabilities of a type of memory in the SoC. @@ -67,17 +66,6 @@ const size_t soc_memory_type_count = sizeof(soc_memory_types) / sizeof(soc_memor */ #define APP_USABLE_DRAM_END (SOC_ROM_STACK_START - SOC_ROM_STACK_SIZE) -#if CONFIG_SECURE_BOOT && ESP_ROM_SUPPORT_SECURE_BOOT_FAST_WAKEUP -#if CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS -#define ESP_SECURE_BOOT_DIGEST_LEN 48 -#else /* !CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS */ -#define ESP_SECURE_BOOT_DIGEST_LEN 32 -#endif /* CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS */ -#define APP_USABLE_RTC_MEM_END (SOC_RTC_DATA_HIGH - ESP_SECURE_BOOT_DIGEST_LEN) -#else -#define APP_USABLE_RTC_MEM_END (SOC_RTC_DATA_HIGH) -#endif - const soc_memory_region_t soc_memory_regions[] = { { 0x40800000, 0x20000, SOC_MEMORY_TYPE_RAM, 0x40800000, false}, //D/IRAM level0, can be used as trace memory { 0x40820000, 0x20000, SOC_MEMORY_TYPE_RAM, 0x40820000, false}, //D/IRAM level1, can be used as trace memory @@ -85,7 +73,7 @@ const soc_memory_region_t soc_memory_regions[] = { { 0x40860000, (APP_USABLE_DRAM_END-0x40860000), SOC_MEMORY_TYPE_RAM, 0x40860000, false}, //D/IRAM level3, can be used as trace memory { APP_USABLE_DRAM_END, (SOC_DIRAM_DRAM_HIGH-APP_USABLE_DRAM_END), SOC_MEMORY_TYPE_RAM, APP_USABLE_DRAM_END, true}, //D/IRAM level3, can be used as trace memory (ROM reserved area) #ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP - { 0x50000000, (APP_USABLE_RTC_MEM_END - SOC_RTC_DATA_LOW), SOC_MEMORY_TYPE_RTCRAM, 0, false}, //LPRAM + { 0x50000000, (SOC_RTC_DATA_HIGH - SOC_RTC_DATA_LOW), SOC_MEMORY_TYPE_RTCRAM, 0, false}, //LPRAM #endif }; diff --git a/components/heap/port/esp32h2/memory_layout.c b/components/heap/port/esp32h2/memory_layout.c index 38cdecf4f17..c874b790875 100644 --- a/components/heap/port/esp32h2/memory_layout.c +++ b/components/heap/port/esp32h2/memory_layout.c @@ -11,7 +11,6 @@ #include "soc/soc.h" #include "heap_memory_layout.h" #include "esp_heap_caps.h" -#include "esp_rom_caps.h" /** * @brief Memory type descriptors. These describe the capabilities of a type of memory in the SoC. @@ -65,17 +64,6 @@ const size_t soc_memory_type_count = sizeof(soc_memory_types) / sizeof(soc_memor */ #define APP_USABLE_DRAM_END (SOC_ROM_STACK_START - SOC_ROM_STACK_SIZE) -#if CONFIG_SECURE_BOOT && ESP_ROM_SUPPORT_SECURE_BOOT_FAST_WAKEUP -#if CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS -#define ESP_SECURE_BOOT_DIGEST_LEN 48 -#else /* !CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS */ -#define ESP_SECURE_BOOT_DIGEST_LEN 32 -#endif /* CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS */ -#define APP_USABLE_RTC_MEM_END (SOC_RTC_DATA_HIGH - ESP_SECURE_BOOT_DIGEST_LEN) -#else -#define APP_USABLE_RTC_MEM_END (SOC_RTC_DATA_HIGH) -#endif - const soc_memory_region_t soc_memory_regions[] = { { 0x40800000, 0x10000, SOC_MEMORY_TYPE_RAM, 0x40800000, false}, //D/IRAM level 0 { 0x40810000, 0x10000, SOC_MEMORY_TYPE_RAM, 0x40810000, false}, //D/IRAM level 1 @@ -84,7 +72,7 @@ const soc_memory_region_t soc_memory_regions[] = { { 0x40840000, APP_USABLE_DRAM_END-0x40840000, SOC_MEMORY_TYPE_RAM, 0x40840000, false}, //D/IRAM level 4 { APP_USABLE_DRAM_END, (SOC_DIRAM_DRAM_HIGH-APP_USABLE_DRAM_END), SOC_MEMORY_TYPE_RAM, APP_USABLE_DRAM_END, true}, //D/IRAM level 4 #ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP - { 0x50000000, (APP_USABLE_RTC_MEM_END - SOC_RTC_DATA_LOW),SOC_MEMORY_TYPE_RTCRAM, 0, false}, //Fast RTC memory + { 0x50000000, (SOC_RTC_DATA_HIGH - SOC_RTC_DATA_LOW), SOC_MEMORY_TYPE_RTCRAM, 0, false}, //Fast RTC memory #endif };