From 85055fabfff66b5f0b695acd035d66e702e00a2f Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Fri, 12 Jun 2026 17:07:33 +0530 Subject: [PATCH] fix(mbedtls): validate ECDSA signature range and harden ECC memory power-down Co-Authored-By: Ashish Sharma --- .../port/soc/esp32c6/system_internal.c | 2 ++ .../port/soc/esp32h2/system_internal.c | 1 + .../port/soc/esp32p4/system_internal.c | 1 + components/hal/esp32c6/include/hal/ecc_ll.h | 4 +++- components/hal/esp32h2/include/hal/ecc_ll.h | 4 +++- components/hal/esp32p4/include/hal/ecc_ll.h | 20 ++++++++++++++++--- components/mbedtls/port/ecdsa/ecdsa_alt.c | 20 +++++++++++++++---- 7 files changed, 43 insertions(+), 9 deletions(-) diff --git a/components/esp_system/port/soc/esp32c6/system_internal.c b/components/esp_system/port/soc/esp32c6/system_internal.c index c74f1d0c3d5..b0bdc935c23 100644 --- a/components/esp_system/port/soc/esp32c6/system_internal.c +++ b/components/esp_system/port/soc/esp32c6/system_internal.c @@ -78,6 +78,8 @@ void IRAM_ATTR esp_system_reset_modules_on_exit(void) CLEAR_PERI_REG_MASK(PCR_HMAC_CONF_REG, PCR_HMAC_RST_EN); CLEAR_PERI_REG_MASK(PCR_RSA_CONF_REG, PCR_RSA_RST_EN); CLEAR_PERI_REG_MASK(PCR_SHA_CONF_REG, PCR_SHA_RST_EN); + CLEAR_PERI_REG_MASK(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_PD); + CLEAR_PERI_REG_MASK(PCR_REGDMA_CONF_REG, PCR_REGDMA_RST_EN); } diff --git a/components/esp_system/port/soc/esp32h2/system_internal.c b/components/esp_system/port/soc/esp32h2/system_internal.c index 09e920b16b2..cbe5393f248 100644 --- a/components/esp_system/port/soc/esp32h2/system_internal.c +++ b/components/esp_system/port/soc/esp32h2/system_internal.c @@ -77,6 +77,7 @@ void IRAM_ATTR esp_system_reset_modules_on_exit(void) CLEAR_PERI_REG_MASK(PCR_HMAC_CONF_REG, PCR_HMAC_RST_EN); CLEAR_PERI_REG_MASK(PCR_RSA_CONF_REG, PCR_RSA_RST_EN); CLEAR_PERI_REG_MASK(PCR_SHA_CONF_REG, PCR_SHA_RST_EN); + CLEAR_PERI_REG_MASK(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_PD); } /* "inner" restart function for after RTOS, interrupts & anything else on this diff --git a/components/esp_system/port/soc/esp32p4/system_internal.c b/components/esp_system/port/soc/esp32p4/system_internal.c index 98e669d0360..c80cfffbdff 100644 --- a/components/esp_system/port/soc/esp32p4/system_internal.c +++ b/components/esp_system/port/soc/esp32p4/system_internal.c @@ -121,6 +121,7 @@ void IRAM_ATTR esp_system_reset_modules_on_exit(void) CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN2_REG, HP_SYS_CLKRST_REG_RST_EN_KM); CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN2_REG, HP_SYS_CLKRST_REG_RST_EN_RSA); CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN2_REG, HP_SYS_CLKRST_REG_RST_EN_SHA); + CLEAR_PERI_REG_MASK(HP_SYSTEM_ECC_PD_CTRL_REG, HP_SYSTEM_ECC_MEM_FORCE_PD); #if CONFIG_ESP32P4_REV_MIN_FULL <= 100 // enable soc clk and reset parent crypto diff --git a/components/hal/esp32c6/include/hal/ecc_ll.h b/components/hal/esp32c6/include/hal/ecc_ll.h index d144dbff297..fc0861b3148 100644 --- a/components/hal/esp32c6/include/hal/ecc_ll.h +++ b/components/hal/esp32c6/include/hal/ecc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,7 @@ #include "soc/ecc_mult_reg.h" #include "soc/pcr_struct.h" #include "soc/pcr_reg.h" +#include "esp_fault.h" #ifdef __cplusplus extern "C" { @@ -46,6 +47,7 @@ static inline void ecc_ll_power_up(void) { REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_PD); REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_PD); + ESP_FAULT_ASSERT(REG_GET_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_PD) == 0); } static inline void ecc_ll_power_down(void) diff --git a/components/hal/esp32h2/include/hal/ecc_ll.h b/components/hal/esp32h2/include/hal/ecc_ll.h index c57200f6273..9db578ed305 100644 --- a/components/hal/esp32h2/include/hal/ecc_ll.h +++ b/components/hal/esp32h2/include/hal/ecc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,7 @@ #include "soc/ecc_mult_reg.h" #include "soc/pcr_struct.h" #include "soc/pcr_reg.h" +#include "esp_fault.h" #include "soc/chip_revision.h" #include "hal/efuse_hal.h" @@ -54,6 +55,7 @@ static inline void ecc_ll_power_up(void) { REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_PD); REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_PD); + ESP_FAULT_ASSERT(REG_GET_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_PD) == 0); } static inline void ecc_ll_power_down(void) diff --git a/components/hal/esp32p4/include/hal/ecc_ll.h b/components/hal/esp32p4/include/hal/ecc_ll.h index 76ed61084eb..12ce58fd276 100644 --- a/components/hal/esp32p4/include/hal/ecc_ll.h +++ b/components/hal/esp32p4/include/hal/ecc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,8 @@ #include "hal/ecc_types.h" #include "soc/ecc_mult_reg.h" #include "soc/hp_sys_clkrst_struct.h" +#include "soc/hp_system_reg.h" +#include "esp_fault.h" #ifdef __cplusplus extern "C" { @@ -56,8 +58,20 @@ static inline void ecc_ll_reset_register(void) /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance #define ecc_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; ecc_ll_reset_register(__VA_ARGS__) -static inline void ecc_ll_power_up(void) {} -static inline void ecc_ll_power_down(void) {} +static inline void ecc_ll_power_up(void) +{ + /* Power up the ECC peripheral (default state is power-up) */ + REG_CLR_BIT(HP_SYSTEM_ECC_PD_CTRL_REG, HP_SYSTEM_ECC_MEM_PD); + REG_CLR_BIT(HP_SYSTEM_ECC_PD_CTRL_REG, HP_SYSTEM_ECC_MEM_FORCE_PD); + ESP_FAULT_ASSERT(REG_GET_BIT(HP_SYSTEM_ECC_PD_CTRL_REG, HP_SYSTEM_ECC_MEM_FORCE_PD) == 0); +} + +static inline void ecc_ll_power_down(void) +{ + /* Power down the ECC peripheral */ + REG_CLR_BIT(HP_SYSTEM_ECC_PD_CTRL_REG, HP_SYSTEM_ECC_MEM_FORCE_PU); + REG_SET_BIT(HP_SYSTEM_ECC_PD_CTRL_REG, HP_SYSTEM_ECC_MEM_PD); +} static inline void ecc_ll_enable_interrupt(void) { diff --git a/components/mbedtls/port/ecdsa/ecdsa_alt.c b/components/mbedtls/port/ecdsa/ecdsa_alt.c index a083a96170a..2b8e622dd46 100644 --- a/components/mbedtls/port/ecdsa/ecdsa_alt.c +++ b/components/mbedtls/port/ecdsa/ecdsa_alt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,7 @@ #include "hal/ecdsa_hal.h" #include "hal/mpi_ll.h" #include "esp_crypto_lock.h" +#include "esp_fault.h" #include "esp_efuse.h" #include "esp_private/esp_crypto_lock_internal.h" #include "mbedtls/error.h" @@ -679,11 +680,22 @@ static int esp_ecdsa_verify(mbedtls_ecp_group *grp, return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } - if (mbedtls_mpi_cmp_int(r, 1) < 0 || mbedtls_mpi_cmp_mpi(r, &grp->N) >= 0 || - mbedtls_mpi_cmp_int(s, 1) < 0 || mbedtls_mpi_cmp_mpi(s, &grp->N) >= 0 ) - { + /* 1 <= scalar <= n-1: that is, scalar > 0 and scalar < n. */ + #define RANGE_OK 0x6A6A6A6AU + #define RANGE_FAIL 0x95959595U + volatile uint32_t verdict = RANGE_FAIL; + if (mbedtls_mpi_cmp_int(r, 0) > 0 && + mbedtls_mpi_cmp_mpi(r, &grp->N) < 0 && + mbedtls_mpi_cmp_int(s, 0) > 0 && + mbedtls_mpi_cmp_mpi(s, &grp->N) < 0) { + verdict = RANGE_OK; + } + if (verdict != RANGE_OK) { return MBEDTLS_ERR_ECP_VERIFY_FAILED; } + ESP_FAULT_ASSERT(verdict == RANGE_OK); + #undef RANGE_OK + #undef RANGE_FAIL ecdsa_be_to_le(buf, sha_le, len);