From e7af5c69d90a76b3ddb6f4112e86ea00a7f0cfdd Mon Sep 17 00:00:00 2001 From: Ashish Sharma Date: Wed, 8 Jul 2026 15:54:40 +0800 Subject: [PATCH] feat(esp_image_verify): split image verification out of bootloader_support --- components/app_update/CMakeLists.txt | 13 +- components/app_update/esp_ota_ops.c | 34 +---- .../test_app_update/main/test_switch_ota.c | 10 +- .../bootloader/subproject/CMakeLists.txt | 1 + .../main/ld/esp32/bootloader.sections.ld.in | 9 +- .../main/ld/esp32c2/bootloader.sections.ld.in | 9 +- .../main/ld/esp32c3/bootloader.sections.ld.in | 9 +- .../main/ld/esp32c5/bootloader.sections.ld.in | 9 +- .../main/ld/esp32c6/bootloader.sections.ld.in | 9 +- .../ld/esp32c61/bootloader.sections.ld.in | 9 +- .../main/ld/esp32h2/bootloader.sections.ld.in | 9 +- .../ld/esp32h21/bootloader.sections.ld.in | 9 +- .../main/ld/esp32h4/bootloader.sections.ld.in | 9 +- .../main/ld/esp32p4/bootloader.sections.ld.in | 18 ++- .../main/ld/esp32s2/bootloader.sections.ld.in | 9 +- .../main/ld/esp32s3/bootloader.sections.ld.in | 9 +- .../ld/esp32s31/bootloader.sections.ld.in | 9 +- components/bootloader_support/CMakeLists.txt | 62 +++----- .../include/bootloader_common.h | 9 +- .../include/bootloader_sha_flash.h | 48 ++++++ .../include/esp_secure_boot.h | 10 ++ .../private_include/bootloader_utility.h | 65 +-------- .../src/bootloader_common.c | 37 ++++- .../src/bootloader_common_loader.c | 1 - .../src/bootloader_utility.c | 137 +----------------- .../bootloader_support/src/secure_boot.c | 26 +--- components/esp_image_verify/CMakeLists.txt | 80 ++++++++++ .../private_include/bootloader_sha.h | 4 +- .../private_include/bootloader_signature.h | 0 .../src/bootloader_sha.c | 12 +- .../src/bootloader_sha_flash.c | 114 +++++++++++++++ .../src/esp_image_format.c | 109 +++++++------- components/esp_image_verify/src/secure_boot.c | 33 +++++ .../src/secure_boot_v1/secure_boot.c | 23 ++- .../secure_boot_signatures_app.c | 3 +- .../secure_boot_signatures_bootloader.c | 15 +- .../src/secure_boot_v2/secure_boot.c | 13 +- .../secure_boot_ecdsa_signature.c | 28 ++-- .../secure_boot_rsa_signature.c | 22 +-- .../secure_boot_signature_priv.h | 0 .../secure_boot_signatures_app.c | 16 +- .../secure_boot_signatures_bootloader.c | 4 +- components/esp_partition/CMakeLists.txt | 4 +- .../esp_partition/include/esp_partition.h | 4 + .../include/esp_private/esp_partition_utils.h | 27 ++++ components/esp_partition/partition_target.c | 45 +++++- components/esp_tee/subproject/CMakeLists.txt | 2 +- .../attestation/esp_att_utils_crypto.c | 1 - .../attestation/esp_att_utils_json.c | 1 - .../test_apps/tee_test_fw/main/CMakeLists.txt | 2 +- tools/idf_py_actions/hints.yml | 9 ++ .../main/CMakeLists.txt | 2 +- .../system/g1_components/CMakeLists.txt | 16 +- .../system/mmu_page_size/main/CMakeLists.txt | 2 +- 54 files changed, 650 insertions(+), 520 deletions(-) create mode 100644 components/bootloader_support/include/bootloader_sha_flash.h create mode 100644 components/esp_image_verify/CMakeLists.txt rename components/{bootloader_support => esp_image_verify}/private_include/bootloader_sha.h (87%) rename components/{bootloader_support => esp_image_verify}/private_include/bootloader_signature.h (100%) rename components/{bootloader_support => esp_image_verify}/src/bootloader_sha.c (97%) create mode 100644 components/esp_image_verify/src/bootloader_sha_flash.c rename components/{bootloader_support => esp_image_verify}/src/esp_image_format.c (95%) create mode 100644 components/esp_image_verify/src/secure_boot.c rename components/{bootloader_support => esp_image_verify}/src/secure_boot_v1/secure_boot.c (91%) rename components/{bootloader_support => esp_image_verify}/src/secure_boot_v1/secure_boot_signatures_app.c (99%) rename components/{bootloader_support => esp_image_verify}/src/secure_boot_v1/secure_boot_signatures_bootloader.c (88%) rename components/{bootloader_support => esp_image_verify}/src/secure_boot_v2/secure_boot.c (97%) rename components/{bootloader_support => esp_image_verify}/src/secure_boot_v2/secure_boot_ecdsa_signature.c (85%) rename components/{bootloader_support => esp_image_verify}/src/secure_boot_v2/secure_boot_rsa_signature.c (90%) rename components/{bootloader_support => esp_image_verify}/src/secure_boot_v2/secure_boot_signature_priv.h (100%) rename components/{bootloader_support => esp_image_verify}/src/secure_boot_v2/secure_boot_signatures_app.c (97%) rename components/{bootloader_support => esp_image_verify}/src/secure_boot_v2/secure_boot_signatures_bootloader.c (98%) create mode 100644 components/esp_partition/include/esp_private/esp_partition_utils.h diff --git a/components/app_update/CMakeLists.txt b/components/app_update/CMakeLists.txt index c853ba64640..32782cf787b 100644 --- a/components/app_update/CMakeLists.txt +++ b/components/app_update/CMakeLists.txt @@ -6,12 +6,15 @@ endif() idf_component_register(SRCS "esp_ota_ops.c" INCLUDE_DIRS "include" - REQUIRES partition_table bootloader_support esp_app_format esp_bootloader_format esp_partition - PRIV_REQUIRES esptool_py efuse spi_flash) + REQUIRES partition_table bootloader_support + esp_app_format esp_bootloader_format esp_partition + PRIV_REQUIRES esptool_py efuse spi_flash esp_image_verify) -if(CONFIG_SECURE_SIGNED_DATA_PARTITION) - idf_component_optional_requires(PRIVATE mbedtls) -endif() +# mbedtls is an *optional* requirement: it is linked only when another component in +# the build pulls it in. esp_image_verify (a priv_require above) always brings +# mbedtls into app builds; this directive makes it available to esp_ota_ops at +# link time without app_update forcing mbedtls in by itself. +idf_component_optional_requires(PRIVATE mbedtls) idf_define_esp_err_codes(HEADERS include/esp_ota_ops.h) diff --git a/components/app_update/esp_ota_ops.c b/components/app_update/esp_ota_ops.c index f90b71d294b..0688a083033 100644 --- a/components/app_update/esp_ota_ops.c +++ b/components/app_update/esp_ota_ops.c @@ -31,6 +31,7 @@ #include "esp_bootloader_desc.h" #include "esp_flash.h" #include "esp_private/esp_flash_internal.h" //For dangerous write protection +#include "esp_private/esp_partition_utils.h" #include "esp_macros.h" #if CONFIG_APP_UPDATE_SECURE_SIGNED_DATA_PARTITION #include "psa/crypto.h" @@ -928,38 +929,7 @@ const esp_partition_t *esp_ota_get_boot_partition(void) const esp_partition_t* esp_ota_get_running_partition(void) { - static const esp_partition_t *curr_partition = NULL; - - /* - * Currently running partition is unlikely to change across reset cycle, - * so it can be cached here, and avoid lookup on every flash write operation. - */ - if (curr_partition != NULL) { - return curr_partition; - } - - /* Find the flash address of this exact function. By definition that is part - of the currently running firmware. Then find the enclosing partition. */ - size_t phys_offs = spi_flash_cache2phys(esp_ota_get_running_partition); - - assert (phys_offs != SPI_FLASH_CACHE2PHYS_FAIL); /* indicates cache2phys lookup is buggy */ - - esp_partition_iterator_t it = esp_partition_find(ESP_PARTITION_TYPE_APP, - ESP_PARTITION_SUBTYPE_ANY, - NULL); - assert(it != NULL); /* has to be at least one app partition */ - - while (it != NULL) { - const esp_partition_t *p = esp_partition_get(it); - if (p->address <= phys_offs && p->address + p->size > phys_offs) { - esp_partition_iterator_release(it); - curr_partition = p; - return p; - } - it = esp_partition_next(it); - } - - abort(); /* Partition table is invalid or corrupt */ + return esp_partition_get_running_partition(); } diff --git a/components/app_update/test_apps/test_app_update/main/test_switch_ota.c b/components/app_update/test_apps/test_app_update/main/test_switch_ota.c index 0bb3c035953..d3913fcc90f 100644 --- a/components/app_update/test_apps/test_app_update/main/test_switch_ota.c +++ b/components/app_update/test_apps/test_app_update/main/test_switch_ota.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -516,7 +516,7 @@ static void test_flow6(void) // 3 Stage: run OTA0 -> check it -> erase OTA_DATA for next tests -> PASS TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0 using esp_ota_write_with_offset", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow6, test_flow6); -TEST_CASE("Test bootloader_common_get_sha256_of_partition returns ESP_ERR_IMAGE_INVALID when image is invalid", "[partitions]") +TEST_CASE("Test esp_partition_get_sha256 returns ESP_ERR_IMAGE_INVALID when image is invalid", "[partitions]") { const esp_partition_t *cur_app = esp_ota_get_running_partition(); ESP_LOGI(TAG, "copy current app to next part"); @@ -526,15 +526,15 @@ TEST_CASE("Test bootloader_common_get_sha256_of_partition returns ESP_ERR_IMAGE_ uint8_t sha_256_cur_app[32]; uint8_t sha_256_other_app[32]; - TEST_ESP_OK(bootloader_common_get_sha256_of_partition(cur_app->address, cur_app->size, cur_app->type, sha_256_cur_app)); - TEST_ESP_OK(bootloader_common_get_sha256_of_partition(other_app->address, other_app->size, other_app->type, sha_256_other_app)); + TEST_ESP_OK(esp_partition_get_sha256(cur_app, sha_256_cur_app)); + TEST_ESP_OK(esp_partition_get_sha256(other_app, sha_256_other_app)); TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha_256_cur_app, sha_256_other_app, sizeof(sha_256_cur_app), "must be the same"); uint32_t data = 0; bootloader_flash_write(other_app->address + 0x50, &data, sizeof(data), false); - TEST_ESP_ERR(ESP_ERR_IMAGE_INVALID, bootloader_common_get_sha256_of_partition(other_app->address, other_app->size, other_app->type, sha_256_other_app)); + TEST_ESP_ERR(ESP_ERR_IMAGE_INVALID, esp_partition_get_sha256(other_app, sha_256_other_app)); TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha_256_cur_app, sha_256_other_app, sizeof(sha_256_cur_app), "must be the same"); } diff --git a/components/bootloader/subproject/CMakeLists.txt b/components/bootloader/subproject/CMakeLists.txt index 68200320c08..6d46dca8d58 100644 --- a/components/bootloader/subproject/CMakeLists.txt +++ b/components/bootloader/subproject/CMakeLists.txt @@ -32,6 +32,7 @@ set(COMPONENTS partition_table soc bootloader_support + esp_image_verify log spi_flash micro-ecc diff --git a/components/bootloader/subproject/main/ld/esp32/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32/bootloader.sections.ld.in index 3a332943eed..9c55f7cdf2f 100644 --- a/components/bootloader/subproject/main/ld/esp32/bootloader.sections.ld.in +++ b/components/bootloader/subproject/main/ld/esp32/bootloader.sections.ld.in @@ -17,17 +17,18 @@ *libesp_common.a:fpga_overrides.*(.literal.bootloader_fill_random .text.bootloader_fill_random) \ *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha_flash.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ diff --git a/components/bootloader/subproject/main/ld/esp32c2/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32c2/bootloader.sections.ld.in index 69d70bc7d6a..62355c0e853 100644 --- a/components/bootloader/subproject/main/ld/esp32c2/bootloader.sections.ld.in +++ b/components/bootloader/subproject/main/ld/esp32c2/bootloader.sections.ld.in @@ -16,17 +16,18 @@ *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) \ *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha_flash.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ diff --git a/components/bootloader/subproject/main/ld/esp32c3/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32c3/bootloader.sections.ld.in index 3b5f2177af3..11f13c9d6c3 100644 --- a/components/bootloader/subproject/main/ld/esp32c3/bootloader.sections.ld.in +++ b/components/bootloader/subproject/main/ld/esp32c3/bootloader.sections.ld.in @@ -15,17 +15,18 @@ *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) \ *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha_flash.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ diff --git a/components/bootloader/subproject/main/ld/esp32c5/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32c5/bootloader.sections.ld.in index 330bf7c56ae..912ca71e9c3 100644 --- a/components/bootloader/subproject/main/ld/esp32c5/bootloader.sections.ld.in +++ b/components/bootloader/subproject/main/ld/esp32c5/bootloader.sections.ld.in @@ -17,17 +17,18 @@ *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) \ *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha_flash.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ diff --git a/components/bootloader/subproject/main/ld/esp32c6/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32c6/bootloader.sections.ld.in index 970d5811ed3..b9d5348acf3 100644 --- a/components/bootloader/subproject/main/ld/esp32c6/bootloader.sections.ld.in +++ b/components/bootloader/subproject/main/ld/esp32c6/bootloader.sections.ld.in @@ -18,17 +18,18 @@ *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_utility_tee.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha_flash.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ diff --git a/components/bootloader/subproject/main/ld/esp32c61/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32c61/bootloader.sections.ld.in index 235e680bb9a..a431188a747 100644 --- a/components/bootloader/subproject/main/ld/esp32c61/bootloader.sections.ld.in +++ b/components/bootloader/subproject/main/ld/esp32c61/bootloader.sections.ld.in @@ -17,17 +17,18 @@ *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) \ *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha_flash.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ diff --git a/components/bootloader/subproject/main/ld/esp32h2/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32h2/bootloader.sections.ld.in index 2eb1cd0e221..cdb0356aaa1 100644 --- a/components/bootloader/subproject/main/ld/esp32h2/bootloader.sections.ld.in +++ b/components/bootloader/subproject/main/ld/esp32h2/bootloader.sections.ld.in @@ -16,17 +16,18 @@ *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) \ *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha_flash.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ diff --git a/components/bootloader/subproject/main/ld/esp32h21/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32h21/bootloader.sections.ld.in index 2eb1cd0e221..cdb0356aaa1 100644 --- a/components/bootloader/subproject/main/ld/esp32h21/bootloader.sections.ld.in +++ b/components/bootloader/subproject/main/ld/esp32h21/bootloader.sections.ld.in @@ -16,17 +16,18 @@ *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) \ *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha_flash.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ diff --git a/components/bootloader/subproject/main/ld/esp32h4/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32h4/bootloader.sections.ld.in index 235e680bb9a..a431188a747 100644 --- a/components/bootloader/subproject/main/ld/esp32h4/bootloader.sections.ld.in +++ b/components/bootloader/subproject/main/ld/esp32h4/bootloader.sections.ld.in @@ -17,17 +17,18 @@ *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) \ *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha_flash.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ diff --git a/components/bootloader/subproject/main/ld/esp32p4/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32p4/bootloader.sections.ld.in index d4b3b2fff15..4f8d7eb7869 100644 --- a/components/bootloader/subproject/main/ld/esp32p4/bootloader.sections.ld.in +++ b/components/bootloader/subproject/main/ld/esp32p4/bootloader.sections.ld.in @@ -16,17 +16,18 @@ *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) \ *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha_flash.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ @@ -57,17 +58,18 @@ *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) \ *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha_flash.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ diff --git a/components/bootloader/subproject/main/ld/esp32s2/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32s2/bootloader.sections.ld.in index f38f53823da..4dcc26c67c2 100644 --- a/components/bootloader/subproject/main/ld/esp32s2/bootloader.sections.ld.in +++ b/components/bootloader/subproject/main/ld/esp32s2/bootloader.sections.ld.in @@ -17,17 +17,18 @@ *libesp_common.a:fpga_overrides.*(.literal.bootloader_fill_random .text.bootloader_fill_random) \ *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha_flash.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ diff --git a/components/bootloader/subproject/main/ld/esp32s3/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32s3/bootloader.sections.ld.in index be0e97427fa..f5a70c3cdd4 100644 --- a/components/bootloader/subproject/main/ld/esp32s3/bootloader.sections.ld.in +++ b/components/bootloader/subproject/main/ld/esp32s3/bootloader.sections.ld.in @@ -17,17 +17,18 @@ *libesp_common.a:fpga_overrides.*(.literal.bootloader_fill_random .text.bootloader_fill_random) \ *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha_flash.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ diff --git a/components/bootloader/subproject/main/ld/esp32s31/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32s31/bootloader.sections.ld.in index 330bf7c56ae..912ca71e9c3 100644 --- a/components/bootloader/subproject/main/ld/esp32s31/bootloader.sections.ld.in +++ b/components/bootloader/subproject/main/ld/esp32s31/bootloader.sections.ld.in @@ -17,17 +17,18 @@ *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) \ *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:bootloader_sha_flash.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libesp_image_verify.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ diff --git a/components/bootloader_support/CMakeLists.txt b/components/bootloader_support/CMakeLists.txt index 3338b065aed..a729ed05125 100644 --- a/components/bootloader_support/CMakeLists.txt +++ b/components/bootloader_support/CMakeLists.txt @@ -11,24 +11,24 @@ if(esp_tee_build) "bootloader_flash/include") set(tee_srcs "src/flash_partitions.c" - "src/bootloader_sha.c" "src/bootloader_common_loader.c" - "src/esp_image_format.c" "src/bootloader_utility.c" "src/bootloader_utility_tee.c" "bootloader_flash/src/bootloader_flash.c") if(CONFIG_SECURE_BOOT_V2_ENABLED) if(CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME OR CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) - list(APPEND tee_srcs "src/secure_boot_v2/secure_boot_signatures_bootloader.c" - "src/secure_boot_v2/secure_boot.c" - "src/${IDF_TARGET}/secure_boot_secure_features.c") + list(APPEND tee_srcs "src/${IDF_TARGET}/secure_boot_secure_features.c") endif() endif() + # The dependency cycle with esp_image_verify is deliberate. + # Without this edge the TEE link cannot resolve esp_image_verify() called + # from bootloader_utility_tee.c. idf_component_register(SRCS ${tee_srcs} INCLUDE_DIRS ${tee_inc_dirs} - PRIV_REQUIRES efuse esp_app_format esptool_py esp_hal_security) + PRIV_REQUIRES efuse esp_app_format esptool_py esp_hal_security + esp_image_verify) return() endif() @@ -60,11 +60,9 @@ if(CONFIG_APP_BUILD_TYPE_APP_2NDBOOT) list(APPEND srcs "src/bootloader_utility.c" "src/flash_partitions.c" - "src/esp_image_format.c" ) endif() -list(APPEND srcs "src/bootloader_sha.c") if(CONFIG_ESP_ROM_REV0_HAS_NO_ECDSA_INTERFACE) list(APPEND srcs "src/${IDF_TARGET}/bootloader_ecdsa.c") endif() @@ -78,7 +76,7 @@ if(BOOTLOADER_BUILD OR CONFIG_APP_BUILD_TYPE_RAM) # and micro-ecc lives in the bootloader subproject so it isn't available in app builds. set(priv_requires spi_flash efuse esp_bootloader_format esp_app_format esptool_py) if(BOOTLOADER_BUILD) - list(APPEND priv_requires micro-ecc) + list(APPEND priv_requires micro-ecc esp_image_verify) endif() # `esp_hal_ana_conv` is required by bootloader_random_esp32xx.c list(APPEND priv_requires esp_hal_wdt esp_hal_gpio esp_hal_uart esp_hal_ana_conv esp_hal_rtc_timer @@ -98,8 +96,9 @@ if(BOOTLOADER_BUILD OR CONFIG_APP_BUILD_TYPE_RAM) else() set(include_dirs "include" "bootloader_flash/include") set(priv_include_dirs "private_include") - # heap is required for `heap_memory_layout.h` header - set(priv_requires spi_flash mbedtls efuse heap esp_bootloader_format esp_app_format esptool_py) + # heap is required for `heap_memory_layout.h`. + set(priv_requires spi_flash efuse heap esp_bootloader_format esp_app_format + esptool_py) # `esp_hal_ana_conv` is required by bootloader_random_esp32xx.c list(APPEND priv_requires esp_hal_wdt esp_hal_gpio esp_hal_uart esp_hal_ana_conv esp_hal_rtc_timer esp_hal_clock esp_hal_security esp_hal_debug_assist) @@ -119,18 +118,12 @@ if(BOOTLOADER_BUILD) endif() if(CONFIG_SECURE_SIGNED_ON_BOOT) - if(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME) - list(APPEND srcs "src/secure_boot_v1/secure_boot_signatures_bootloader.c") - endif() if(CONFIG_SECURE_BOOT_V1_ENABLED) - list(APPEND srcs "src/secure_boot_v1/secure_boot.c" - "src/${IDF_TARGET}/secure_boot_secure_features.c") + list(APPEND srcs "src/${IDF_TARGET}/secure_boot_secure_features.c") endif() if(CONFIG_SECURE_BOOT_V2_ENABLED) - list(APPEND srcs "src/secure_boot_v2/secure_boot_signatures_bootloader.c" - "src/secure_boot_v2/secure_boot.c" - "src/${IDF_TARGET}/secure_boot_secure_features.c") + list(APPEND srcs "src/${IDF_TARGET}/secure_boot_secure_features.c") endif() endif() else() @@ -138,20 +131,6 @@ else() list(APPEND srcs "src/${IDF_TARGET}/secure_boot_secure_features.c") endif() - if(CONFIG_SECURE_SIGNED_ON_UPDATE) - if(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME) - list(APPEND srcs "src/secure_boot_v1/secure_boot_signatures_app.c") - endif() - - if(CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME) - list(APPEND srcs "src/secure_boot_v2/secure_boot_signatures_app.c") - list(APPEND srcs "src/secure_boot_v2/secure_boot_rsa_signature.c") - endif() - if(CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) - list(APPEND srcs "src/secure_boot_v2/secure_boot_signatures_app.c") - list(APPEND srcs "src/secure_boot_v2/secure_boot_ecdsa_signature.c") - endif() - endif() endif() set(requires soc) #unfortunately the header directly uses SOC registers @@ -162,17 +141,12 @@ idf_component_register(SRCS "${srcs}" REQUIRES "${requires}" PRIV_REQUIRES "${priv_requires}") -idf_define_esp_err_codes(HEADERS include/esp_image_format.h) - -if(NOT BOOTLOADER_BUILD) - if(CONFIG_SECURE_SIGNED_ON_UPDATE) - if(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME OR CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME OR - CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) - target_link_libraries(${COMPONENT_LIB} PRIVATE idf::app_update) - endif() - endif() +if(NOT BOOTLOADER_BUILD AND NOT esp_tee_build) + idf_component_optional_requires(PRIVATE esp_image_verify) endif() +idf_define_esp_err_codes(HEADERS include/esp_image_format.h) + if(CONFIG_SECURE_SIGNED_APPS AND (CONFIG_SECURE_BOOT_V1_ENABLED OR CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME)) idf_component_get_property(espsecure_py_cmd esptool_py ESPSECUREPY_CMD) if(BOOTLOADER_BUILD) @@ -243,3 +217,7 @@ endif() # Disable LTO for bootloader_support: it relies on linker script placements that # depend on object file names, which LTO does not preserve. idf_component_set_property(${COMPONENT_NAME} NO_LTO 1) + +if(NOT BOOTLOADER_BUILD AND NOT esp_tee_build AND CONFIG_BOOTLOADER_RESERVE_RTC_MEM) + target_link_libraries(${COMPONENT_LIB} INTERFACE "-u bootloader_common_get_rtc_retain_mem") +endif() diff --git a/components/bootloader_support/include/bootloader_common.h b/components/bootloader_support/include/bootloader_common.h index 40365f123b1..8940d33b8f2 100644 --- a/components/bootloader_support/include/bootloader_common.h +++ b/components/bootloader_support/include/bootloader_common.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -153,8 +153,13 @@ void bootloader_configure_spi_pins(int drv); * - ESP_ERR_NO_MEM: Cannot allocate memory for sha256 operation. * - ESP_ERR_IMAGE_INVALID: App partition doesn't contain a valid app image. * - ESP_FAIL: An allocation error occurred. + * + * @deprecated Use esp_partition_get_sha256() from the esp_partition component instead. + * Requires the esp_image_verify component in the build; otherwise + * calls fail at link time with an undefined reference. */ -esp_err_t bootloader_common_get_sha256_of_partition(uint32_t address, uint32_t size, int type, uint8_t *out_sha_256); +esp_err_t bootloader_common_get_sha256_of_partition(uint32_t address, uint32_t size, int type, uint8_t *out_sha_256) +__attribute__((deprecated("Use esp_partition_get_sha256() from the esp_partition component instead"))); /** * @brief Returns the number of active otadata. diff --git a/components/bootloader_support/include/bootloader_sha_flash.h b/components/bootloader_support/include/bootloader_sha_flash.h new file mode 100644 index 00000000000..3bdc6c242b9 --- /dev/null +++ b/components/bootloader_support/include/bootloader_sha_flash.h @@ -0,0 +1,48 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "esp_err.h" +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Generates the SHA-256 digest of flash contents between offset and offset+length. + * + * Reads in MMU-sized chunks, so it handles images larger than the MMU window + * (3.2 MB / 50 pages of 64 KB). + * + * @param[in] flash_offset Byte offset in flash. + * @param[in] len Length of data in bytes. + * @param[out] digest 32-byte buffer for the resulting SHA-256 digest. + * + * @return ESP_OK on success; ESP_ERR_NO_MEM if allocation fails. + * + * @note Defined in the esp_image_verify component; calling it in builds without + * that component fails at link time with an undefined reference. + */ +esp_err_t bootloader_sha256_flash_contents(uint32_t flash_offset, uint32_t len, uint8_t *digest); + +#if SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 +/** @brief Generates the SHA-384 digest of flash contents between offset and offset+length. + * + * @param[in] flash_offset Byte offset in flash. + * @param[in] len Length of data in bytes. + * @param[out] digest 48-byte buffer for the resulting SHA-384 digest. + * + * @return ESP_OK on success; ESP_ERR_NO_MEM if allocation fails. + * + * @note Defined in the esp_image_verify component; calling it in builds without + * that component fails at link time with an undefined reference. + */ +esp_err_t bootloader_sha384_flash_contents(uint32_t flash_offset, uint32_t len, uint8_t *digest); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/bootloader_support/include/esp_secure_boot.h b/components/bootloader_support/include/esp_secure_boot.h index 3994e2c523d..3e2a1ef28dd 100644 --- a/components/bootloader_support/include/esp_secure_boot.h +++ b/components/bootloader_support/include/esp_secure_boot.h @@ -312,6 +312,16 @@ typedef struct { */ void esp_secure_boot_init_checks(void); +/** + * @brief Run the on-update signature-block check for app-side secure boot. + * + * @important This function is invoked by esp_secure_boot_init_checks() during app + * startup when CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT is configured with + * V2 RSA or ECDSA schemes. It verifies that the running app's signature blocks + * are intact so future OTA updates can be verified. + */ +void esp_secure_boot_check_signature_on_update(void); + #if !BOOTLOADER_BUILD && (CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) /** @brief Scan the current running app for signature blocks diff --git a/components/bootloader_support/private_include/bootloader_utility.h b/components/bootloader_support/private_include/bootloader_utility.h index d8ed6464e5b..f669aa48df9 100644 --- a/components/bootloader_support/private_include/bootloader_utility.h +++ b/components/bootloader_support/private_include/bootloader_utility.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -89,69 +89,6 @@ __attribute__((__noreturn__)) void bootloader_reset(void); */ void bootloader_atexit(void); -/** - * @brief Converts an array to a printable string. - * - * This function is useful for printing SHA-256 digest. - * \code{c} - * // Example of using. image_hash will be printed - * #define HASH_LEN 32 // SHA-256 digest length - * ... - * char hash_print[HASH_LEN * 2 + 1]; - * hash_print[HASH_LEN * 2] = 0; - * bootloader_sha256_hex_to_str(hash_print, image_hash, HASH_LEN); - * ESP_LOGI(TAG, %s", hash_print); - * \endcode - - * @param[out] out_str Output string - * @param[in] in_array_hex Pointer to input array - * @param[in] len Length of input array - * - * @return ESP_OK: Successful - * ESP_ERR_INVALID_ARG: Error in the passed arguments - */ -esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_hex, size_t len); - -/** - * @brief Debug log contents of a buffer as hexadecimal. - * - * @note - Only works if component log level is DEBUG or higher. - * - It will print at most 128 bytes from @c buffer. - * - * @param buffer Buffer to log - * @param length Length of buffer in bytes. Maximum length 128 bytes. - * @param label Label to print at beginning of log line. - */ -void bootloader_debug_buffer(const void *buffer, size_t length, const char *label); - -/** @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); - -/** @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-384 - * 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_sha384_flash_contents(uint32_t flash_offset, uint32_t len, uint8_t *digest); - #ifdef __cplusplus } #endif diff --git a/components/bootloader_support/src/bootloader_common.c b/components/bootloader_support/src/bootloader_common.c index 2327cb78a26..0c40d39efa4 100644 --- a/components/bootloader_support/src/bootloader_common.c +++ b/components/bootloader_support/src/bootloader_common.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,15 +14,15 @@ #include "esp_rom_gpio.h" #include "esp_rom_sys.h" #include "esp_flash_partitions.h" +#include "esp_image_format.h" #include "bootloader_flash_priv.h" #include "bootloader_common.h" #include "bootloader_utility.h" +#include "bootloader_sha_flash.h" #include "soc/soc_caps.h" #include "soc/rtc.h" #include "soc/efuse_reg.h" #include "hal/gpio_ll.h" -#include "esp_image_format.h" -#include "bootloader_sha.h" #include "sys/param.h" #define ESP_PARTITION_HASH_LEN 32 /* SHA-256 digest length */ @@ -153,7 +153,8 @@ esp_err_t bootloader_common_get_sha256_of_partition(uint32_t address, uint32_t s .size = size, }; esp_image_metadata_t data; - if (esp_image_get_metadata(&partition_pos, &data) != ESP_OK) { + esp_err_t err = esp_image_get_metadata(&partition_pos, &data); + if (err != ESP_OK) { return ESP_ERR_IMAGE_INVALID; } if (data.image.hash_appended) { @@ -187,3 +188,31 @@ void bootloader_common_vddsdio_configure(void) } #endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST } + +// Lives here rather than in esp_image_format.c (esp_image_verify) because +// esp_system calls it during early init and must be able to resolve it via +// its existing bootloader_support dep, without dragging esp_image_verify +// (and mbedTLS) into the build graph for every app. +int esp_image_get_flash_size(esp_image_flash_size_t app_flash_size) +{ + switch (app_flash_size) { + case ESP_IMAGE_FLASH_SIZE_1MB: + return 1 * 1024 * 1024; + case ESP_IMAGE_FLASH_SIZE_2MB: + return 2 * 1024 * 1024; + case ESP_IMAGE_FLASH_SIZE_4MB: + return 4 * 1024 * 1024; + case ESP_IMAGE_FLASH_SIZE_8MB: + return 8 * 1024 * 1024; + case ESP_IMAGE_FLASH_SIZE_16MB: + return 16 * 1024 * 1024; + case ESP_IMAGE_FLASH_SIZE_32MB: + return 32 * 1024 * 1024; + case ESP_IMAGE_FLASH_SIZE_64MB: + return 64 * 1024 * 1024; + case ESP_IMAGE_FLASH_SIZE_128MB: + return 128 * 1024 * 1024; + default: + return 0; + } +} diff --git a/components/bootloader_support/src/bootloader_common_loader.c b/components/bootloader_support/src/bootloader_common_loader.c index 62b8cead3df..6716f4336f1 100644 --- a/components/bootloader_support/src/bootloader_common_loader.c +++ b/components/bootloader_support/src/bootloader_common_loader.c @@ -20,7 +20,6 @@ #include "soc/chip_revision.h" #include "hal/efuse_hal.h" #include "esp_image_format.h" -#include "bootloader_sha.h" #include "sys/param.h" #include "bootloader_flash_priv.h" #include "esp_rom_caps.h" diff --git a/components/bootloader_support/src/bootloader_utility.c b/components/bootloader_support/src/bootloader_utility.c index e8364b8a42b..ce1b579f6bd 100644 --- a/components/bootloader_support/src/bootloader_utility.c +++ b/components/bootloader_support/src/bootloader_utility.c @@ -43,7 +43,7 @@ #include "bootloader_config.h" #include "bootloader_common.h" #include "bootloader_utility.h" -#include "bootloader_sha.h" +#include "bootloader_util.h" #include "bootloader_console.h" #include "bootloader_soc.h" #include "bootloader_memory_utils.h" @@ -1174,138 +1174,3 @@ void bootloader_atexit(void) abort(); #endif } - -esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_hex, size_t len) -{ - if (out_str == NULL || in_array_hex == NULL || len == 0) { - return ESP_ERR_INVALID_ARG; - } - for (size_t i = 0; i < len; i++) { - for (int shift = 0; shift < 2; shift++) { - uint8_t nibble = (in_array_hex[i] >> (shift ? 0 : 4)) & 0x0F; - if (nibble < 10) { - out_str[i * 2 + shift] = '0' + nibble; - } else { - out_str[i * 2 + shift] = 'a' + nibble - 10; - } - } - } - return ESP_OK; -} - -void bootloader_debug_buffer(const void *buffer, size_t length, const char *label) -{ -#if CONFIG_BOOTLOADER_LOG_LEVEL >= 4 - const uint8_t *bytes = (const uint8_t *)buffer; - const size_t output_len = MIN(length, 128); - char hexbuf[128 * 2 + 1]; - - bootloader_sha256_hex_to_str(hexbuf, bytes, output_len); - - hexbuf[output_len * 2] = '\0'; - ESP_LOGD(TAG, "%s: %s", label, hexbuf); -#else - (void) buffer; - (void) length; - (void) label; -#endif -} - -static esp_err_t bootloader_sha_flash_contents(esp_sha_type type, 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_sha_handle_t sha_handle = NULL; - - if (type == SHA2_256) { - sha_handle = bootloader_sha256_start(); - } else - // Using SOC_ECDSA_SUPPORT_CURVE_P384 here so that there is no flash size impact in the case of existing targets like ESP32. -#if SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 - if (type == SHA2_384) { - sha_handle = bootloader_sha512_start(true); - } else -#endif /* SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 */ - { - return ESP_ERR_INVALID_ARG; - } - - 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 max_pages = (mmu_free_pages_count > mmu_page_offset) ? (mmu_free_pages_count - mmu_page_offset) : 0; - if (max_pages == 0) { - ESP_LOGE(TAG, "No free MMU pages are available"); - if (type == SHA2_256) { - bootloader_sha256_finish(sha_handle, NULL); - } -#if SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 - else if (type == SHA2_384) { - bootloader_sha512_finish(sha_handle, NULL); - } -#endif /* SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 */ - return ESP_ERR_NO_MEM; - } - uint32_t max_image_len; - if (__builtin_mul_overflow(max_pages, SPI_FLASH_MMU_PAGE_SIZE, &max_image_len)) { - max_image_len = UINT32_MAX; - } - uint32_t partial_image_len = MIN(len, max_image_len); /* Read the image that fits in the free MMU pages */ - - const void * image = bootloader_mmap(flash_offset, partial_image_len); - if (image == NULL) { - if (type == SHA2_256) { - bootloader_sha256_finish(sha_handle, NULL); - } -#if SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 - else if (type == SHA2_384) { - bootloader_sha512_finish(sha_handle, NULL); - } -#endif /* SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 */ - return ESP_FAIL; - } - - if (type == SHA2_256) { - bootloader_sha256_data(sha_handle, image, partial_image_len); - } -#if SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 - else if (type == SHA2_384) { - bootloader_sha512_data(sha_handle, image, partial_image_len); - } -#endif /* SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 */ - - bootloader_munmap(image); - - flash_offset += partial_image_len; - len -= partial_image_len; - } - - if (type == SHA2_256) { - bootloader_sha256_finish(sha_handle, digest); - } -#if SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 - else if (type == SHA2_384) { - bootloader_sha512_finish(sha_handle, digest); - } -#endif /* SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 */ - return ESP_OK; -} - -esp_err_t bootloader_sha256_flash_contents(uint32_t flash_offset, uint32_t len, uint8_t *digest) -{ - return bootloader_sha_flash_contents(SHA2_256, flash_offset, len, digest); -} - -#if SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 -esp_err_t bootloader_sha384_flash_contents(uint32_t flash_offset, uint32_t len, uint8_t *digest) -{ - return bootloader_sha_flash_contents(SHA2_384, flash_offset, len, digest); -} -#endif /* SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 */ diff --git a/components/bootloader_support/src/secure_boot.c b/components/bootloader_support/src/secure_boot.c index 70fefc63a7b..2e8076d69c3 100644 --- a/components/bootloader_support/src/secure_boot.c +++ b/components/bootloader_support/src/secure_boot.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -148,28 +148,6 @@ static esp_err_t secure_boot_v2_check(bool *need_fix) #endif #endif // CONFIG_SECURE_BOOT -#if (CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT - -static void check_signature_on_update_check(void) -{ - // We rely on the keys used to sign this app to verify the next app on OTA, so make sure there is at - // least one to avoid a stuck firmware - esp_image_sig_public_key_digests_t digests = { 0 }; - - esp_err_t err = esp_secure_boot_get_signature_blocks_for_running_app(false, &digests); - - if (err != ESP_OK || digests.num_digests == 0) { - ESP_LOGE(TAG, "This app is not signed, but check signature on update is enabled in config. It won't be possible to verify any update."); - abort(); - } -#if CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT && SECURE_BOOT_NUM_BLOCKS > 1 - if (digests.num_digests > 1) { - ESP_LOGW(TAG, "App has %d signatures. Only the first position of signature blocks is used to verify any update", digests.num_digests); - } -#endif -} -#endif // (CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT - void esp_secure_boot_init_checks(void) { #ifdef CONFIG_SECURE_BOOT @@ -189,7 +167,7 @@ void esp_secure_boot_init_checks(void) #if (CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT - check_signature_on_update_check(); + esp_secure_boot_check_signature_on_update(); #endif // (CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT } diff --git a/components/esp_image_verify/CMakeLists.txt b/components/esp_image_verify/CMakeLists.txt new file mode 100644 index 00000000000..9d3ddadb52a --- /dev/null +++ b/components/esp_image_verify/CMakeLists.txt @@ -0,0 +1,80 @@ +idf_build_get_property(target IDF_TARGET) +idf_build_get_property(esp_tee_build ESP_TEE_BUILD) + +if(${target} STREQUAL "linux") + return() +endif() + +set(srcs + "src/esp_image_format.c" + "src/bootloader_sha.c" + "src/bootloader_sha_flash.c" +) + +# Secure Boot V1 + V2 sources. Bootloader build picks up the on-boot verifier; app +# build picks up the on-update verifier. ESP-TEE app builds compile V2 (RSA / ECDSA-V2) +# but skip V1 entirely (V1 hardware is ESP32 / ESP32-S2). +if(BOOTLOADER_BUILD) + if(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME) + list(APPEND srcs "src/secure_boot_v1/secure_boot_signatures_bootloader.c") + endif() + if(CONFIG_SECURE_BOOT_V1_ENABLED) + list(APPEND srcs "src/secure_boot_v1/secure_boot.c") + endif() + if(CONFIG_SECURE_BOOT_V2_ENABLED) + list(APPEND srcs "src/secure_boot_v2/secure_boot_signatures_bootloader.c" + "src/secure_boot_v2/secure_boot.c") + endif() +elseif(esp_tee_build) + if(CONFIG_SECURE_BOOT_V2_ENABLED) + if(CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME OR CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) + list(APPEND srcs "src/secure_boot_v2/secure_boot_signatures_bootloader.c" + "src/secure_boot_v2/secure_boot.c") + endif() + endif() +else() + if(CONFIG_SECURE_SIGNED_ON_UPDATE) + if(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME) + list(APPEND srcs "src/secure_boot_v1/secure_boot_signatures_app.c") + endif() + if(CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME) + list(APPEND srcs "src/secure_boot_v2/secure_boot_signatures_app.c" + "src/secure_boot_v2/secure_boot_rsa_signature.c") + endif() + if(CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) + list(APPEND srcs "src/secure_boot_v2/secure_boot_signatures_app.c" + "src/secure_boot_v2/secure_boot_ecdsa_signature.c") + endif() + endif() + # secure_boot.c — app-side on-update signature-block sanity check + list(APPEND srcs "src/secure_boot.c") +endif() + +# Public REQUIRES bootloader_support — esp_image_format.h includes esp_flash_partitions.h +# from bootloader_support's public include path. +set(requires bootloader_support esp_app_format esp_bootloader_format) + +set(priv_requires spi_flash efuse esp_hal_security) + +if(BOOTLOADER_BUILD) + list(APPEND priv_requires micro-ecc) +elseif(NOT esp_tee_build) + # heap is needed by the SHA primitive (PSA hash op allocations). + list(APPEND priv_requires heap mbedtls app_update) +endif() + +idf_component_register( + SRCS "${srcs}" + PRIV_INCLUDE_DIRS "private_include" + REQUIRES "${requires}" + PRIV_REQUIRES "${priv_requires}" +) + +if(NOT BOOTLOADER_BUILD AND NOT esp_tee_build) + if(CONFIG_SECURE_SIGNED_ON_UPDATE) + if(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME OR CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME OR + CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) + target_link_libraries(${COMPONENT_LIB} PRIVATE idf::app_update) + endif() + endif() +endif() diff --git a/components/bootloader_support/private_include/bootloader_sha.h b/components/esp_image_verify/private_include/bootloader_sha.h similarity index 87% rename from components/bootloader_support/private_include/bootloader_sha.h rename to components/esp_image_verify/private_include/bootloader_sha.h index 661aa8028ee..4f546e2caa6 100644 --- a/components/bootloader_support/private_include/bootloader_sha.h +++ b/components/esp_image_verify/private_include/bootloader_sha.h @@ -5,10 +5,8 @@ */ #pragma once -/* Provide a SHA256 API for bootloader_support code, +/* Provide a SHA256 API for image-verification code, that can be used from bootloader or app code. - - This header is available to source code in the bootloader & bootloader_support components only. Use PSA APIs or include esp32/sha.h to calculate SHA256 in IDF apps. */ diff --git a/components/bootloader_support/private_include/bootloader_signature.h b/components/esp_image_verify/private_include/bootloader_signature.h similarity index 100% rename from components/bootloader_support/private_include/bootloader_signature.h rename to components/esp_image_verify/private_include/bootloader_signature.h diff --git a/components/bootloader_support/src/bootloader_sha.c b/components/esp_image_verify/src/bootloader_sha.c similarity index 97% rename from components/bootloader_support/src/bootloader_sha.c rename to components/esp_image_verify/src/bootloader_sha.c index 37af59a7893..037062228c7 100644 --- a/components/bootloader_support/src/bootloader_sha.c +++ b/components/esp_image_verify/src/bootloader_sha.c @@ -104,7 +104,7 @@ void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data, for (size_t i = 0; i < copy_words; i++) { sha_text_reg[block_count + i] = __builtin_bswap32(w[i]); } - asm volatile ("memw"); + asm volatile("memw"); // Update counters words_hashed += copy_words; @@ -152,7 +152,7 @@ void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest assert(words_hashed % BLOCK_WORDS == 60 / 4); // 32-bits left in block // Calculate 32-bit length for final 32 bits of data - uint32_t bit_count = __builtin_bswap32( data_words * 32 ); + uint32_t bit_count = __builtin_bswap32(data_words * 32); bootloader_sha256_data(handle, &bit_count, sizeof(bit_count)); assert(words_hashed % BLOCK_WORDS == 0); @@ -166,12 +166,12 @@ void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest for (size_t i = 0; i < DIGEST_WORDS; i++) { digest_words[i] = __builtin_bswap32(sha_text_reg[i]); } - asm volatile ("memw"); + asm volatile("memw"); } #endif /* CONFIG_IDF_TARGET_ESP32 */ #else /* NON_OS_BUILD || CONFIG_APP_BUILD_TYPE_RAM */ -#include "bootloader_flash_priv.h" +/* App-side SHA implementation backed by PSA/mbedtls. */ #include "psa/crypto.h" bootloader_sha256_handle_t bootloader_sha256_start(void) @@ -218,14 +218,13 @@ void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest } free(handle); - handle = NULL; } #if SOC_SHA_SUPPORT_SHA512 typedef struct { psa_hash_operation_t *hash_op; - int psa_alg; + psa_algorithm_t psa_alg; } bootloader_psa_sha_handle_t; bootloader_sha_handle_t bootloader_sha512_start(bool is384) @@ -283,7 +282,6 @@ void bootloader_sha512_finish(bootloader_sha_handle_t handle, uint8_t *digest) free(op->hash_op); free(op); - handle = NULL; } #endif /* SOC_SHA_SUPPORT_SHA512 */ #endif /* !(NON_OS_BUILD || CONFIG_APP_BUILD_TYPE_RAM) */ diff --git a/components/esp_image_verify/src/bootloader_sha_flash.c b/components/esp_image_verify/src/bootloader_sha_flash.c new file mode 100644 index 00000000000..f515e018919 --- /dev/null +++ b/components/esp_image_verify/src/bootloader_sha_flash.c @@ -0,0 +1,114 @@ +/* + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "esp_log.h" +#include "bootloader_flash_priv.h" +#include "bootloader_sha.h" +#include "bootloader_sha_flash.h" +#include "spi_flash_mmap.h" +#include "soc/soc_caps.h" +#include "hal/sha_types.h" +#include "rom/sha.h" + +ESP_LOG_ATTR_TAG(TAG, "boot_sha"); + +static esp_err_t bootloader_sha_flash_contents(esp_sha_type type, 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_sha_handle_t sha_handle = NULL; + + if (type == SHA2_256) { + sha_handle = bootloader_sha256_start(); + } else +#if SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 + if (type == SHA2_384) { + sha_handle = bootloader_sha512_start(true); + } else +#endif /* SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 */ + { + return ESP_ERR_INVALID_ARG; + } + + 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 max_pages = (mmu_free_pages_count > mmu_page_offset) ? (mmu_free_pages_count - mmu_page_offset) : 0; + if (max_pages == 0) { + ESP_LOGE(TAG, "No free MMU pages are available"); + if (type == SHA2_256) { + bootloader_sha256_finish(sha_handle, NULL); + } +#if SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 + else if (type == SHA2_384) { + bootloader_sha512_finish(sha_handle, NULL); + } +#endif /* SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 */ + return ESP_ERR_NO_MEM; + } + uint32_t max_image_len; + if (__builtin_mul_overflow(max_pages, SPI_FLASH_MMU_PAGE_SIZE, &max_image_len)) { + max_image_len = UINT32_MAX; + } + uint32_t partial_image_len = MIN(len, max_image_len); /* Read the image that fits in the free MMU pages */ + + const void * image = bootloader_mmap(flash_offset, partial_image_len); + if (image == NULL) { + if (type == SHA2_256) { + bootloader_sha256_finish(sha_handle, NULL); + } +#if SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 + else if (type == SHA2_384) { + bootloader_sha512_finish(sha_handle, NULL); + } +#endif /* SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 */ + return ESP_FAIL; + } + + if (type == SHA2_256) { + bootloader_sha256_data(sha_handle, image, partial_image_len); + } +#if SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 + else if (type == SHA2_384) { + bootloader_sha512_data(sha_handle, image, partial_image_len); + } +#endif /* SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 */ + + bootloader_munmap(image); + + flash_offset += partial_image_len; + len -= partial_image_len; + } + + if (type == SHA2_256) { + bootloader_sha256_finish(sha_handle, digest); + } +#if SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 + else if (type == SHA2_384) { + bootloader_sha512_finish(sha_handle, digest); + } +#endif /* SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 */ + return ESP_OK; +} + +esp_err_t bootloader_sha256_flash_contents(uint32_t flash_offset, uint32_t len, uint8_t *digest) +{ + return bootloader_sha_flash_contents(SHA2_256, flash_offset, len, digest); +} + +#if SOC_SHA_SUPPORT_SHA384 && SOC_ECDSA_SUPPORT_CURVE_P384 +esp_err_t bootloader_sha384_flash_contents(uint32_t flash_offset, uint32_t len, uint8_t *digest) +{ + return bootloader_sha_flash_contents(SHA2_384, flash_offset, len, digest); +} +#endif diff --git a/components/bootloader_support/src/esp_image_format.c b/components/esp_image_verify/src/esp_image_format.c similarity index 95% rename from components/bootloader_support/src/esp_image_format.c rename to components/esp_image_verify/src/esp_image_format.c index 797eae4d544..4ef6f9d931f 100644 --- a/components/bootloader_support/src/esp_image_format.c +++ b/components/esp_image_verify/src/esp_image_format.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -147,11 +146,11 @@ void esp_image_bootloader_offset_set(const uint32_t offset) static bool is_bootloader(uint32_t offset) { return ((offset == ESP_PRIMARY_BOOTLOADER_OFFSET) - || (offset == s_bootloader_partition_offset) + || (offset == s_bootloader_partition_offset) #if SOC_RECOVERY_BOOTLOADER_SUPPORTED - || (efuse_hal_recovery_bootloader_enabled() ? offset == efuse_hal_get_recovery_bootloader_address() : false) + || (efuse_hal_recovery_bootloader_enabled() ? offset == efuse_hal_get_recovery_bootloader_address() : false) #endif - ); + ); } #if BOOTLOADER_BUILD && (SECURE_BOOT_CHECK_SIGNATURE == 1) @@ -187,7 +186,7 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_ bootloader_sha256_handle_t sha_handle = NULL; bool verify_sha; #if (SECURE_BOOT_CHECK_SIGNATURE == 1) - /* used for anti-FI checks */ + /* used for anti-FI checks */ uint8_t image_digest[ESP_SECURE_BOOT_DIGEST_LEN] = { [ 0 ... ESP_SECURE_BOOT_DIGEST_LEN - 1 ] = 0xEE }; uint8_t verified_digest[ESP_SECURE_BOOT_DIGEST_LEN] = { [ 0 ... ESP_SECURE_BOOT_DIGEST_LEN - 1 ] = 0x01 }; #endif @@ -336,15 +335,15 @@ esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metad #elif CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON #if SOC_EFUSE_HAS_EFUSE_RST_BUG - || esp_rom_get_reset_reason(0) == RESET_REASON_CORE_EFUSE_CRC + || esp_rom_get_reset_reason(0) == RESET_REASON_CORE_EFUSE_CRC #endif - ) { + ) { mode = ESP_IMAGE_LOAD_NO_VALIDATE; } #endif // CONFIG_BOOTLOADER_SKIP_... #endif // CONFIG_SECURE_BOOT - return image_load(mode, part, data); + return image_load(mode, part, data); #endif // BOOTLOADER_BUILD } @@ -387,11 +386,11 @@ static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t esp_err_t err = ESP_OK; ESP_LOGD(TAG, "image header: 0x%02x 0x%02x 0x%02x 0x%02x %08"PRIx32, - image->magic, - image->segment_count, - image->spi_mode, - image->spi_size, - image->entry_addr); + image->magic, + image->segment_count, + image->spi_mode, + image->spi_size, + image->entry_addr); if (image->magic != ESP_IMAGE_HEADER_MAGIC) { FAIL_LOAD("image at 0x%"PRIx32" has invalid magic byte (nothing flashed here?)", src_addr); @@ -442,7 +441,7 @@ static bool verify_load_addresses(int segment_index, intptr_t load_addr, intptr_ /* Check if we're clobbering the stack */ intptr_t sp = (intptr_t)esp_cpu_get_sp(); if (bootloader_util_regions_overlap(sp - STACK_LOAD_HEADROOM, ROM_STACK_START, - load_addr, load_end)) { + load_addr, load_end)) { reason = ESP_LOG_ATTR_STR("overlaps bootloader stack"); goto invalid; } @@ -485,8 +484,7 @@ static bool verify_load_addresses(int segment_index, intptr_t load_addr, intptr_ return verify_load_addresses(segment_index, iram_load_addr, iram_load_end, print_error, true); } } - } - else if (esp_ptr_in_iram(load_addr_p) && esp_ptr_in_iram(load_inclusive_end_p)) { /* Writing to IRAM */ + } else if (esp_ptr_in_iram(load_addr_p) && esp_ptr_in_iram(load_inclusive_end_p)) { /* Writing to IRAM */ /* Check for overlap of 'loader' section of IRAM */ if (bootloader_util_regions_overlap((intptr_t)&_loader_text_start, (intptr_t)&_loader_text_end, load_addr, load_end)) { @@ -522,12 +520,12 @@ static bool verify_load_addresses(int segment_index, intptr_t load_addr, intptr_ return verify_load_addresses(segment_index, dram_load_addr, dram_load_end, print_error, true); } } - /* Sections entirely in RTC memory won't overlap with a vanilla bootloader but are valid load addresses, thus skipping them from the check */ + /* Sections entirely in RTC memory won't overlap with a vanilla bootloader but are valid load addresses, thus skipping them from the check */ } #if SOC_RTC_FAST_MEM_SUPPORTED - else if (esp_ptr_in_rtc_iram_fast(load_addr_p) && esp_ptr_in_rtc_iram_fast(load_inclusive_end_p)){ + else if (esp_ptr_in_rtc_iram_fast(load_addr_p) && esp_ptr_in_rtc_iram_fast(load_inclusive_end_p)) { return true; - } else if (esp_ptr_in_rtc_dram_fast(load_addr_p) && esp_ptr_in_rtc_dram_fast(load_inclusive_end_p)){ + } else if (esp_ptr_in_rtc_dram_fast(load_addr_p) && esp_ptr_in_rtc_dram_fast(load_inclusive_end_p)) { return true; } #endif @@ -550,7 +548,7 @@ static bool verify_load_addresses(int segment_index, intptr_t load_addr, intptr_ } return true; - invalid: +invalid: if (print_error) { ESP_LOGE(TAG, "Segment %d 0x%08x-0x%08x invalid: %s", segment_index, load_addr, load_end, reason); } @@ -653,7 +651,6 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme (do_load) ? ESP_LOG_ATTR_STR("load") : (is_mapping) ? ESP_LOG_ATTR_STR("map") : ""); } - #ifdef BOOTLOADER_BUILD /* Before loading segment, check it doesn't clobber bootloader RAM. */ if (do_load && data_len > 0) { @@ -681,7 +678,7 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme #if (SECURE_BOOT_CHECK_SIGNATURE == 1) && defined(BOOTLOADER_BUILD) /* Double check the address verification done above */ ESP_FAULT_ASSERT(!do_load || verify_load_addresses(0, segment_data.load_addr, - segment_data.load_addr + data_len_remain, false, false)); + segment_data.load_addr + data_len_remain, false, false)); #endif uint32_t offset_page = ((segment_data.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. */ @@ -799,11 +796,11 @@ static esp_err_t process_segment_data(const process_segment_data_t *segment_data // Anti-rollback check and efuse block version check should handle only Case I from above. if (segment_data->segment == 0 && segment_data->is_segment_start && !is_bootloader(segment_data->metadata->start_addr)) { -/* ESP32 doesn't have more memory and more efuse bits for block major version. */ + /* ESP32 doesn't have more memory and more efuse bits for block major version. */ #if !CONFIG_IDF_TARGET_ESP32 const esp_app_desc_t *app_desc = (const esp_app_desc_t *)src; esp_err_t ret = bootloader_common_check_efuse_blk_validity(app_desc->min_efuse_blk_rev_full, - app_desc->max_efuse_blk_rev_full); + app_desc->max_efuse_blk_rev_full); if (ret != ESP_OK) { bootloader_munmap(data); return ret; @@ -1042,7 +1039,7 @@ static esp_err_t process_appended_hash_and_sig(esp_image_metadata_t *data, uint3 sig_block_len += sizeof(ets_secure_boot_signature_t); #endif } else { - // Case II: Application part + // Case II: Application part #if CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME sig_block_len = sizeof(esp_secure_boot_sig_block_t); #else @@ -1147,6 +1144,44 @@ static esp_err_t verify_signature_and_adjust_image_len(esp_image_metadata_t *dat } #endif /* SECURE_BOOT_CHECK_SIGNATURE */ +#if CONFIG_BOOTLOADER_LOG_LEVEL >= 4 +static esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_hex, size_t len) +{ + if (out_str == NULL || in_array_hex == NULL || len == 0) { + return ESP_ERR_INVALID_ARG; + } + for (size_t i = 0; i < len; i++) { + for (int shift = 0; shift < 2; shift++) { + uint8_t nibble = (in_array_hex[i] >> (shift ? 0 : 4)) & 0x0F; + if (nibble < 10) { + out_str[i * 2 + shift] = '0' + nibble; + } else { + out_str[i * 2 + shift] = 'a' + nibble - 10; + } + } + } + return ESP_OK; +} +#endif + +static void bootloader_debug_buffer(const void *buffer, size_t length, const char *label) +{ +#if CONFIG_BOOTLOADER_LOG_LEVEL >= 4 + const uint8_t *bytes = (const uint8_t *)buffer; + const size_t output_len = MIN(length, 128); + char hexbuf[128 * 2 + 1]; + + bootloader_sha256_hex_to_str(hexbuf, bytes, output_len); + + hexbuf[output_len * 2] = '\0'; + ESP_LOGD(TAG, "%s: %s", label, hexbuf); +#else + (void) buffer; + (void) length; + (void) label; +#endif +} + static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data, uint8_t *image_digest, uint8_t *verified_digest) { #if (SECURE_BOOT_CHECK_SIGNATURE == 1) @@ -1226,27 +1261,3 @@ static esp_err_t verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_i return ESP_OK; } - -int esp_image_get_flash_size(esp_image_flash_size_t app_flash_size) -{ - switch (app_flash_size) { - case ESP_IMAGE_FLASH_SIZE_1MB: - return 1 * 1024 * 1024; - case ESP_IMAGE_FLASH_SIZE_2MB: - return 2 * 1024 * 1024; - case ESP_IMAGE_FLASH_SIZE_4MB: - return 4 * 1024 * 1024; - case ESP_IMAGE_FLASH_SIZE_8MB: - return 8 * 1024 * 1024; - case ESP_IMAGE_FLASH_SIZE_16MB: - return 16 * 1024 * 1024; - case ESP_IMAGE_FLASH_SIZE_32MB: - return 32 * 1024 * 1024; - case ESP_IMAGE_FLASH_SIZE_64MB: - return 64 * 1024 * 1024; - case ESP_IMAGE_FLASH_SIZE_128MB: - return 128 * 1024 * 1024; - default: - return 0; - } -} diff --git a/components/esp_image_verify/src/secure_boot.c b/components/esp_image_verify/src/secure_boot.c new file mode 100644 index 00000000000..ab0cb87480f --- /dev/null +++ b/components/esp_image_verify/src/secure_boot.c @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include "esp_log.h" +#include "esp_secure_boot.h" + +ESP_LOG_ATTR_TAG(TAG, "secure_boot"); + +#if (CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT + +void esp_secure_boot_check_signature_on_update(void) +{ + /* We rely on the keys used to sign this app to verify the next app on OTA, so make sure + there is at least one to avoid a stuck firmware. */ + esp_image_sig_public_key_digests_t digests = { 0 }; + esp_err_t err = esp_secure_boot_get_signature_blocks_for_running_app(false, &digests); + + if (err != ESP_OK || digests.num_digests == 0) { + ESP_LOGE(TAG, "This app is not signed, but check signature on update is enabled in config. It won't be possible to verify any update."); + abort(); + } +#if SECURE_BOOT_NUM_BLOCKS > 1 + if (digests.num_digests > 1) { + ESP_LOGW(TAG, "App has %d signatures. Only the first position of signature blocks is used to verify any update", digests.num_digests); + } +#endif +} + +#endif /* (CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT */ diff --git a/components/bootloader_support/src/secure_boot_v1/secure_boot.c b/components/esp_image_verify/src/secure_boot_v1/secure_boot.c similarity index 91% rename from components/bootloader_support/src/secure_boot_v1/secure_boot.c rename to components/esp_image_verify/src/secure_boot_v1/secure_boot.c index 3297c93f267..a509df859ee 100644 --- a/components/bootloader_support/src/secure_boot_v1/secure_boot.c +++ b/components/esp_image_verify/src/secure_boot_v1/secure_boot.c @@ -14,7 +14,6 @@ #include "esp32/rom/secure_boot.h" #include "soc/rtc_periph.h" -#include "bootloader_utility.h" #include "sdkconfig.h" @@ -37,7 +36,8 @@ ESP_LOG_ATTR_TAG(TAG, "secure_boot_v1"); * * @inputs: image_len - length of image to calculate digest for */ -static bool secure_boot_generate(uint32_t image_len){ +static bool secure_boot_generate(uint32_t image_len) +{ esp_err_t err; esp_secure_boot_iv_digest_t digest; const uint32_t *image; @@ -53,8 +53,7 @@ static bool secure_boot_generate(uint32_t image_len){ ets_secure_boot_hash(NULL); /* iv stored in sec 0 */ err = bootloader_flash_erase_sector(0); - if (err != ESP_OK) - { + if (err != ESP_OK) { ESP_LOGE(TAG, "SPI erase failed: 0x%x", err); return false; } @@ -65,8 +64,8 @@ static bool secure_boot_generate(uint32_t image_len){ ESP_LOGE(TAG, "bootloader_mmap(0x1000, 0x%" PRIx32 ") failed", image_len); return false; } - for (size_t i = 0; i < image_len; i+= sizeof(digest.iv)) { - ets_secure_boot_hash(&image[i/sizeof(uint32_t)]); + for (size_t i = 0; i < image_len; i += sizeof(digest.iv)) { + ets_secure_boot_hash(&image[i / sizeof(uint32_t)]); } bootloader_munmap(image); @@ -76,7 +75,7 @@ static bool secure_boot_generate(uint32_t image_len){ ESP_LOGD(TAG, "write iv+digest to flash"); err = bootloader_flash_write(FLASH_OFFS_SECURE_BOOT_IV_DIGEST, &digest, - sizeof(digest), esp_efuse_is_flash_encryption_enabled()); + sizeof(digest), esp_efuse_is_flash_encryption_enabled()); if (err != ESP_OK) { ESP_LOGE(TAG, "SPI write failed: 0x%x", err); return false; @@ -90,7 +89,7 @@ esp_err_t esp_secure_boot_generate_digest(void) esp_err_t err; if (esp_secure_boot_enabled()) { ESP_LOGI(TAG, "bootloader secure boot is already enabled." - " No need to generate digest. continuing.."); + " No need to generate digest. continuing.."); return ESP_OK; } #if CONFIG_SECURE_BOOT_REQUIRE_ALREADY_ENABLED @@ -135,11 +134,11 @@ esp_err_t esp_secure_boot_generate_digest(void) /* Generate secure boot digest using programmed key in EFUSE */ ESP_LOGI(TAG, "Generating secure boot digest..."); uint32_t image_len = bootloader_data.image_len; - if(bootloader_data.image.hash_appended) { + if (bootloader_data.image.hash_appended) { /* Secure boot digest doesn't cover the hash */ image_len -= ESP_IMAGE_HASH_LEN; } - if (false == secure_boot_generate(image_len)){ + if (false == secure_boot_generate(image_len)) { ESP_LOGE(TAG, "secure boot generation failed"); return ESP_FAIL; } @@ -165,8 +164,8 @@ esp_err_t esp_secure_boot_permanently_enable(void) bool dis_write = esp_efuse_read_field_bit(ESP_EFUSE_WR_DIS_BLK2); if (dis_read != dis_write) { ESP_LOGE(TAG, "Pre-loaded key is not %s %s protected. Refusing to blow secure boot efuse.", - (!dis_read) ? "read,":" ", - (!dis_read) ? "write":" "); + (!dis_read) ? "read," : " ", + (!dis_read) ? "write" : " "); return ESP_ERR_INVALID_STATE; } esp_efuse_batch_write_begin(); /* Batch all efuse writes at the end of this function */ diff --git a/components/bootloader_support/src/secure_boot_v1/secure_boot_signatures_app.c b/components/esp_image_verify/src/secure_boot_v1/secure_boot_signatures_app.c similarity index 99% rename from components/bootloader_support/src/secure_boot_v1/secure_boot_signatures_app.c rename to components/esp_image_verify/src/secure_boot_v1/secure_boot_signatures_app.c index 92be1b5a52a..8f713c88bd5 100644 --- a/components/bootloader_support/src/secure_boot_v1/secure_boot_signatures_app.c +++ b/components/esp_image_verify/src/secure_boot_v1/secure_boot_signatures_app.c @@ -7,7 +7,7 @@ #include "bootloader_flash_priv.h" #include "bootloader_sha.h" -#include "bootloader_utility.h" +#include "bootloader_sha_flash.h" #include "esp_log.h" #include "esp_image_format.h" #include "esp_secure_boot.h" @@ -16,7 +16,6 @@ #include #include "mbedtls/pk.h" - #ifdef CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME ESP_LOG_ATTR_TAG(TAG, "secure_boot_v1"); diff --git a/components/bootloader_support/src/secure_boot_v1/secure_boot_signatures_bootloader.c b/components/esp_image_verify/src/secure_boot_v1/secure_boot_signatures_bootloader.c similarity index 88% rename from components/bootloader_support/src/secure_boot_v1/secure_boot_signatures_bootloader.c rename to components/esp_image_verify/src/secure_boot_v1/secure_boot_signatures_bootloader.c index 3d3ad04fc9b..3c9f2a42abf 100644 --- a/components/bootloader_support/src/secure_boot_v1/secure_boot_signatures_bootloader.c +++ b/components/esp_image_verify/src/secure_boot_v1/secure_boot_signatures_bootloader.c @@ -7,7 +7,7 @@ #include "bootloader_flash_priv.h" #include "bootloader_sha.h" -#include "bootloader_utility.h" +#include "bootloader_sha_flash.h" #include "esp_log.h" #include "esp_image_format.h" #include "esp_secure_boot.h" @@ -41,7 +41,7 @@ esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t 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) { + if (!sigblock) { ESP_LOGE(TAG, "bootloader_mmap(0x%" PRIx32 ", 0x%x) failed", src_addr + length, sizeof(esp_secure_boot_sig_block_t)); return ESP_FAIL; } @@ -53,7 +53,6 @@ esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length) return err; } - esp_err_t esp_secure_boot_verify_ecdsa_signature_block(const esp_secure_boot_sig_block_t *sig_block, const uint8_t *image_digest, uint8_t *verified_digest) { ptrdiff_t keylen; @@ -73,11 +72,11 @@ esp_err_t esp_secure_boot_verify_ecdsa_signature_block(const esp_secure_boot_sig bool is_valid; is_valid = uECC_verify_antifault(signature_verification_key_start, - image_digest, - ESP_SECURE_BOOT_DIGEST_LEN, - sig_block->signature, - uECC_secp256r1(), - verified_digest); + image_digest, + ESP_SECURE_BOOT_DIGEST_LEN, + sig_block->signature, + uECC_secp256r1(), + verified_digest); ESP_LOGD(TAG, "Verification result %d", is_valid); return is_valid ? ESP_OK : ESP_ERR_IMAGE_INVALID; diff --git a/components/bootloader_support/src/secure_boot_v2/secure_boot.c b/components/esp_image_verify/src/secure_boot_v2/secure_boot.c similarity index 97% rename from components/bootloader_support/src/secure_boot_v2/secure_boot.c rename to components/esp_image_verify/src/secure_boot_v2/secure_boot.c index 111991477a9..b585ddecaff 100644 --- a/components/bootloader_support/src/secure_boot_v2/secure_boot.c +++ b/components/esp_image_verify/src/secure_boot_v2/secure_boot.c @@ -10,14 +10,13 @@ #include "esp_secure_boot.h" #include "bootloader_flash_priv.h" #include "bootloader_sha.h" -#include "bootloader_utility.h" +#include "bootloader_sha_flash.h" #include "esp_image_format.h" #include "esp_efuse.h" #include "esp_efuse_table.h" #include "secure_boot_signature_priv.h" #include "esp_macros.h" - /* The following API implementations are used only when called * from the bootloader code. */ @@ -177,7 +176,7 @@ static esp_err_t check_and_generate_secure_boot_keys(const esp_image_metadata_t } /* Initialize all efuse block entries to invalid (max) value */ - esp_efuse_block_t blocks[SECURE_BOOT_NUM_BLOCKS] = {[0 ... SECURE_BOOT_NUM_BLOCKS-1] = EFUSE_BLK_KEY_MAX}; + esp_efuse_block_t blocks[SECURE_BOOT_NUM_BLOCKS] = {[0 ... SECURE_BOOT_NUM_BLOCKS - 1] = EFUSE_BLK_KEY_MAX}; /* Check if secure boot digests are present */ bool has_secure_boot_digest = false; for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) { @@ -190,7 +189,7 @@ static esp_err_t check_and_generate_secure_boot_keys(const esp_image_metadata_t esp_image_sig_public_key_digests_t boot_key_digests = {0}; esp_image_sig_public_key_digests_t app_key_digests = {0}; - ESP_LOGI(TAG, "Secure boot digests %s", has_secure_boot_digest ? "already present":"absent, generating.."); + ESP_LOGI(TAG, "Secure boot digests %s", has_secure_boot_digest ? "already present" : "absent, generating.."); if (!has_secure_boot_digest) { /* Generate the bootloader public key digests */ @@ -245,8 +244,8 @@ static esp_err_t check_and_generate_secure_boot_keys(const esp_image_metadata_t #else size_t offset = 0; #endif - ret = esp_efuse_read_block(blocks[i], boot_key_digests.key_digests[boot_key_digests.num_digests], offset, - ESP_SECURE_BOOT_KEY_DIGEST_LEN * 8); + ret = esp_efuse_read_block(blocks[i], boot_key_digests.key_digests[boot_key_digests.num_digests], offset, + ESP_SECURE_BOOT_KEY_DIGEST_LEN * 8); if (ret) { ESP_LOGE(TAG, "Error during reading %d eFuse block (err=0x%x)", blocks[i], ret); return ret; @@ -318,7 +317,7 @@ static esp_err_t check_and_generate_secure_boot_keys(const esp_image_metadata_t } #if CONFIG_SECURE_ENABLE_TEE if (!match) { - continue; + continue; } for (unsigned j = 0; j < tee_key_digests.num_digests; j++) { diff --git a/components/bootloader_support/src/secure_boot_v2/secure_boot_ecdsa_signature.c b/components/esp_image_verify/src/secure_boot_v2/secure_boot_ecdsa_signature.c similarity index 85% rename from components/bootloader_support/src/secure_boot_v2/secure_boot_ecdsa_signature.c rename to components/esp_image_verify/src/secure_boot_v2/secure_boot_ecdsa_signature.c index 41eef7459c5..ed1f0fe4300 100644 --- a/components/bootloader_support/src/secure_boot_v2/secure_boot_ecdsa_signature.c +++ b/components/esp_image_verify/src/secure_boot_v2/secure_boot_ecdsa_signature.c @@ -38,24 +38,24 @@ esp_err_t verify_ecdsa_signature_block(const ets_secure_boot_signature_t *sig_bl uint8_t key_size = 0; psa_ecc_family_t curve_family; - switch(trusted_block->ecdsa.key.curve_id) { + switch (trusted_block->ecdsa.key.curve_id) { #if CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_256_BITS - case ECDSA_CURVE_P256: - key_size = 32; - curve_family = PSA_ECC_FAMILY_SECP_R1; - psa_set_key_bits(&key_attributes, PSA_BYTES_TO_BITS(key_size)); - break; + case ECDSA_CURVE_P256: + key_size = 32; + curve_family = PSA_ECC_FAMILY_SECP_R1; + psa_set_key_bits(&key_attributes, PSA_BYTES_TO_BITS(key_size)); + break; #endif /* CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_256_BITS */ #if CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS - case ECDSA_CURVE_P384: - key_size = 48; - curve_family = PSA_ECC_FAMILY_SECP_R1; - psa_set_key_bits(&key_attributes, PSA_BYTES_TO_BITS(key_size)); - break; + case ECDSA_CURVE_P384: + key_size = 48; + curve_family = PSA_ECC_FAMILY_SECP_R1; + psa_set_key_bits(&key_attributes, PSA_BYTES_TO_BITS(key_size)); + break; #endif /* CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS */ - default: - ESP_LOGE(TAG, "Invalid curve ID"); - return ESP_ERR_INVALID_ARG; + default: + ESP_LOGE(TAG, "Invalid curve ID"); + return ESP_ERR_INVALID_ARG; } #if CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS diff --git a/components/bootloader_support/src/secure_boot_v2/secure_boot_rsa_signature.c b/components/esp_image_verify/src/secure_boot_v2/secure_boot_rsa_signature.c similarity index 90% rename from components/bootloader_support/src/secure_boot_v2/secure_boot_rsa_signature.c rename to components/esp_image_verify/src/secure_boot_v2/secure_boot_rsa_signature.c index 7f815214f67..1c304637dcc 100644 --- a/components/bootloader_support/src/secure_boot_v2/secure_boot_rsa_signature.c +++ b/components/esp_image_verify/src/secure_boot_v2/secure_boot_rsa_signature.c @@ -24,9 +24,9 @@ ESP_LOG_ATTR_TAG(TAG, "secure_boot_v2_rsa"); * } */ static int encode_rsa_pubkey_der(const uint8_t *modulus, size_t modulus_len, - const uint8_t *exponent, size_t exponent_len, - uint8_t *der_buf, size_t der_buf_size, - uint8_t **der_start, size_t *der_len) + const uint8_t *exponent, size_t exponent_len, + uint8_t *der_buf, size_t der_buf_size, + uint8_t **der_start, size_t *der_len) { if (!der_buf || !der_start || !der_len || der_buf_size == 0) { return MBEDTLS_ERR_X509_BAD_INPUT_DATA; @@ -77,7 +77,7 @@ static int encode_rsa_pubkey_der(const uint8_t *modulus, size_t modulus_len, /* Write SEQUENCE header */ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, der_buf, len)); MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, der_buf, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)); + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)); *der_start = c; *der_len = len; @@ -137,11 +137,11 @@ esp_err_t verify_rsa_signature_block(const ets_secure_boot_signature_t *sig_bloc e_bytes[3] = trusted_block->key.e & 0xFF; ret = encode_rsa_pubkey_der( - n_be, rsa_key_size, - e_bytes, sizeof(e_bytes), - pubkey_der_buf, pubkey_der_buf_size, - &der_start, &der_len - ); + n_be, rsa_key_size, + e_bytes, sizeof(e_bytes), + pubkey_der_buf, pubkey_der_buf_size, + &der_start, &der_len + ); free(n_be); @@ -170,8 +170,8 @@ esp_err_t verify_rsa_signature_block(const ets_secure_boot_signature_t *sig_bloc /* Verify the signature using PSA APIs */ status = psa_verify_hash(key_id, PSA_ALG_RSA_PSS(PSA_ALG_SHA_256), - image_digest, ESP_SECURE_BOOT_DIGEST_LEN, - sig_be, rsa_key_size); + image_digest, ESP_SECURE_BOOT_DIGEST_LEN, + sig_be, rsa_key_size); if (status != PSA_SUCCESS) { ESP_LOGE(TAG, "Signature verification failed, err: %d", status); diff --git a/components/bootloader_support/src/secure_boot_v2/secure_boot_signature_priv.h b/components/esp_image_verify/src/secure_boot_v2/secure_boot_signature_priv.h similarity index 100% rename from components/bootloader_support/src/secure_boot_v2/secure_boot_signature_priv.h rename to components/esp_image_verify/src/secure_boot_v2/secure_boot_signature_priv.h diff --git a/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_app.c b/components/esp_image_verify/src/secure_boot_v2/secure_boot_signatures_app.c similarity index 97% rename from components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_app.c rename to components/esp_image_verify/src/secure_boot_v2/secure_boot_signatures_app.c index 44a2ea05f1c..677ec78b39c 100644 --- a/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_app.c +++ b/components/esp_image_verify/src/secure_boot_v2/secure_boot_signatures_app.c @@ -7,7 +7,7 @@ #include "bootloader_flash_priv.h" #include "bootloader_sha.h" -#include "bootloader_utility.h" +#include "bootloader_sha_flash.h" #include "bootloader_signature.h" #include "esp_log.h" #include "esp_image_format.h" @@ -35,7 +35,7 @@ ESP_LOG_ATTR_TAG(TAG, "secure_boot_v2"); static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *block) { if (block->magic_byte != ETS_SECURE_BOOT_V2_SIGNATURE_MAGIC - || block->block_crc != esp_rom_crc32_le(0, (uint8_t *)block, CRC_SIGN_BLOCK_LEN)) { + || block->block_crc != esp_rom_crc32_le(0, (uint8_t *)block, CRC_SIGN_BLOCK_LEN)) { return ESP_FAIL; } if (block->version != ESP_SECURE_BOOT_SCHEME) { @@ -100,11 +100,11 @@ static esp_err_t calculate_image_public_key_digests(bool verify_image_digest, bo if (verify_image_digest) { // Check we can verify the image using this signature and this key uint8_t temp_verified_digest[ESP_SECURE_BOOT_DIGEST_LEN]; - #if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME +#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME bool verified = ets_rsa_pss_verify(&block.key, block.signature, image_digest, temp_verified_digest); - #elif CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME +#elif CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME bool verified = ets_ecdsa_verify(&block.ecdsa.key.point[0], block.ecdsa.signature, block.ecdsa.key.curve_id, image_digest, temp_verified_digest); - #endif +#endif if (!verified) { ESP_LOGE(TAG, "Secure boot key (%d) verification failed.", i); continue; @@ -157,7 +157,7 @@ static esp_err_t get_secure_boot_key_digests(esp_image_sig_public_key_digests_t // Gets key digests from running app ESP_LOGI(TAG, "Take trusted digest key(s) from running app"); return esp_secure_boot_get_signature_blocks_for_running_app(true, public_key_digests); - } else { // CONFIG_SECURE_BOOT_V2_ENABLED + } else { // CONFIG_SECURE_BOOT_V2_ENABLED ESP_LOGI(TAG, "Take trusted digest key(s) from eFuse block(s)"); // Read key digests from efuse esp_secure_boot_key_digests_t efuse_trusted; @@ -172,7 +172,7 @@ static esp_err_t get_secure_boot_key_digests(esp_image_sig_public_key_digests_t if (public_key_digests->num_digests > 0) { return ESP_OK; } - } + } return ESP_ERR_NOT_FOUND; } @@ -282,7 +282,7 @@ esp_err_t esp_secure_boot_verify_sbv2_signature_block(const ets_secure_boot_sign break; } } - return (ret != 0 || any_trusted_key == false) ? ESP_ERR_IMAGE_INVALID: ESP_OK; + return (ret != 0 || any_trusted_key == false) ? ESP_ERR_IMAGE_INVALID : ESP_OK; } #if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME diff --git a/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_bootloader.c b/components/esp_image_verify/src/secure_boot_v2/secure_boot_signatures_bootloader.c similarity index 98% rename from components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_bootloader.c rename to components/esp_image_verify/src/secure_boot_v2/secure_boot_signatures_bootloader.c index f81e8972b8f..50f61a5fcfb 100644 --- a/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_bootloader.c +++ b/components/esp_image_verify/src/secure_boot_v2/secure_boot_signatures_bootloader.c @@ -9,7 +9,7 @@ #include "esp_fault.h" #include "bootloader_flash_priv.h" #include "bootloader_sha.h" -#include "bootloader_utility.h" +#include "bootloader_sha_flash.h" #include "bootloader_signature.h" #include "esp_log.h" #include "esp_image_format.h" @@ -63,7 +63,7 @@ esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length) static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *block) { if (block->magic_byte != ETS_SECURE_BOOT_V2_SIGNATURE_MAGIC - || block->block_crc != esp_rom_crc32_le(0, (uint8_t *)block, CRC_SIGN_BLOCK_LEN)) { + || block->block_crc != esp_rom_crc32_le(0, (uint8_t *)block, CRC_SIGN_BLOCK_LEN)) { return ESP_FAIL; } if (block->version != ESP_SECURE_BOOT_SCHEME) { diff --git a/components/esp_partition/CMakeLists.txt b/components/esp_partition/CMakeLists.txt index c2be4594302..63e09e9091d 100644 --- a/components/esp_partition/CMakeLists.txt +++ b/components/esp_partition/CMakeLists.txt @@ -29,7 +29,7 @@ else() set(srcs "partition.c") set(priv_reqs esp_system spi_flash partition_table efuse) set(reqs esp_blockdev) - set(private_include_dirs) + set(private_include_dirs "") idf_build_get_property(build_dir BUILD_DIR) idf_build_get_property(target IDF_TARGET) @@ -41,7 +41,7 @@ else() idf_component_get_property(bootloader_support_dir bootloader_support COMPONENT_DIR) set(private_include_dirs ${bootloader_support_dir}/include) else() - list(APPEND priv_reqs bootloader_support app_update) + list(APPEND priv_reqs bootloader_support) list(APPEND srcs "partition_target.c") endif() diff --git a/components/esp_partition/include/esp_partition.h b/components/esp_partition/include/esp_partition.h index ec747c9ab30..6e2dd1456f3 100644 --- a/components/esp_partition/include/esp_partition.h +++ b/components/esp_partition/include/esp_partition.h @@ -535,6 +535,10 @@ void esp_partition_munmap(esp_partition_mmap_handle_t handle); * - ESP_ERR_NO_MEM: Cannot allocate memory for sha256 operation. * - ESP_ERR_IMAGE_INVALID: App partition doesn't contain a valid app image. * - ESP_FAIL: An allocation error occurred. + * + * @note Requires the esp_image_verify component in the build (apps using OTA get + * it through app_update). Calling it without that component fails at link + * time with an undefined reference. */ esp_err_t esp_partition_get_sha256(const esp_partition_t* partition, uint8_t* sha_256); diff --git a/components/esp_partition/include/esp_private/esp_partition_utils.h b/components/esp_partition/include/esp_private/esp_partition_utils.h new file mode 100644 index 00000000000..e3c25e5bf91 --- /dev/null +++ b/components/esp_partition/include/esp_private/esp_partition_utils.h @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "esp_partition.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Find the APP partition containing the currently executing firmware. + * + * Private helper shared by esp_partition and app_update; application code + * should prefer esp_ota_get_running_partition() (app_update). The result is + * cached after the first lookup. + * + * @return Running APP partition + */ +const esp_partition_t *esp_partition_get_running_partition(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_partition/partition_target.c b/components/esp_partition/partition_target.c index 0bcd97f1aa0..56046ad2f97 100644 --- a/components/esp_partition/partition_target.c +++ b/components/esp_partition/partition_target.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,7 +19,7 @@ #include "esp_rom_md5.h" #include "spi_flash_mmap.h" #include "bootloader_common.h" -#include "esp_ota_ops.h" +#include "esp_private/esp_partition_utils.h" #define HASH_LEN 32 /* SHA-256 digest length */ @@ -189,7 +189,13 @@ void esp_partition_munmap(esp_partition_mmap_handle_t handle) esp_err_t esp_partition_get_sha256(const esp_partition_t *partition, uint8_t *sha_256) { - return bootloader_common_get_sha256_of_partition(partition->address, partition->size, partition->type, sha_256); + /* Single shared implementation lives in bootloader_common. + Inline its body here once that API is removed. */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + return bootloader_common_get_sha256_of_partition(partition->address, partition->size, + partition->type, sha_256); +#pragma GCC diagnostic pop } bool esp_partition_check_identity(const esp_partition_t *partition_1, const esp_partition_t *partition_2) @@ -224,12 +230,43 @@ bool esp_partition_is_flash_region_writable(size_t addr, size_t size) return true; } +const esp_partition_t *esp_partition_get_running_partition(void) +{ + static const esp_partition_t *s_running_partition = NULL; + + if (s_running_partition != NULL) { + return s_running_partition; + } + size_t phys_offs = spi_flash_cache2phys(esp_partition_get_running_partition); + + assert(phys_offs != SPI_FLASH_CACHE2PHYS_FAIL); /* indicates cache2phys lookup is buggy */ + if (phys_offs == SPI_FLASH_CACHE2PHYS_FAIL) { + abort(); /* stay fatal when asserts are compiled out */ + } + + esp_partition_iterator_t it = esp_partition_find(ESP_PARTITION_TYPE_APP, + ESP_PARTITION_SUBTYPE_ANY, NULL); + assert(it != NULL); /* has to be at least one app partition */ + + while (it != NULL) { + const esp_partition_t *p = esp_partition_get(it); + if (phys_offs >= p->address && phys_offs < p->address + p->size) { + esp_partition_iterator_release(it); + s_running_partition = p; + return p; + } + it = esp_partition_next(it); + } + + abort(); /* Partition table is invalid or corrupt */ +} + bool esp_partition_main_flash_region_safe(size_t addr, size_t size) { if (addr <= ESP_PARTITION_TABLE_OFFSET + ESP_PARTITION_TABLE_MAX_LEN) { return false; } - const esp_partition_t *p = esp_ota_get_running_partition(); + const esp_partition_t *p = esp_partition_get_running_partition(); if (addr >= p->address && addr < p->address + p->size) { return false; } diff --git a/components/esp_tee/subproject/CMakeLists.txt b/components/esp_tee/subproject/CMakeLists.txt index 0635a5a37b8..ad99ffca9a7 100644 --- a/components/esp_tee/subproject/CMakeLists.txt +++ b/components/esp_tee/subproject/CMakeLists.txt @@ -25,7 +25,7 @@ set(ESP_TEE_BUILD 1) set(NON_OS_BUILD 1) # Additional components -list(APPEND COMPONENTS bootloader_support efuse esp_hal_mspi esp_hal_wdt +list(APPEND COMPONENTS bootloader_support esp_image_verify efuse esp_hal_mspi esp_hal_wdt esp_hal_security esp_security mbedtls esp_stdio) # TEE-specific components diff --git a/components/esp_tee/subproject/components/attestation/esp_att_utils_crypto.c b/components/esp_tee/subproject/components/attestation/esp_att_utils_crypto.c index 7a5bd54f1ec..a51741c6d3d 100644 --- a/components/esp_tee/subproject/components/attestation/esp_att_utils_crypto.c +++ b/components/esp_tee/subproject/components/attestation/esp_att_utils_crypto.c @@ -11,7 +11,6 @@ #include "esp_err.h" #if ESP_TEE_BUILD -#include "bootloader_sha.h" #include "esp_tee_sec_storage.h" #endif #include "esp_random.h" diff --git a/components/esp_tee/subproject/components/attestation/esp_att_utils_json.c b/components/esp_tee/subproject/components/attestation/esp_att_utils_json.c index 7fb2c91041b..20be4a62abc 100644 --- a/components/esp_tee/subproject/components/attestation/esp_att_utils_json.c +++ b/components/esp_tee/subproject/components/attestation/esp_att_utils_json.c @@ -11,7 +11,6 @@ #include "esp_err.h" #if ESP_TEE_BUILD -#include "bootloader_sha.h" #include "esp_tee_sec_storage.h" #endif #include "esp_random.h" diff --git a/components/esp_tee/test_apps/tee_test_fw/main/CMakeLists.txt b/components/esp_tee/test_apps/tee_test_fw/main/CMakeLists.txt index 7cfa4b308c8..d91b4193ed3 100644 --- a/components/esp_tee/test_apps/tee_test_fw/main/CMakeLists.txt +++ b/components/esp_tee/test_apps/tee_test_fw/main/CMakeLists.txt @@ -1,6 +1,6 @@ idf_build_get_property(idf_path IDF_PATH) -set(priv_requires bootloader_support esp_driver_gptimer esp_system esp_tee esp_timer mbedtls spi_flash) +set(priv_requires bootloader_support esp_driver_gptimer esp_system esp_tee esp_timer mbedtls spi_flash esp_image_verify) # Test FW related list(APPEND priv_requires console nvs_flash test_utils unity) # TEE related diff --git a/tools/idf_py_actions/hints.yml b/tools/idf_py_actions/hints.yml index 345f0cc8d21..2dd1fa59acf 100644 --- a/tools/idf_py_actions/hints.yml +++ b/tools/idf_py_actions/hints.yml @@ -592,3 +592,12 @@ - re: "error: 'WIFI_BW_HT40' undeclared \\(first use in this function\\)" hint: "The enum value 'WIFI_BW_HT40' has been removed. Use 'WIFI_BW40' instead." + +- + re: "undefined reference to `(esp_image_get_metadata|bootloader_sha256_flash_contents|bootloader_sha384_flash_contents)'" + hint: "'{}' is provided by the esp_image_verify component, which is not in the build. APIs such as esp_partition_get_sha256() need it. Add esp_image_verify (or app_update, which includes it and provides the OTA APIs) to the calling component's PRIV_REQUIRES or to the project's COMPONENTS list." + match_to_output: True + +- + re: "undefined reference to `esp_secure_boot_check_signature_on_update'" + hint: "CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT requires the startup signature check from the esp_image_verify component, which is not in the build. Add esp_image_verify (or app_update, which includes it) to the calling component's PRIV_REQUIRES or to the project's COMPONENTS list." diff --git a/tools/test_apps/security/signed_app_no_secure_boot/main/CMakeLists.txt b/tools/test_apps/security/signed_app_no_secure_boot/main/CMakeLists.txt index 72d6f353d54..e41d19e416c 100644 --- a/tools/test_apps/security/signed_app_no_secure_boot/main/CMakeLists.txt +++ b/tools/test_apps/security/signed_app_no_secure_boot/main/CMakeLists.txt @@ -1,3 +1,3 @@ idf_component_register(SRCS "main.c" INCLUDE_DIRS "." - PRIV_REQUIRES nvs_flash) + PRIV_REQUIRES nvs_flash esp_image_verify) diff --git a/tools/test_apps/system/g1_components/CMakeLists.txt b/tools/test_apps/system/g1_components/CMakeLists.txt index d652da0b209..3d7dfeab25b 100644 --- a/tools/test_apps/system/g1_components/CMakeLists.txt +++ b/tools/test_apps/system/g1_components/CMakeLists.txt @@ -44,11 +44,6 @@ set(extra_allowed_components # These components are currently included into "G1" build, but shouldn't. # After removing the extra dependencies, remove the components from this list as well. set(extra_components_which_shouldnt_be_included - # app_update gets added because of spi_flash and esp_partition. - # esp_partition will get removed from g1 and spi_flash does not actually seem to need app_update anymore. - # When esp-partition is removed from g1 build it should be easy for us to also remove app-update # TODO IDF-8577 - app_update - # bootloader is only included from esptool_py, which should be removed from G1 bootloader @@ -85,7 +80,7 @@ set(extra_components_which_shouldnt_be_included # esp_pm is pulled in by esp_system due to pm_init and freertos idle hook # both could be moved to pm component if esp-system idle hook provided a way to register hooks # esp_hw_support dependency seems like it could be removed? - # It is also used by esp_driver_gpio, mbedtls all of which should be removed from G1-only build. + # It is also used by esp_driver_gpio, which should be removed from G1-only build. # IDF-10415 esp_pm @@ -101,10 +96,6 @@ set(extra_components_which_shouldnt_be_included # should be removed from G1-only build. esptool_py - # mbedtls is a dependency of bootloader_support (plus other easier-to-remove ones) - # it is hard to make it conditional, need to remove bootloader_support. - mbedtls - # partition_table is pulled in by app_update, esptool_py, bootloader, esp_partition; all to be removed partition_table @@ -118,12 +109,9 @@ set(extra_components_which_shouldnt_be_included # pthread is required by cxx. See [refactor-todo] about cxx, can it work without pthread? pthread - # esp_security is required by mbedtls and spi_flash + # esp_security is required by spi_flash esp_security - # esp_driver_dma is required by mbedtls - esp_driver_dma - # esp_usb_cdc_rom_console is used by the panic handler, will be conditional on cdc console option when # the new build-system is implemented esp_usb_cdc_rom_console diff --git a/tools/test_apps/system/mmu_page_size/main/CMakeLists.txt b/tools/test_apps/system/mmu_page_size/main/CMakeLists.txt index 3aa21a2cd1b..e5fdfaa3d34 100644 --- a/tools/test_apps/system/mmu_page_size/main/CMakeLists.txt +++ b/tools/test_apps/system/mmu_page_size/main/CMakeLists.txt @@ -1,2 +1,2 @@ idf_component_register(SRCS "main.c" - PRIV_REQUIRES unity esp_partition bootloader_support) + PRIV_REQUIRES unity esp_partition bootloader_support esp_image_verify)