From 0154c7cfe36a190135a6a721bcd6d1e7f6940329 Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Wed, 7 May 2025 15:42:19 +0530 Subject: [PATCH] fix(mbedtls): Enable signature verification s/w fallback when ECDSA curve is disabled --- components/efuse/esp32h21/esp_efuse_fields.c | 38 ------------- .../efuse/esp32h21/include/esp_efuse_chip.h | 7 --- components/efuse/include/esp_efuse.h | 18 +++++- components/efuse/src/esp_efuse_fields.c | 57 ++++++++++++++++++- .../test_apps/crypto/main/ecdsa/test_ecdsa.c | 25 ++------ components/mbedtls/port/ecdsa/ecdsa_alt.c | 4 +- .../test_apps/main/test_mbedtls_ecdsa.c | 11 +--- 7 files changed, 83 insertions(+), 77 deletions(-) diff --git a/components/efuse/esp32h21/esp_efuse_fields.c b/components/efuse/esp32h21/esp_efuse_fields.c index 69c5862631..e4cb7d9319 100644 --- a/components/efuse/esp32h21/esp_efuse_fields.c +++ b/components/efuse/esp32h21/esp_efuse_fields.c @@ -10,7 +10,6 @@ #include "stdlib.h" #include "esp_types.h" #include "assert.h" -#include "hal/efuse_ll.h" #include "esp_err.h" #include "esp_log.h" #include "soc/efuse_periph.h" @@ -52,40 +51,3 @@ esp_err_t esp_efuse_enable_rom_secure_download_mode(void) } return esp_efuse_write_field_bit(ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD); } - -#if SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED -bool esp_efuse_is_ecdsa_p192_curve_supported(void) -{ - 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); -} - -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; - } - - // 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/efuse/esp32h21/include/esp_efuse_chip.h b/components/efuse/esp32h21/include/esp_efuse_chip.h index 54f59d1cea..a49e32c773 100644 --- a/components/efuse/esp32h21/include/esp_efuse_chip.h +++ b/components/efuse/esp32h21/include/esp_efuse_chip.h @@ -77,13 +77,6 @@ typedef enum { ESP_EFUSE_KEY_PURPOSE_MAX, /**< MAX PURPOSE */ } esp_efuse_purpose_t; -typedef enum { - ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_ONLY_P256_BIT = 0, - ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_ONLY_P192_BIT = 1, - ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_BOTH_P192_P256_BIT = 2, - ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_ONLY_P256_BIT_LOCKED = 3, -} esp_efuse_ecdsa_curve_mode_t; - #ifdef __cplusplus } #endif diff --git a/components/efuse/include/esp_efuse.h b/components/efuse/include/esp_efuse.h index 3673f272ac..d18348fe47 100644 --- a/components/efuse/include/esp_efuse.h +++ b/components/efuse/include/esp_efuse.h @@ -806,7 +806,7 @@ esp_err_t esp_efuse_check_errors(void); */ esp_err_t esp_efuse_destroy_block(esp_efuse_block_t block); -#if SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED +#if SOC_ECDSA_SUPPORTED /** * @brief Checks if 192-bit ECDSA curve operations are supported. * @@ -814,6 +814,22 @@ esp_err_t esp_efuse_destroy_block(esp_efuse_block_t block); */ bool esp_efuse_is_ecdsa_p192_curve_supported(void); +/** + * @brief Checks if 256-bit ECDSA curve operations are supported. + * + * This function checks if the current eFuse configuration supports 256-bit ECDSA curve operations. +*/ +bool esp_efuse_is_ecdsa_p256_curve_supported(void); +#endif /* SOC_ECDSA_SUPPORTED*/ + +#if SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED +typedef enum { + ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_ONLY_P256_BIT = 0, + ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_ONLY_P192_BIT = 1, + ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_BOTH_P192_P256_BIT = 2, + ESP_EFUSE_ECDSA_CURVE_MODE_ALLOW_ONLY_P256_BIT_LOCKED = 3, +} esp_efuse_ecdsa_curve_mode_t; + /** * @brief Enables 192-bit ECDSA curve operations by setting the appropriate eFuse value. * diff --git a/components/efuse/src/esp_efuse_fields.c b/components/efuse/src/esp_efuse_fields.c index 7672c0716f..b20938047b 100644 --- a/components/efuse/src/esp_efuse_fields.c +++ b/components/efuse/src/esp_efuse_fields.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,6 +16,8 @@ #include "esp_log.h" #include "soc/efuse_periph.h" #include "sys/param.h" +#include "soc/soc_caps.h" +#include "hal/efuse_ll.h" static __attribute__((unused)) const char *TAG = "efuse"; @@ -81,3 +83,56 @@ esp_err_t esp_efuse_update_secure_version(uint32_t secure_version) } return ESP_OK; } + +#if SOC_ECDSA_SUPPORTED +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); +#else + return true; +#endif /* SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED */ +} + +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); +#else + return true; +#endif /* SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED */ +} +#endif /* SOC_ECDSA_SUPPORTED */ + +#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; + } + + // 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/test_apps/crypto/main/ecdsa/test_ecdsa.c b/components/hal/test_apps/crypto/main/ecdsa/test_ecdsa.c index 56abd58cb1..ccb870ac04 100644 --- a/components/hal/test_apps/crypto/main/ecdsa/test_ecdsa.c +++ b/components/hal/test_apps/crypto/main/ecdsa/test_ecdsa.c @@ -289,36 +289,27 @@ TEST_TEAR_DOWN(ecdsa) TEST(ecdsa, ecdsa_SECP192R1_signature_verification) { -#if SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED if (!esp_efuse_is_ecdsa_p192_curve_supported()) { ESP_LOGI(TAG, "Skipping test because ECDSA 192-curve operations are disabled."); - } else -#endif - { + } else { TEST_ASSERT_EQUAL(0, test_ecdsa_verify(0, sha, ecdsa192_r, ecdsa192_s, ecdsa192_pub_x, ecdsa192_pub_y)); } } TEST(ecdsa, ecdsa_SECP192R1_sign_and_verify) { -#if SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED if (!esp_efuse_is_ecdsa_p192_curve_supported()) { ESP_LOGI(TAG, "Skipping test because ECDSA 192-curve operations are disabled."); - } else -#endif - { + } else { test_ecdsa_sign_and_verify(0, sha, ecdsa192_pub_x, ecdsa192_pub_y, false, ECDSA_K_TYPE_TRNG); } } TEST(ecdsa, ecdsa_SECP192R1_corrupt_signature) { -#if SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED if (!esp_efuse_is_ecdsa_p192_curve_supported()) { ESP_LOGI(TAG, "Skipping test because ECDSA 192-curve operations are disabled."); - } else -#endif - { + } else { test_ecdsa_corrupt_data(0, sha, ecdsa192_r, ecdsa192_s, ecdsa192_pub_x, ecdsa192_pub_y); } } @@ -341,12 +332,9 @@ TEST(ecdsa, ecdsa_SECP256R1_corrupt_signature) #ifdef SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE TEST(ecdsa, ecdsa_SECP192R1_det_sign_and_verify) { -#if SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED if (!esp_efuse_is_ecdsa_p192_curve_supported()) { ESP_LOGI(TAG, "Skipping test because ECDSA 192-curve operations are disabled."); - } else -#endif - { + } else { test_ecdsa_sign_and_verify(0, sha, ecdsa192_pub_x, ecdsa192_pub_y, false, ECDSA_K_TYPE_DETERMINISITIC); } } @@ -360,12 +348,9 @@ TEST(ecdsa, ecdsa_SECP256R1_det_sign_and_verify) #ifdef SOC_ECDSA_SUPPORT_EXPORT_PUBKEY TEST(ecdsa, ecdsa_SECP192R1_export_pubkey) { -#if SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED if (!esp_efuse_is_ecdsa_p192_curve_supported()) { ESP_LOGI(TAG, "Skipping test because ECDSA 192-curve operations are disabled."); - } else -#endif - { + } else { test_ecdsa_export_pubkey(0, ecdsa192_pub_x, ecdsa192_pub_y, 0); } } diff --git a/components/mbedtls/port/ecdsa/ecdsa_alt.c b/components/mbedtls/port/ecdsa/ecdsa_alt.c index e31a46f527..fe61d2468f 100644 --- a/components/mbedtls/port/ecdsa/ecdsa_alt.c +++ b/components/mbedtls/port/ecdsa/ecdsa_alt.c @@ -911,7 +911,9 @@ int __wrap_mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp, const mbedtls_mpi *s, mbedtls_ecdsa_restart_ctx *rs_ctx) { - if ((grp->id == MBEDTLS_ECP_DP_SECP192R1 || grp->id == MBEDTLS_ECP_DP_SECP256R1) && blen == ECDSA_SHA_LEN) { + if (((grp->id == MBEDTLS_ECP_DP_SECP192R1 && esp_efuse_is_ecdsa_p192_curve_supported()) + || (grp->id == MBEDTLS_ECP_DP_SECP256R1 && esp_efuse_is_ecdsa_p256_curve_supported())) + && blen == ECDSA_SHA_LEN) { return esp_ecdsa_verify(grp, buf, blen, Q, r, s); } else { return __real_mbedtls_ecdsa_verify_restartable(grp, buf, blen, Q, r, s, rs_ctx); diff --git a/components/mbedtls/test_apps/main/test_mbedtls_ecdsa.c b/components/mbedtls/test_apps/main/test_mbedtls_ecdsa.c index 5d0afc169a..57803b28e9 100644 --- a/components/mbedtls/test_apps/main/test_mbedtls_ecdsa.c +++ b/components/mbedtls/test_apps/main/test_mbedtls_ecdsa.c @@ -146,15 +146,8 @@ void test_ecdsa_verify(mbedtls_ecp_group_id id, const uint8_t *hash, const uint8 TEST_CASE("mbedtls ECDSA signature verification performance on SECP192R1", "[mbedtls]") { -#if SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED - if (!esp_efuse_is_ecdsa_p192_curve_supported()) { - ESP_LOGI(TAG, "Skipping test because ECDSA 192-curve operations are disabled."); - } else -#endif - { - test_ecdsa_verify(MBEDTLS_ECP_DP_SECP192R1, sha, ecdsa192_r, ecdsa192_s, - ecdsa192_pub_x, ecdsa192_pub_y); - } + test_ecdsa_verify(MBEDTLS_ECP_DP_SECP192R1, sha, ecdsa192_r, ecdsa192_s, + ecdsa192_pub_x, ecdsa192_pub_y); } TEST_CASE("mbedtls ECDSA signature verification performance on SECP256R1", "[mbedtls]")