fix(mbedtls): validate ECDSA signature range and harden ECC memory power-down

Co-Authored-By: Ashish Sharma <ashish.sharma@espressif.com>
This commit is contained in:
harshal.patil
2026-06-12 16:54:33 +05:30
co-authored by Ashish Sharma
parent dfe53e2090
commit 483c51b3c8
11 changed files with 56 additions and 11 deletions
@@ -99,6 +99,7 @@ void esp_system_reset_modules_on_exit(void)
CLEAR_PERI_REG_MASK(PCR_RSA_CONF_REG, PCR_RSA_RST_EN); CLEAR_PERI_REG_MASK(PCR_RSA_CONF_REG, PCR_RSA_RST_EN);
SET_PERI_REG_MASK(PCR_SHA_CONF_REG, PCR_SHA_RST_EN); SET_PERI_REG_MASK(PCR_SHA_CONF_REG, PCR_SHA_RST_EN);
CLEAR_PERI_REG_MASK(PCR_SHA_CONF_REG, PCR_SHA_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);
// UART's sclk is controlled in the PCR register and does not reset with the UART module. The ROM missed enabling // UART's sclk is controlled in the PCR register and does not reset with the UART module. The ROM missed enabling
// it when initializing the ROM UART. If it is not turned on, it will trigger LP_WDT in the ROM. // it when initializing the ROM UART. If it is not turned on, it will trigger LP_WDT in the ROM.
@@ -80,6 +80,8 @@ void esp_system_reset_modules_on_exit(void)
CLEAR_PERI_REG_MASK(PCR_HMAC_CONF_REG, PCR_HMAC_RST_EN); 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_RSA_CONF_REG, PCR_RSA_RST_EN);
CLEAR_PERI_REG_MASK(PCR_SHA_CONF_REG, PCR_SHA_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); CLEAR_PERI_REG_MASK(PCR_REGDMA_CONF_REG, PCR_REGDMA_RST_EN);
// UART's sclk is controlled in the PCR register and does not reset with the UART module. The ROM missed enabling // UART's sclk is controlled in the PCR register and does not reset with the UART module. The ROM missed enabling
@@ -97,6 +97,7 @@ void esp_system_reset_modules_on_exit(void)
CLEAR_PERI_REG_MASK(PCR_RSA_CONF_REG, PCR_RSA_RST_EN); CLEAR_PERI_REG_MASK(PCR_RSA_CONF_REG, PCR_RSA_RST_EN);
SET_PERI_REG_MASK(PCR_SHA_CONF_REG, PCR_SHA_RST_EN); SET_PERI_REG_MASK(PCR_SHA_CONF_REG, PCR_SHA_RST_EN);
CLEAR_PERI_REG_MASK(PCR_SHA_CONF_REG, PCR_SHA_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);
// UART's sclk is controlled in the PCR register and does not reset with the UART module. The ROM missed enabling // UART's sclk is controlled in the PCR register and does not reset with the UART module. The ROM missed enabling
// it when initializing the ROM UART. If it is not turned on, it will trigger LP_WDT in the ROM. // it when initializing the ROM UART. If it is not turned on, it will trigger LP_WDT in the ROM.
@@ -79,6 +79,7 @@ void esp_system_reset_modules_on_exit(void)
CLEAR_PERI_REG_MASK(PCR_HMAC_CONF_REG, PCR_HMAC_RST_EN); 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_RSA_CONF_REG, PCR_RSA_RST_EN);
CLEAR_PERI_REG_MASK(PCR_SHA_CONF_REG, PCR_SHA_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);
// UART's sclk is controlled in the PCR register and does not reset with the UART module. The ROM missed enabling // UART's sclk is controlled in the PCR register and does not reset with the UART module. The ROM missed enabling
// it when initializing the ROM UART. If it is not turned on, it will trigger LP_WDT in the ROM. // it when initializing the ROM UART. If it is not turned on, it will trigger LP_WDT in the ROM.
@@ -127,6 +127,7 @@ void 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_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_RSA);
CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN2_REG, HP_SYS_CLKRST_REG_RST_EN_SHA); 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 < 101 #if CONFIG_ESP32P4_REV_MIN_FULL < 101
if (efuse_hal_chip_revision() < 101) { if (efuse_hal_chip_revision() < 101) {
+8 -1
View File
@@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -12,6 +12,7 @@
#include "soc/ecc_mult_reg.h" #include "soc/ecc_mult_reg.h"
#include "soc/pcr_struct.h" #include "soc/pcr_struct.h"
#include "soc/pcr_reg.h" #include "soc/pcr_reg.h"
#include "esp_fault.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@@ -47,11 +48,17 @@ static inline void ecc_ll_reset_register(void)
PCR.ecdsa_conf.ecdsa_rst_en = 0; PCR.ecdsa_conf.ecdsa_rst_en = 0;
} }
static inline void ecc_ll_clear_force_pd(void)
{
REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_PD);
}
static inline void ecc_ll_power_up(void) static inline void ecc_ll_power_up(void)
{ {
/* Power up the ECC peripheral (default state is power-down) */ /* Power up the ECC peripheral (default state is power-down) */
REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_PD); 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); 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) static inline void ecc_ll_power_down(void)
+3 -1
View File
@@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -12,6 +12,7 @@
#include "soc/ecc_mult_reg.h" #include "soc/ecc_mult_reg.h"
#include "soc/pcr_struct.h" #include "soc/pcr_struct.h"
#include "soc/pcr_reg.h" #include "soc/pcr_reg.h"
#include "esp_fault.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { 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_PD);
REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_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) static inline void ecc_ll_power_down(void)
+4 -2
View File
@@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -12,6 +12,7 @@
#include "soc/ecc_mult_reg.h" #include "soc/ecc_mult_reg.h"
#include "soc/pcr_struct.h" #include "soc/pcr_struct.h"
#include "soc/pcr_reg.h" #include "soc/pcr_reg.h"
#include "esp_fault.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@@ -49,9 +50,10 @@ static inline void ecc_ll_reset_register(void)
static inline void ecc_ll_power_up(void) static inline void ecc_ll_power_up(void)
{ {
/* Power up the ECC peripheral (default state is power-down) */ /* Power up the ECC peripheral (default state is power-up) */
REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_PD); 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); 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) static inline void ecc_ll_power_down(void)
+3 -1
View File
@@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -12,6 +12,7 @@
#include "soc/ecc_mult_reg.h" #include "soc/ecc_mult_reg.h"
#include "soc/pcr_struct.h" #include "soc/pcr_struct.h"
#include "soc/pcr_reg.h" #include "soc/pcr_reg.h"
#include "esp_fault.h"
#include "soc/chip_revision.h" #include "soc/chip_revision.h"
#include "hal/efuse_hal.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_PD);
REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_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) static inline void ecc_ll_power_down(void)
+17 -3
View File
@@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -12,8 +12,10 @@
#include "hal/efuse_hal.h" #include "hal/efuse_hal.h"
#include "soc/ecc_mult_reg.h" #include "soc/ecc_mult_reg.h"
#include "soc/hp_sys_clkrst_struct.h" #include "soc/hp_sys_clkrst_struct.h"
#include "soc/hp_system_reg.h"
#include "soc/chip_revision.h" #include "soc/chip_revision.h"
#include "hal/config.h" #include "hal/config.h"
#include "esp_fault.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@@ -59,8 +61,20 @@ static inline void ecc_ll_reset_register(void)
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance /// 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__) #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_up(void)
static inline void ecc_ll_power_down(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) static inline void ecc_ll_enable_interrupt(void)
{ {
+15 -3
View File
@@ -7,6 +7,7 @@
#include "esp_err.h" #include "esp_err.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_fault.h"
#include "hal/ecdsa_types.h" #include "hal/ecdsa_types.h"
#include "ecdsa/ecdsa_alt.h" #include "ecdsa/ecdsa_alt.h"
@@ -1080,11 +1081,22 @@ static int esp_ecdsa_verify(mbedtls_ecp_group *grp,
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
} }
if (mbedtls_mpi_cmp_int(r, 1) < 0 || mbedtls_mpi_cmp_mpi(r, &grp->N) >= 0 || /* 1 <= scalar <= n-1: that is, scalar > 0 and scalar < n. */
mbedtls_mpi_cmp_int(s, 1) < 0 || mbedtls_mpi_cmp_mpi(s, &grp->N) >= 0 ) #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; 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); ecdsa_be_to_le(buf, sha_le, len);