diff --git a/components/bootloader_support/src/esp32h2/secure_boot_secure_features.c b/components/bootloader_support/src/esp32h2/secure_boot_secure_features.c index 9ea0f69e4b..da7f84df5c 100644 --- a/components/bootloader_support/src/esp32h2/secure_boot_secure_features.c +++ b/components/bootloader_support/src/esp32h2/secure_boot_secure_features.c @@ -1,10 +1,11 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include +#include "hal/ecdsa_ll.h" #include "esp_flash_encrypt.h" #include "esp_secure_boot.h" #include "esp_efuse.h" @@ -36,6 +37,12 @@ esp_err_t esp_secure_boot_enable_secure_features(void) ESP_LOGW(TAG, "UART ROM Download mode kept enabled - SECURITY COMPROMISED"); #endif +#ifdef SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED + if (ecdsa_ll_is_configurable_curve_supported()) { + 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); diff --git a/components/bootloader_support/src/secure_boot.c b/components/bootloader_support/src/secure_boot.c index 94ca379056..7d086a687b 100644 --- a/components/bootloader_support/src/secure_boot.c +++ b/components/bootloader_support/src/secure_boot.c @@ -12,6 +12,10 @@ #include "esp_secure_boot.h" #include "hal/efuse_hal.h" +#ifdef SOC_ECDSA_SUPPORTED +#include "hal/ecdsa_ll.h" +#endif + #ifndef BOOTLOADER_BUILD static __attribute__((unused)) const char *TAG = "secure_boot"; @@ -341,15 +345,17 @@ bool esp_secure_boot_cfg_verify_release_mode(void) } #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)"); + if (ecdsa_ll_is_configurable_curve_supported()) { + 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)"); + } } } } diff --git a/components/efuse/src/esp_efuse_fields.c b/components/efuse/src/esp_efuse_fields.c index b20938047b..af35572dd8 100644 --- a/components/efuse/src/esp_efuse_fields.c +++ b/components/efuse/src/esp_efuse_fields.c @@ -18,6 +18,11 @@ #include "sys/param.h" #include "soc/soc_caps.h" #include "hal/efuse_ll.h" +#include "hal/efuse_hal.h" + +#ifdef SOC_ECDSA_SUPPORTED +#include "hal/ecdsa_ll.h" +#endif /* SOC_ECDSA_SUPPORTED */ static __attribute__((unused)) const char *TAG = "efuse"; @@ -88,8 +93,12 @@ esp_err_t esp_efuse_update_secure_version(uint32_t secure_version) bool esp_efuse_is_ecdsa_p192_curve_supported(void) { #if SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED - uint32_t current_curve = efuse_ll_get_ecdsa_curve_mode(); - return (current_curve == ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_BOTH_P192_P256_BIT || current_curve == ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_ONLY_P192_BIT); + if (ecdsa_ll_is_configurable_curve_supported()) { + uint32_t current_curve = efuse_hal_get_ecdsa_curve_mode(); + return (current_curve == ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_BOTH_P192_P256_BIT || current_curve == ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_ONLY_P192_BIT); + } else { + return true; + } #else return true; #endif /* SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED */ @@ -98,8 +107,12 @@ bool esp_efuse_is_ecdsa_p192_curve_supported(void) bool esp_efuse_is_ecdsa_p256_curve_supported(void) { #if SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED - uint32_t current_curve = efuse_ll_get_ecdsa_curve_mode(); - return (current_curve != ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_ONLY_P192_BIT); + if (ecdsa_ll_is_configurable_curve_supported()) { + uint32_t current_curve = efuse_hal_get_ecdsa_curve_mode(); + return (current_curve != ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_ONLY_P192_BIT); + } else { + return true; + } #else return true; #endif /* SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED */ @@ -109,30 +122,32 @@ bool esp_efuse_is_ecdsa_p256_curve_supported(void) #if SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED esp_err_t esp_efuse_enable_ecdsa_p192_curve_mode(void) { - esp_err_t err; - uint8_t current_curve, next_curve; - 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"); - return ESP_OK; + if (ecdsa_ll_is_configurable_curve_supported()) { + esp_err_t err; + uint8_t current_curve, next_curve; + + current_curve = efuse_hal_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"); + return ESP_OK; + } + + // Check if write is disabled or already locked to P256 + if (esp_efuse_read_field_bit(ESP_EFUSE_WR_DIS_ECDSA_CURVE_MODE) || current_curve == ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_ONLY_P256_BIT_LOCKED) { + ESP_EARLY_LOGE(TAG, "ECDSA curve mode is locked, cannot enable P-192 curve"); + return ESP_FAIL; + } + + // Attempt to write new curve mode + next_curve = ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_BOTH_P192_P256_BIT; + err = esp_efuse_write_field_blob(ESP_EFUSE_ECDSA_CURVE_MODE, &next_curve, ESP_EFUSE_ECDSA_CURVE_MODE[0]->bit_count); + if (err != ESP_OK) { + ESP_EARLY_LOGE(TAG, "Failed to enable ECDSA P-192 curve %d", err); + return err; + } } - - // Check if write is disabled or already locked to P256 - if (esp_efuse_read_field_bit(ESP_EFUSE_WR_DIS_ECDSA_CURVE_MODE) || current_curve == ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_ONLY_P256_BIT_LOCKED) { - ESP_EARLY_LOGE(TAG, "ECDSA curve mode is locked, cannot enable P-192 curve"); - return ESP_FAIL; - } - - // Attempt to write new curve mode - next_curve = ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_BOTH_P192_P256_BIT; - err = esp_efuse_write_field_blob(ESP_EFUSE_ECDSA_CURVE_MODE, &next_curve, ESP_EFUSE_ECDSA_CURVE_MODE[0]->bit_count); - if (err != ESP_OK) { - ESP_EARLY_LOGE(TAG, "Failed to enable ECDSA P-192 curve %d", err); - return err; - } - return ESP_OK; } #endif /* SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED */ diff --git a/components/hal/esp32h2/efuse_hal.c b/components/hal/esp32h2/efuse_hal.c index 94a1051713..f6d1c0f40a 100644 --- a/components/hal/esp32h2/efuse_hal.c +++ b/components/hal/esp32h2/efuse_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,7 @@ #include #include "sdkconfig.h" #include "soc/soc_caps.h" +#include "soc/chip_revision.h" #include "hal/assert.h" #include "hal/efuse_hal.h" #include "hal/efuse_ll.h" @@ -79,6 +80,16 @@ void efuse_hal_rs_calculate(const void *data, void *rs_values) ets_efuse_rs_calculate(data, rs_values); } +uint32_t efuse_hal_get_ecdsa_curve_mode(void) +{ + if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102)) { + return efuse_ll_get_ecdsa_curve_mode(); + } else { + // Curve mode is not configurable for previous versions + return 0; + } +} + /******************* eFuse control functions *************************/ bool efuse_hal_is_coding_error_in_block(unsigned block) diff --git a/components/hal/esp32h2/include/hal/ecdsa_ll.h b/components/hal/esp32h2/include/hal/ecdsa_ll.h index bea4ef26ef..ff83a3709d 100644 --- a/components/hal/esp32h2/include/hal/ecdsa_ll.h +++ b/components/hal/esp32h2/include/hal/ecdsa_ll.h @@ -378,6 +378,16 @@ static inline int ecdsa_ll_get_operation_result(void) return REG_GET_BIT(ECDSA_RESULT_REG, ECDSA_OPERATION_RESULT); } +/** + * @brief Check if the ECDSA curves configuration is supported + * The ECDSA curves configuration is only avliable in chip version + * above 1.2 in ESP32-H2 + */ +static inline bool ecdsa_ll_is_configurable_curve_supported(void) +{ + return ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102); +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32h2/include/hal/efuse_hal.h b/components/hal/esp32h2/include/hal/efuse_hal.h index b6c83d6da6..37c4f72cd9 100644 --- a/components/hal/esp32h2/include/hal/efuse_hal.h +++ b/components/hal/esp32h2/include/hal/efuse_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -54,6 +54,13 @@ void efuse_hal_program(uint32_t block); */ void efuse_hal_rs_calculate(const void *data, void *rs_values); +/** + * @brief Get ECDSA curve mode + * + * @return ECDSA curve mode + */ +uint32_t efuse_hal_get_ecdsa_curve_mode(void); + /** * @brief Checks coding error in a block * diff --git a/components/hal/esp32h2/include/hal/efuse_ll.h b/components/hal/esp32h2/include/hal/efuse_ll.h index c120dfe383..a12018a898 100644 --- a/components/hal/esp32h2/include/hal/efuse_ll.h +++ b/components/hal/esp32h2/include/hal/efuse_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -21,6 +21,11 @@ extern "C" { /******************* eFuse fields *************************/ +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_ecdsa_curve_mode(void) +{ + return EFUSE.rd_repeat_data0.ecdsa_curve_mode; +} + __attribute__((always_inline)) static inline uint32_t efuse_ll_get_flash_crypt_cnt(void) { return EFUSE.rd_repeat_data1.spi_boot_crypt_cnt; diff --git a/components/hal/esp32h21/efuse_hal.c b/components/hal/esp32h21/efuse_hal.c index f59ea7b619..79c58dda99 100644 --- a/components/hal/esp32h21/efuse_hal.c +++ b/components/hal/esp32h21/efuse_hal.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 */ @@ -81,6 +81,11 @@ void efuse_hal_rs_calculate(const void *data, void *rs_values) ets_efuse_rs_calculate(data, rs_values); } +uint32_t efuse_hal_get_ecdsa_curve_mode(void) +{ + return efuse_ll_get_ecdsa_curve_mode(); +} + /******************* eFuse control functions *************************/ bool efuse_hal_is_coding_error_in_block(unsigned block) diff --git a/components/hal/esp32h21/include/hal/ecdsa_ll.h b/components/hal/esp32h21/include/hal/ecdsa_ll.h index 544c217b4c..82607794bd 100644 --- a/components/hal/esp32h21/include/hal/ecdsa_ll.h +++ b/components/hal/esp32h21/include/hal/ecdsa_ll.h @@ -420,6 +420,13 @@ static inline int ecdsa_ll_check_k_value(void) return REG_GET_BIT(ECDSA_RESULT_REG, ECDSA_K_VALUE_WARNING); } +/** + * @brief Check if the ECDSA curves configuration is supported + */ +static inline bool ecdsa_ll_is_configurable_curve_supported(void) +{ + return true; +} #ifdef __cplusplus } diff --git a/components/hal/esp32h21/include/hal/efuse_hal.h b/components/hal/esp32h21/include/hal/efuse_hal.h index 9064293d34..f18c274657 100644 --- a/components/hal/esp32h21/include/hal/efuse_hal.h +++ b/components/hal/esp32h21/include/hal/efuse_hal.h @@ -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 */ @@ -56,6 +56,13 @@ void efuse_hal_program(uint32_t block); */ void efuse_hal_rs_calculate(const void *data, void *rs_values); +/** + * @brief Get ECDSA curve mode + * + * @return ECDSA curve mode + */ +uint32_t efuse_hal_get_ecdsa_curve_mode(void); + /** * @brief Checks coding error in a block * diff --git a/components/hal/test_apps/crypto/main/Kconfig.projbuild b/components/hal/test_apps/crypto/main/Kconfig.projbuild index 769a4a8944..3e0c441589 100644 --- a/components/hal/test_apps/crypto/main/Kconfig.projbuild +++ b/components/hal/test_apps/crypto/main/Kconfig.projbuild @@ -22,7 +22,7 @@ menu "Test App Configuration" Enabling this option includes HMAC Peripheral related test cases in the build for supported targets. config CRYPTO_TEST_APP_ENABLE_ECDSA_TESTS - depends on !CRYPTO_TEST_APP_ENABLE_HMAC_TESTS + depends on SOC_ECDSA_SUPPORTED && !CRYPTO_TEST_APP_ENABLE_HMAC_TESTS bool "Enable ECDSA Peripheral test cases" default n help diff --git a/components/mbedtls/test_apps/main/test_mbedtls_ecdsa.c b/components/mbedtls/test_apps/main/test_mbedtls_ecdsa.c index 57803b28e9..fe1c11a92f 100644 --- a/components/mbedtls/test_apps/main/test_mbedtls_ecdsa.c +++ b/components/mbedtls/test_apps/main/test_mbedtls_ecdsa.c @@ -29,6 +29,11 @@ #if SOC_KEY_MANAGER_SUPPORTED #include "esp_key_mgr.h" #endif + +#if SOC_ECDSA_SUPPORTED +#include "hal/ecdsa_ll.h" +#endif + #define TEST_ASSERT_MBEDTLS_OK(X) TEST_ASSERT_EQUAL_HEX32(0, -(X)) #if CONFIG_NEWLIB_NANO_FORMAT diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index 9685668843..b1564369b3 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -1331,6 +1331,10 @@ config SOC_ECDSA_USES_MPI bool default y +config SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED + bool + default y + config SOC_UART_NUM int default 2 diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 7ee8c84c1d..f220667269 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -530,6 +530,8 @@ /*------------------------- ECDSA CAPS -------------------------*/ #define SOC_ECDSA_USES_MPI (1) +#define SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED (1) + /*-------------------------- UART CAPS ---------------------------------------*/ // ESP32-H2 has 2 UARTs #define SOC_UART_NUM (2) diff --git a/docs/en/api-reference/peripherals/ecdsa.rst b/docs/en/api-reference/peripherals/ecdsa.rst index b3dbd3b95f..20e400cdcf 100644 --- a/docs/en/api-reference/peripherals/ecdsa.rst +++ b/docs/en/api-reference/peripherals/ecdsa.rst @@ -67,7 +67,11 @@ Following code snippet uses :cpp:func:`esp_efuse_write_key` to set physical key ECDSA Curve Configuration ------------------------- - The ECDSA peripheral of {IDF_TARGET_NAME} supports both ECDSA-P192 and ECDSA-P256 operations, but only ECDSA-P256 operations are enabled by default. You can enable ECDSA-P192 operations through the following configuration options: + .. only:: esp32h2 + The ECDSA peripheral of the ESP32-H2 supports both ECDSA-P192 and ECDSA-P256 operations. However, starting with ESP32-H2 revision 1.2, only ECDSA-P256 operations are enabled by default. You can enable ECDSA-P192 operations using the following configuration options: + + .. only:: not esp32h2 + The ECDSA peripheral of {IDF_TARGET_NAME} supports both ECDSA-P192 and ECDSA-P256 operations, but only ECDSA-P256 operations are enabled by default. You can enable ECDSA-P192 operations through the following configuration options: - :ref:`CONFIG_ESP_ECDSA_ENABLE_P192_CURVE` enables support for ECDSA-P192 curve operations, allowing the device to perform ECDSA operations with both 192-bit and 256-bit curves. However, if ECDSA-P192 operations have already been permanently disabled during eFuse write protection, enabling this option can not re-enable ECDSA-P192 curve operations.