Merge branch 'fix/ecdsa_ecc_hw_input_validation_v6.1' into 'release/v6.1'

Validate ECDSA signature range and harden ECC memory power-down (v6.1)

See merge request espressif/esp-idf!49427
This commit is contained in:
Mahavir Jain
2026-06-10 14:39:49 +05:30
47 changed files with 427 additions and 61 deletions
@@ -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
*/
@@ -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" {
@@ -47,11 +48,17 @@ static inline void ecc_ll_reset_register(void)
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)
{
/* 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_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)
@@ -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)
@@ -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"
#ifdef __cplusplus
extern "C" {
@@ -49,9 +50,10 @@ static inline void ecc_ll_reset_register(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_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)
@@ -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)
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-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" {
@@ -52,6 +53,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)
@@ -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" {
@@ -50,9 +51,11 @@ static inline void ecc_ll_reset_register(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_MEM_LP_CTRL_REG, PCR_ECC_MEM_LP_EN);
REG_CLR_BIT(PCR_ECC_MEM_LP_CTRL_REG, PCR_ECC_MEM_FORCE_CTRL);
REG_SET_BIT(PCR_ECC_MEM_LP_CTRL_REG, PCR_ECC_MEM_FORCE_CTRL);
ESP_FAULT_ASSERT(REG_GET_BIT(PCR_ECC_MEM_LP_CTRL_REG, PCR_ECC_MEM_LP_EN) == 0 &&
REG_GET_BIT(PCR_ECC_MEM_LP_CTRL_REG, PCR_ECC_MEM_FORCE_CTRL) != 0);
}
static inline void ecc_ll_power_down(void)
@@ -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
*/
@@ -12,8 +12,10 @@
#include "hal/efuse_hal.h"
#include "soc/ecc_mult_reg.h"
#include "soc/hp_sys_clkrst_struct.h"
#include "soc/hp_system_reg.h"
#include "soc/chip_revision.h"
#include "hal/config.h"
#include "esp_fault.h"
#ifdef __cplusplus
extern "C" {
@@ -65,8 +67,20 @@ static inline void ecc_ll_reset_register(void)
ecc_ll_reset_register(__VA_ARGS__); \
} while(0)
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)
{
@@ -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" {
@@ -62,8 +64,21 @@ static inline void ecc_ll_reset_register(void)
ecc_ll_reset_register(__VA_ARGS__); \
} while(0)
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_MEM_LP_CTRL_REG, HP_SYSTEM_ECC_MEM_LP_EN);
REG_SET_BIT(HP_SYSTEM_ECC_MEM_LP_CTRL_REG, HP_SYSTEM_ECC_MEM_LP_FORCE_CTRL);
/* Anti-FI: confirm the clears took effect. */
ESP_FAULT_ASSERT(REG_GET_BIT(HP_SYSTEM_ECC_MEM_LP_CTRL_REG, HP_SYSTEM_ECC_MEM_LP_EN) == 0 &&
REG_GET_BIT(HP_SYSTEM_ECC_MEM_LP_CTRL_REG, HP_SYSTEM_ECC_MEM_LP_FORCE_CTRL) != 0);
}
static inline void ecc_ll_power_down(void)
{
/* Power down the ECC peripheral */
REG_SET_BIT(HP_SYSTEM_ECC_MEM_LP_CTRL_REG, HP_SYSTEM_ECC_MEM_LP_EN);
}
static inline void ecc_ll_enable_interrupt(void)
{
@@ -207,6 +207,10 @@ static void test_ecc_point_mul_inner_constant_time(void)
uint32_t max_time = 0, min_time = UINT32_MAX;
int loop_count = 10;
/* Warm-up: the first call is otherwise an I-cache / branch-predictor
* outlier that dominates max_time and thus creating deviations */
ecc_point_mul(scalar_le, x_le, y_le, ECC_P256_SIZE_BYTES, 0, x_res_le, y_res_le);
for (int i = 0; i < loop_count; i++) {
ccomp_timer_start();
ecc_point_mul(scalar_le, x_le, y_le, ECC_P256_SIZE_BYTES, 0, x_res_le, y_res_le);
@@ -230,6 +234,9 @@ static void test_ecc_point_mul_inner_constant_time(void)
min_time = UINT32_MAX;
total_elapsed_time = 0;
/* Warm-up — see comment on the P256 loop. */
ecc_point_mul(scalar_le, x_le, y_le, ECC_P192_SIZE_BYTES, 0, x_res_le, y_res_le);
for (int i = 0; i < loop_count; i++) {
ccomp_timer_start();
ecc_point_mul(scalar_le, x_le, y_le, ECC_P192_SIZE_BYTES, 0, x_res_le, y_res_le);
@@ -255,6 +262,9 @@ static void test_ecc_point_mul_inner_constant_time(void)
min_time = UINT32_MAX;
total_elapsed_time = 0;
/* Warm-up — see comment on the P256 loop. */
ecc_point_mul(scalar_le, x_le, y_le, ECC_P384_SIZE_BYTES, 0, x_res_le, y_res_le);
for (int i = 0; i < loop_count; i++) {
ccomp_timer_start();
ecc_point_mul(scalar_le, x_le, y_le, ECC_P384_SIZE_BYTES, 0, x_res_le, y_res_le);