diff --git a/components/bootloader_support/include/esp_secure_boot.h b/components/bootloader_support/include/esp_secure_boot.h index 84cb241010..58e32ea190 100644 --- a/components/bootloader_support/include/esp_secure_boot.h +++ b/components/bootloader_support/include/esp_secure_boot.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,27 +14,8 @@ #include "sdkconfig.h" #include "esp_rom_crc.h" #include "hal/efuse_ll.h" - -#if CONFIG_IDF_TARGET_ESP32 -#include "esp32/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32S2 -#include "esp32s2/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32C3 -#include "esp32c3/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32S3 -#include "esp32s3/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32C2 -#include "esp32c2/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32C6 -#include "esp32c6/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32H2 -#include "esp32h2/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32P4 -#include "esp32p4/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32C5 -#include "esp32c5/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32C61 -#include "esp32c61/rom/secure_boot.h" +#if !CONFIG_IDF_TARGET_LINUX +#include "rom/secure_boot.h" #endif #ifdef CONFIG_SECURE_BOOT_V1_ENABLED diff --git a/components/bootloader_support/private_include/bootloader_signature.h b/components/bootloader_support/private_include/bootloader_signature.h index f101b42402..2ade78bf43 100644 --- a/components/bootloader_support/private_include/bootloader_signature.h +++ b/components/bootloader_support/private_include/bootloader_signature.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,28 +8,7 @@ #include "sdkconfig.h" #include #include - -#if CONFIG_IDF_TARGET_ESP32 -#include "esp32/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32S2 -#include "esp32s2/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32C3 -#include "esp32c3/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32S3 -#include "esp32s3/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32C2 -#include "esp32c2/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32C6 -#include "esp32c6/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32H2 -#include "esp32h2/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32P4 -#include "esp32p4/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32C5 -#include "esp32c5/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32C61 -#include "esp32c61/rom/secure_boot.h" -#endif +#include "rom/secure_boot.h" #ifdef __cplusplus extern "C" { diff --git a/components/bootloader_support/src/esp32h21/secure_boot_secure_features.c b/components/bootloader_support/src/esp32h21/secure_boot_secure_features.c index 6c4db9ea16..0ea0e26e18 100644 --- a/components/bootloader_support/src/esp32h21/secure_boot_secure_features.c +++ b/components/bootloader_support/src/esp32h21/secure_boot_secure_features.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,7 +16,59 @@ static __attribute__((unused)) const char *TAG = "secure_boot"; esp_err_t esp_secure_boot_enable_secure_features(void) { - //TODO: [ESP32H21] IDF-11500 - abort(); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT); + +#ifdef CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE + ESP_LOGI(TAG, "Enabling Security download mode..."); + esp_err_t err = esp_efuse_enable_rom_secure_download_mode(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Could not enable Security download mode..."); + return err; + } +#elif CONFIG_SECURE_DISABLE_ROM_DL_MODE + ESP_LOGI(TAG, "Disable ROM Download mode..."); + esp_err_t err = esp_efuse_disable_rom_download_mode(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Could not disable ROM Download mode..."); + return err; + } +#else + ESP_LOGW(TAG, "UART ROM Download mode kept enabled - SECURITY COMPROMISED"); +#endif + +#ifdef SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED + esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_ECDSA_CURVE_MODE); +#endif + +#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG + ESP_LOGI(TAG, "Disable hardware & software JTAG..."); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_PAD_JTAG); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_USB_JTAG); + esp_efuse_write_field_cnt(ESP_EFUSE_SOFT_DIS_JTAG, ESP_EFUSE_SOFT_DIS_JTAG[0]->bit_count); +#else + ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED"); +#endif + +#ifdef CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE + esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE); +#endif + + esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_EN); + +#ifndef CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS + bool rd_dis_now = true; +#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED + /* If flash encryption is not enabled yet then don't read-disable efuses yet, do it later in the boot + when Flash Encryption is being enabled */ + rd_dis_now = esp_flash_encryption_enabled(); +#endif + if (rd_dis_now) { + ESP_LOGI(TAG, "Prevent read disabling of additional efuses..."); + esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS); + } +#else + ESP_LOGW(TAG, "Allowing read disabling of additional efuses - SECURITY COMPROMISED"); +#endif + return ESP_OK; } diff --git a/components/bootloader_support/src/secure_boot.c b/components/bootloader_support/src/secure_boot.c index 9df2e6278c..94ca379056 100644 --- a/components/bootloader_support/src/secure_boot.c +++ b/components/bootloader_support/src/secure_boot.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -340,6 +340,21 @@ bool esp_secure_boot_cfg_verify_release_mode(void) #endif } +#ifdef SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED + secure = esp_efuse_read_field_bit(ESP_EFUSE_WR_DIS_ECDSA_CURVE_MODE); + if (!secure) { + uint8_t current_curve; + esp_err_t err = esp_efuse_read_field_blob(ESP_EFUSE_ECDSA_CURVE_MODE, ¤t_curve, ESP_EFUSE_ECDSA_CURVE_MODE[0]->bit_count); + if (err == ESP_OK) { + if (current_curve != ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_ONLY_P256_BIT_LOCKED) { + // If not P256 mode + result &= secure; + ESP_LOGW(TAG, "Not write disabled ECDSA curve mode (set WR_DIS_ECDSA_CURVE_MODE->1)"); + } + } + } +#endif + #ifdef CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE secure = esp_efuse_read_field_bit(ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE); result &= secure; diff --git a/components/bootloader_support/src/secure_boot_v2/secure_boot_signature_priv.h b/components/bootloader_support/src/secure_boot_v2/secure_boot_signature_priv.h index 22a7701f18..91ec2dbdf0 100644 --- a/components/bootloader_support/src/secure_boot_v2/secure_boot_signature_priv.h +++ b/components/bootloader_support/src/secure_boot_v2/secure_boot_signature_priv.h @@ -1,31 +1,10 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "esp_secure_boot.h" - -#if CONFIG_IDF_TARGET_ESP32 -#include "esp32/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32S2 -#include "esp32s2/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32C3 -#include "esp32c3/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32S3 -#include "esp32s3/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32C2 -#include "esp32c2/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32C6 -#include "esp32c6/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32H2 -#include "esp32h2/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32P4 -#include "esp32p4/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32C5 -#include "esp32c5/rom/secure_boot.h" -#elif CONFIG_IDF_TARGET_ESP32C61 -#include "esp32c61/rom/secure_boot.h" -#endif +#include "rom/secure_boot.h" esp_err_t verify_ecdsa_signature_block(const ets_secure_boot_signature_t *sig_block, const uint8_t *image_digest, const ets_secure_boot_sig_block_t *trusted_block); diff --git a/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_app.c b/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_app.c index 8dc886e67d..9ab1c8f848 100644 --- a/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_app.c +++ b/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_app.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -48,6 +48,18 @@ static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *blo ESP_LOGE(TAG, "%s signing scheme selected but signature block generated for %s scheme", esp_secure_boot_get_scheme_name(ESP_SECURE_BOOT_SCHEME), esp_secure_boot_get_scheme_name(block->version)); return ESP_FAIL; } + +#if SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED && CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME + if (block->ecdsa.key.curve_id == ECDSA_CURVE_P192) { + // Enabling ECDSA-192 Curve mode + esp_err_t err = esp_efuse_enable_ecdsa_p192_curve_mode(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to enable ECDSA-192 curve mode: %d", err); + return err; + } + } +#endif + return ESP_OK; } diff --git a/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_bootloader.c b/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_bootloader.c index 45332f9925..00b3c1b022 100644 --- a/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_bootloader.c +++ b/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_bootloader.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -65,6 +65,18 @@ static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *blo ESP_LOGE(TAG, "%s signing scheme selected but signature block generated for %s scheme", esp_secure_boot_get_scheme_name(ESP_SECURE_BOOT_SCHEME), esp_secure_boot_get_scheme_name(block->version)); return ESP_FAIL; } + +#if SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED && CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME + if (block->ecdsa.key.curve_id == ECDSA_CURVE_P192) { + // Enabling ECDSA-192 Curve mode + esp_err_t err = esp_efuse_enable_ecdsa_p192_curve_mode(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to enable ECDSA-192 curve mode: %d", err); + return err; + } + } +#endif + return ESP_OK; } diff --git a/components/efuse/esp32h21/esp_efuse_fields.c b/components/efuse/esp32h21/esp_efuse_fields.c index 104fdb66aa..69c5862631 100644 --- a/components/efuse/esp32h21/esp_efuse_fields.c +++ b/components/efuse/esp32h21/esp_efuse_fields.c @@ -65,12 +65,7 @@ esp_err_t esp_efuse_enable_ecdsa_p192_curve_mode(void) esp_err_t err; uint8_t current_curve, next_curve; - err = esp_efuse_read_field_blob(ESP_EFUSE_ECDSA_CURVE_MODE, ¤t_curve, ESP_EFUSE_ECDSA_CURVE_MODE[0]->bit_count); - if (err != ESP_OK) { - ESP_EARLY_LOGE(TAG, "Failed to read ECDSA curve mode"); - return err; - } - + current_curve = efuse_ll_get_ecdsa_curve_mode(); // Check if already in desired state if (current_curve == ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_BOTH_P192_P256_BIT || current_curve == ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_ONLY_P192_BIT) { ESP_EARLY_LOGD(TAG, "ECDSA P-192 curve mode is already enabled"); diff --git a/components/esp_security/src/init.c b/components/esp_security/src/init.c index 11d01f89d9..26b99a94a2 100644 --- a/components/esp_security/src/init.c +++ b/components/esp_security/src/init.c @@ -60,8 +60,7 @@ ESP_SYSTEM_INIT_FN(esp_security_init, SECONDARY, BIT(0), 103) #endif #if CONFIG_ESP_ECDSA_ENABLE_P192_CURVE - esp_err_t err; - err = esp_efuse_enable_ecdsa_p192_curve_mode(); + esp_err_t err = esp_efuse_enable_ecdsa_p192_curve_mode(); if (err != ESP_OK) { return err; } diff --git a/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in index 68975d81d1..2ac27a68bb 100644 --- a/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in @@ -79,6 +79,10 @@ config SOC_FLASH_ENC_SUPPORTED bool default y +config SOC_SECURE_BOOT_SUPPORTED + bool + default y + config SOC_SPI_FLASH_SUPPORTED bool default y diff --git a/components/soc/esp32h21/include/soc/soc_caps.h b/components/soc/esp32h21/include/soc/soc_caps.h index 63e13dd9b2..45eeac58bd 100644 --- a/components/soc/esp32h21/include/soc/soc_caps.h +++ b/components/soc/esp32h21/include/soc/soc_caps.h @@ -51,7 +51,7 @@ #define SOC_ECC_EXTENDED_MODES_SUPPORTED 1 #define SOC_ECDSA_SUPPORTED 1 #define SOC_FLASH_ENC_SUPPORTED 1 -// #define SOC_SECURE_BOOT_SUPPORTED 1 //TODO: [ESP32H21] IDF-11500 +#define SOC_SECURE_BOOT_SUPPORTED 1 // #define SOC_BOD_SUPPORTED 1 //TODO: [ESP32H21] IDF-11530 // #define SOC_APM_SUPPORTED 1 //TODO: [ESP32H21] IDF-11494 // #define SOC_PMU_SUPPORTED 1 diff --git a/docs/en/security/secure-boot-v2.rst b/docs/en/security/secure-boot-v2.rst index f6842643c1..30bdf8be2c 100644 --- a/docs/en/security/secure-boot-v2.rst +++ b/docs/en/security/secure-boot-v2.rst @@ -5,11 +5,11 @@ Secure Boot v2 :link_to_translation:`zh_CN:[中文]` -{IDF_TARGET_SBV2_SCHEME:default="RSA-PSS", esp32c2="ECDSA", esp32c6="RSA-PSS or ECDSA", esp32h2="RSA-PSS or ECDSA", esp32p4="RSA-PSS or ECDSA", esp32c5="RSA-PSS or ECDSA", esp32c61="ECDSA"} +{IDF_TARGET_SBV2_SCHEME:default="RSA-PSS", esp32c2="ECDSA", esp32c6="RSA-PSS or ECDSA", esp32h2="RSA-PSS or ECDSA", esp32p4="RSA-PSS or ECDSA", esp32c5="RSA-PSS or ECDSA", esp32c61="ECDSA", esp32h21="RSA-PSS or ECDSA"} -{IDF_TARGET_SBV2_KEY:default="RSA-3072", esp32c2="ECDSA-256 or ECDSA-192", esp32c6="RSA-3072, ECDSA-256, or ECDSA-192", esp32h2="RSA-3072, ECDSA-256, or ECDSA-192", esp32p4="RSA-3072, ECDSA-256, or ECDSA-192", esp32c5="RSA-3072, ECDSA-256, or ECDSA-192", esp32c61="ECDSA-256 or ECDSA-192"} +{IDF_TARGET_SBV2_KEY:default="RSA-3072", esp32c2="ECDSA-256 or ECDSA-192", esp32c6="RSA-3072, ECDSA-256, or ECDSA-192", esp32h2="RSA-3072, ECDSA-256, or ECDSA-192", esp32p4="RSA-3072, ECDSA-256, or ECDSA-192", esp32c5="RSA-3072, ECDSA-256, or ECDSA-192", esp32c61="ECDSA-256 or ECDSA-192", esp32h21="RSA-3072, ECDSA-256, or ECDSA-192"} -{IDF_TARGET_SECURE_BOOT_OPTION_TEXT:default="", esp32c6="RSA is recommended for faster verification. You can choose either the RSA or ECDSA scheme from the menu.", esp32h2="RSA is recommended for faster verification. You can choose either the RSA or ECDSA scheme from the menu.", esp32p4="RSA is recommended for faster verification. You can choose either the RSA or ECDSA scheme from the menu.", esp32c5="RSA is recommended for faster verification. You can choose either the RSA or ECDSA scheme from the menu."} +{IDF_TARGET_SECURE_BOOT_OPTION_TEXT:default="", esp32c6="RSA is recommended for faster verification. You can choose either the RSA or ECDSA scheme from the menu.", esp32h2="RSA is recommended for faster verification. You can choose either the RSA or ECDSA scheme from the menu.", esp32p4="RSA is recommended for faster verification. You can choose either the RSA or ECDSA scheme from the menu.", esp32c5="RSA is recommended for faster verification. You can choose either the RSA or ECDSA scheme from the menu.", esp32h21="RSA is recommended for faster verification. You can choose either the RSA or ECDSA scheme from the menu."} {IDF_TARGET_ECO_VERSION:default="", esp32="(v3.0 onwards)", esp32c3="(v0.3 onwards)"} @@ -69,6 +69,9 @@ The Secure Boot process on {IDF_TARGET_NAME} involves the following steps: 2. When the second stage bootloader loads a particular application image, the application's {IDF_TARGET_SBV2_SCHEME} signature is verified. If the verification is successful, the application image is executed. +.. only:: SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED + + The ECDSA-P192 curve is disabled by default on {IDF_TARGET_NAME}. If the provided secure boot signing key uses the ECDSA-P192 curve, the system attempts to enable support for ECDSA-P192 curve mode to proceed with secure boot. However, if the curve mode has already been locked, enabling ECDSA-P192 is not possible. In such cases, secure boot cannot be configured using an ECDSA-P192 key. The user must instead provide a signing key based on the ECDSA-P256 curve or RSA based signing key. Advantages ---------- @@ -437,6 +440,10 @@ Restrictions After Secure Boot Is Enabled - After Secure Boot is enabled, further read-protection of eFuse keys is not possible. This is done to prevent an attacker from read-protecting the eFuse block that contains the Secure Boot public key digest, which could result in immediate denial of service and potentially enable a fault injection attack to bypass the signature verification. For further information on read-protected keys, see the details below. +.. only:: SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED + + When Secure Boot is enabled, the ECDSA curve mode becomes write-protected. This means that if the curve mode was not previously set to use the ECDSA-P192 key before enabling Secure Boot, it will no longer be possible to configure or use the ECDSA-P192 curve with the ECDSA peripheral afterward. + Burning read-protected keys ~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/en/security/security-features-enablement-workflows.rst b/docs/en/security/security-features-enablement-workflows.rst index 9ff9f71789..854c9e0d46 100644 --- a/docs/en/security/security-features-enablement-workflows.rst +++ b/docs/en/security/security-features-enablement-workflows.rst @@ -485,6 +485,7 @@ In this workflow we shall use ``espsecure`` tool to generate signing keys and us :SOC_EFUSE_DIS_USB_JTAG: - ``DIS_USB_JTAG``: Disable USB switch to JTAG. :SOC_EFUSE_DIS_PAD_JTAG: - ``DIS_PAD_JTAG``: Disable JTAG permanently. :SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS: - ``SECURE_BOOT_AGGRESSIVE_REVOKE``: Aggressive revocation of key digests, see :ref:`secure-boot-v2-aggressive-key-revocation` for more details. + :SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED: - ``WR_DIS_ECDSA_CURVE_MODE``: Disable ECDSA curve mode. The respective eFuses can be burned by running: diff --git a/tools/test_apps/security/secure_boot/README.md b/tools/test_apps/security/secure_boot/README.md index f042b06414..9fc2e18f7d 100644 --- a/tools/test_apps/security/secure_boot/README.md +++ b/tools/test_apps/security/secure_boot/README.md @@ -18,6 +18,7 @@ Any of the following ESP module: * ESP32P4 (supports Secure Boot V2) * ESP32C5 (supports Secure Boot V2) * ESP32C61 (supports Secure Boot V2) +* ESP32H21 (supports Secure Boot V2) It is recommended to use Secure Boot V2 from ESP32-ECO3 onwards. @@ -72,7 +73,7 @@ Purpose of the test case (`pytest_secure_boot.py`) is to test the secure boot im ### Hardware required -* FPGA setup with ESP32C3/ESP32S3/ESP32P4/ESP32C5/ESP32C61 image +* FPGA setup with ESP32C3/ESP32S3/ESP32P4/ESP32C5/ESP32C61/ESP32H21 image * COM port for programming and export it as ESPPORT e.g `export ESPPORT=/dev/ttyUSB0` @@ -85,7 +86,7 @@ Purpose of the test case (`pytest_secure_boot.py`) is to test the secure boot im ``` export IDF_ENV_FPGA=1 -idf.py set-target esp32c3 #(or esp32s3 / esp32p4 / esp32c5 / esp32c61) +idf.py set-target esp32c3 #(or esp32s3 / esp32p4 / esp32c5 / esp32c61 / esp32h21) idf.py menuconfig ``` diff --git a/tools/test_apps/security/secure_boot/conftest.py b/tools/test_apps/security/secure_boot/conftest.py index ec30181580..03a1ee672d 100644 --- a/tools/test_apps/security/secure_boot/conftest.py +++ b/tools/test_apps/security/secure_boot/conftest.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 # pylint: disable=W0621 # redefined-outer-name import os @@ -40,8 +40,7 @@ class FpgaSerial(IdfSerial): """ offs = int(self.app.sdkconfig.get('BOOTLOADER_OFFSET_IN_FLASH', 0)) esptool.main( - f'--port {self.esp_port} --no-stub write_flash {str(offs)} {bootloader_path} --force'.split(), - esp=self.esp + f'--port {self.esp_port} --no-stub write_flash {str(offs)} {bootloader_path} --force'.split(), esp=self.esp ) @EspSerial.use_esptool() @@ -53,8 +52,7 @@ class FpgaSerial(IdfSerial): """ offs = int(self.app.flash_args['partition-table']['offset'], 16) esptool.main( - f'--port {self.esp_port} --no-stub write_flash {str(offs)} {partition_table_path}'.split(), - esp=self.esp + f'--port {self.esp_port} --no-stub write_flash {str(offs)} {partition_table_path}'.split(), esp=self.esp ) @EspSerial.use_esptool() @@ -65,10 +63,7 @@ class FpgaSerial(IdfSerial): :return: None """ offs = int(self.app.flash_args['app']['offset'], 16) - esptool.main( - f'--port {self.esp_port} --no-stub write_flash {str(offs)} {app_path}'.split(), - esp=self.esp - ) + esptool.main(f'--port {self.esp_port} --no-stub write_flash {str(offs)} {app_path}'.split(), esp=self.esp) def erase_app_header(self) -> None: """ @@ -86,23 +81,16 @@ class FpgaSerial(IdfSerial): @EspSerial.use_esptool() def burn_efuse_key_digest(self, key: str, purpose: str, block: str) -> None: espefuse.main( - f'--port {self.esp_port} burn_key_digest {block} {key} {purpose} --do-not-confirm'.split(), - esp=self.esp + f'--port {self.esp_port} burn_key_digest {block} {key} {purpose} --do-not-confirm'.split(), esp=self.esp ) @EspSerial.use_esptool() def burn_efuse(self, field: str, val: int) -> None: - espefuse.main( - f'--port {self.esp_port} burn_efuse {field} {str(val)} --do-not-confirm'.split(), - esp=self.esp - ) + espefuse.main(f'--port {self.esp_port} burn_efuse {field} {str(val)} --do-not-confirm'.split(), esp=self.esp) @EspSerial.use_esptool() def burn_efuse_key(self, key: str, purpose: str, block: str) -> None: - espefuse.main( - f'--port {self.esp_port} burn_key {block} {key} {purpose} --do-not-confirm'.split(), - esp=self.esp - ) + espefuse.main(f'--port {self.esp_port} burn_key {block} {key} {purpose} --do-not-confirm'.split(), esp=self.esp) def reset_efuses(self) -> None: with serial.Serial(self.efuse_reset_port) as efuseport: @@ -118,7 +106,7 @@ class FpgaSerial(IdfSerial): class FpgaDut(IdfDut): - SECURE_BOOT_EN_KEY = None # type: str + SECURE_BOOT_EN_KEY = None # type: str SECURE_BOOT_EN_VAL = 0 def __init__(self, *args, **kwargs) -> None: # type: ignore @@ -200,6 +188,20 @@ class Esp32c61FpgaDut(FpgaDut): self.serial.burn_efuse_key_digest(digest, 'SECURE_BOOT_DIGEST%d' % key_index, 'BLOCK_KEY%d' % block) +class Esp32h21FpgaDut(FpgaDut): + SECURE_BOOT_EN_KEY = 'SECURE_BOOT_EN' + SECURE_BOOT_EN_VAL = 1 + + def burn_wafer_version(self) -> None: + pass + + def secure_boot_burn_en_bit(self) -> None: + self.serial.burn_efuse(self.SECURE_BOOT_EN_KEY, self.SECURE_BOOT_EN_VAL) + + def secure_boot_burn_digest(self, digest: str, key_index: int = 0, block: int = 0) -> None: + self.serial.burn_efuse_key_digest(digest, 'SECURE_BOOT_DIGEST%d' % key_index, 'BLOCK_KEY%d' % block) + + @pytest.fixture(scope='module') def monkeypatch_module(request: FixtureRequest) -> MonkeyPatch: mp = MonkeyPatch() @@ -209,16 +211,19 @@ def monkeypatch_module(request: FixtureRequest) -> MonkeyPatch: @pytest.fixture(scope='module', autouse=True) def replace_dut_class(monkeypatch_module: MonkeyPatch, pytestconfig: pytest.Config) -> None: - target = pytestconfig.getoption('target') - if target == 'esp32c3': - monkeypatch_module.setattr('pytest_embedded_idf.IdfDut', Esp32c3FpgaDut) - elif target == 'esp32s3': - monkeypatch_module.setattr('pytest_embedded_idf.IdfDut', Esp32s3FpgaDut) - elif target == 'esp32p4': - monkeypatch_module.setattr('pytest_embedded_idf.IdfDut', Esp32p4FpgaDut) - elif target == 'esp32c5': - monkeypatch_module.setattr('pytest_embedded_idf.IdfDut', Esp32c5FpgaDut) - elif target == 'esp32c61': - monkeypatch_module.setattr('pytest_embedded_idf.IdfDut', Esp32c61FpgaDut) + FPGA_DUT_MAP = { + 'esp32c3': Esp32c3FpgaDut, + 'esp32s3': Esp32s3FpgaDut, + 'esp32p4': Esp32p4FpgaDut, + 'esp32c5': Esp32c5FpgaDut, + 'esp32c61': Esp32c61FpgaDut, + 'esp32h21': Esp32h21FpgaDut, + } + target = pytestconfig.getoption('target') + fpga_dut_class = FPGA_DUT_MAP.get(target) + if fpga_dut_class is None: + raise ValueError(f'Unsupported target: {target}') + + monkeypatch_module.setattr('pytest_embedded_idf.IdfDut', fpga_dut_class) monkeypatch_module.setattr('pytest_embedded_idf.IdfSerial', FpgaSerial)