mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 10:47:19 +02:00
feat(ecc): enable ECC constant time mode for ESP32-H2 ECO5
This commit is contained in:
committed by
Aditya Patwardhan
parent
d4bb0e2aa3
commit
e97c51ea24
@ -95,6 +95,19 @@ static esp_err_t init_efuse_secure(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_ESP_CRYPTO_FORCE_ECC_CONSTANT_TIME_POINT_MUL
|
||||||
|
bool force_constant_time = true;
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102)) {
|
||||||
|
force_constant_time = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!esp_efuse_read_field_bit(ESP_EFUSE_ECC_FORCE_CONST_TIME) && force_constant_time) {
|
||||||
|
ESP_EARLY_LOGD(TAG, "Forcefully enabling ECC constant time operations");
|
||||||
|
ESP_RETURN_ON_ERROR(esp_efuse_write_field_bit(ESP_EFUSE_ECC_FORCE_CONST_TIME), TAG, "Failed to enable ECC constant time operations");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_SECURE_DISABLE_ROM_DL_MODE
|
#if CONFIG_SECURE_DISABLE_ROM_DL_MODE
|
||||||
// Permanently disable ROM download mode
|
// Permanently disable ROM download mode
|
||||||
ESP_RETURN_ON_ERROR(esp_efuse_disable_rom_download_mode(), TAG, "Failed to disable ROM download mode");
|
ESP_RETURN_ON_ERROR(esp_efuse_disable_rom_download_mode(), TAG, "Failed to disable ROM download mode");
|
||||||
|
@ -325,6 +325,20 @@ menu "Hardware Settings"
|
|||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
|
config ESP_CRYPTO_FORCE_ECC_CONSTANT_TIME_POINT_MUL
|
||||||
|
bool "Forcefully enable ECC constant time point multiplication operations"
|
||||||
|
depends on SOC_ECC_CONSTANT_TIME_POINT_MUL
|
||||||
|
default N
|
||||||
|
help
|
||||||
|
If enabled, the app startup code will burn the ECC_FORCE_CONST_TIME efuse bit to force the
|
||||||
|
ECC peripheral to always perform constant time point multiplication operations,
|
||||||
|
irrespective of the ECC_MULT_SECURITY_MODE status bit that is present in the ECC_MULT_CONF_REG
|
||||||
|
register. By default, ESP-IDF configures the ECC peripheral to perform constant time point
|
||||||
|
multiplication operations, so enabling this config would provide security enhancement only in
|
||||||
|
the cases when trusted boot is not enabled and the attacker tries carrying out non-constant
|
||||||
|
time point multiplication operations by changing the default ESP-IDF configurations.
|
||||||
|
Performing constant time operations protect the ECC multiplication operations from timing attacks.
|
||||||
|
|
||||||
orsource "./port/$IDF_TARGET/Kconfig.dcdc"
|
orsource "./port/$IDF_TARGET/Kconfig.dcdc"
|
||||||
|
|
||||||
orsource "./port/$IDF_TARGET/Kconfig.ldo"
|
orsource "./port/$IDF_TARGET/Kconfig.ldo"
|
||||||
|
@ -15,6 +15,8 @@ choice ESP32H2_REV_MIN
|
|||||||
bool "Rev v0.1 (ECO1)"
|
bool "Rev v0.1 (ECO1)"
|
||||||
config ESP32H2_REV_MIN_2
|
config ESP32H2_REV_MIN_2
|
||||||
bool "Rev v0.2 (ECO2)"
|
bool "Rev v0.2 (ECO2)"
|
||||||
|
config ESP32H2_REV_MIN_102
|
||||||
|
bool "Rev v1.2 (ECO5)"
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
config ESP32H2_REV_MIN_FULL
|
config ESP32H2_REV_MIN_FULL
|
||||||
@ -22,6 +24,7 @@ config ESP32H2_REV_MIN_FULL
|
|||||||
default 0 if ESP32H2_REV_MIN_0
|
default 0 if ESP32H2_REV_MIN_0
|
||||||
default 1 if ESP32H2_REV_MIN_1
|
default 1 if ESP32H2_REV_MIN_1
|
||||||
default 2 if ESP32H2_REV_MIN_2
|
default 2 if ESP32H2_REV_MIN_2
|
||||||
|
default 102 if ESP32H2_REV_MIN_102
|
||||||
|
|
||||||
config ESP_REV_MIN_FULL
|
config ESP_REV_MIN_FULL
|
||||||
int
|
int
|
||||||
@ -31,7 +34,7 @@ config ESP_REV_MIN_FULL
|
|||||||
# MAX Revision
|
# MAX Revision
|
||||||
#
|
#
|
||||||
|
|
||||||
comment "Maximum Supported ESP32-H2 Revision (Rev v0.99)"
|
comment "Maximum Supported ESP32-H2 Revision (Rev v1.99)"
|
||||||
# Maximum revision that IDF supports.
|
# Maximum revision that IDF supports.
|
||||||
# It can not be changed by user.
|
# It can not be changed by user.
|
||||||
# Only Espressif can change it when a new version will be supported in IDF.
|
# Only Espressif can change it when a new version will be supported in IDF.
|
||||||
|
@ -105,8 +105,8 @@ menu "Hardware Abstraction Layer (HAL) and Low Level (LL)"
|
|||||||
|
|
||||||
config HAL_ECDSA_GEN_SIG_CM
|
config HAL_ECDSA_GEN_SIG_CM
|
||||||
bool "Enable countermeasure for ECDSA signature generation"
|
bool "Enable countermeasure for ECDSA signature generation"
|
||||||
|
depends on IDF_TARGET_ESP32H2 && ESP32H2_REV_MIN_FULL < 102
|
||||||
default n
|
default n
|
||||||
# ToDo - IDF-11051
|
|
||||||
help
|
help
|
||||||
Enable this option to apply the countermeasure for ECDSA signature operation
|
Enable this option to apply the countermeasure for ECDSA signature operation
|
||||||
This countermeasure masks the real ECDSA sign operation
|
This countermeasure masks the real ECDSA sign operation
|
||||||
|
@ -177,3 +177,8 @@ int ecc_hal_read_mod_op_result(uint8_t *r, uint16_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SOC_ECC_EXTENDED_MODES_SUPPORTED */
|
#endif /* SOC_ECC_EXTENDED_MODES_SUPPORTED */
|
||||||
|
|
||||||
|
void ecc_hal_enable_constant_time_point_mul(bool enable)
|
||||||
|
{
|
||||||
|
ecc_ll_enable_constant_time_point_mul(enable);
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -171,6 +171,12 @@ static inline void ecc_ll_read_param(ecc_ll_param_t param, uint8_t *buf, uint16_
|
|||||||
memcpy(buf, (void *)reg, len);
|
memcpy(buf, (void *)reg, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void ecc_ll_enable_constant_time_point_mul(bool enable)
|
||||||
|
{
|
||||||
|
// Not supported for ESP32-C2
|
||||||
|
(void) enable; //unused
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -173,6 +173,12 @@ static inline void ecc_ll_read_param(ecc_ll_param_t param, uint8_t *buf, uint16_
|
|||||||
memcpy(buf, (void *)reg, len);
|
memcpy(buf, (void *)reg, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void ecc_ll_enable_constant_time_point_mul(bool enable)
|
||||||
|
{
|
||||||
|
// Not supported for ESP32-C6
|
||||||
|
(void) enable; //unused
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
#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 "soc/chip_revision.h"
|
||||||
|
#include "hal/efuse_ll.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -211,6 +213,18 @@ static inline ecc_mod_base_t ecc_ll_get_mod_base(void)
|
|||||||
return (ecc_mod_base_t)(REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_MOD_BASE));
|
return (ecc_mod_base_t)(REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_MOD_BASE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void ecc_ll_enable_constant_time_point_mul(bool enable)
|
||||||
|
{
|
||||||
|
// ECC constant time point multiplication is supported only on rev 1.2 and above
|
||||||
|
if ((efuse_ll_get_chip_wafer_version_major() >= 1) && (efuse_ll_get_chip_wafer_version_minor() >= 2)) {
|
||||||
|
if (enable) {
|
||||||
|
REG_SET_BIT(ECC_MULT_CONF_REG, ECC_MULT_SECURITY_MODE);
|
||||||
|
} else {
|
||||||
|
REG_CLR_BIT(ECC_MULT_CONF_REG, ECC_MULT_SECURITY_MODE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline void ecc_ll_read_param(ecc_ll_param_t param, uint8_t *buf, uint16_t len)
|
static inline void ecc_ll_read_param(ecc_ll_param_t param, uint8_t *buf, uint16_t len)
|
||||||
{
|
{
|
||||||
uint32_t reg;
|
uint32_t reg;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -240,6 +240,12 @@ static inline void ecc_ll_read_param(ecc_ll_param_t param, uint8_t *buf, uint16_
|
|||||||
memcpy(buf, (void *)reg, len);
|
memcpy(buf, (void *)reg, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void ecc_ll_enable_constant_time_point_mul(bool enable)
|
||||||
|
{
|
||||||
|
// Not supported for ESP32-P4
|
||||||
|
(void) enable; //unused
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -195,6 +195,13 @@ int ecc_hal_read_mod_op_result(uint8_t *r, uint16_t len);
|
|||||||
|
|
||||||
#endif /* SOC_ECC_EXTENDED_MODES_SUPPORTED */
|
#endif /* SOC_ECC_EXTENDED_MODES_SUPPORTED */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable constant time multiplication operations
|
||||||
|
*
|
||||||
|
* @param true: enable; false: disable
|
||||||
|
*/
|
||||||
|
void ecc_hal_enable_constant_time_point_mul(bool enable);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -86,6 +86,7 @@ static void ecc_point_mul(const uint8_t *k_le, const uint8_t *x_le, const uint8_
|
|||||||
} else {
|
} else {
|
||||||
ecc_hal_set_mode(ECC_MODE_POINT_MUL);
|
ecc_hal_set_mode(ECC_MODE_POINT_MUL);
|
||||||
}
|
}
|
||||||
|
ecc_hal_enable_constant_time_point_mul(true);
|
||||||
ecc_hal_start_calc();
|
ecc_hal_start_calc();
|
||||||
|
|
||||||
while (!ecc_hal_is_calc_finished()) {
|
while (!ecc_hal_is_calc_finished()) {
|
||||||
@ -160,6 +161,74 @@ TEST(ecc, ecc_point_multiplication_on_SECP192R1_and_SECP256R1)
|
|||||||
{
|
{
|
||||||
test_ecc_point_mul_inner(false);
|
test_ecc_point_mul_inner(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SOC_ECC_CONSTANT_TIME_POINT_MUL || (CONFIG_IDF_TARGET_ESP32H2 && CONFIG_ESP32H2_REV_MIN_FULL >= 102)
|
||||||
|
|
||||||
|
#define CONST_TIME_DEVIATION_PERCENT 0.002
|
||||||
|
|
||||||
|
static void test_ecc_point_mul_inner_constant_time(void)
|
||||||
|
{
|
||||||
|
uint8_t scalar_le[32];
|
||||||
|
uint8_t x_le[32];
|
||||||
|
uint8_t y_le[32];
|
||||||
|
|
||||||
|
/* P256 */
|
||||||
|
ecc_be_to_le(ecc_p256_scalar, scalar_le, 32);
|
||||||
|
ecc_be_to_le(ecc_p256_point_x, x_le, 32);
|
||||||
|
ecc_be_to_le(ecc_p256_point_y, y_le, 32);
|
||||||
|
|
||||||
|
uint8_t x_res_le[32];
|
||||||
|
uint8_t y_res_le[32];
|
||||||
|
|
||||||
|
double deviation = 0;
|
||||||
|
uint32_t elapsed_time, mean_elapsed_time, total_elapsed_time = 0;
|
||||||
|
uint32_t max_time = 0, min_time = UINT32_MAX;
|
||||||
|
int loop_count = 10;
|
||||||
|
|
||||||
|
for (int i = 0; i < loop_count; i++) {
|
||||||
|
ccomp_timer_start();
|
||||||
|
ecc_point_mul(scalar_le, x_le, y_le, 32, 0, x_res_le, y_res_le);
|
||||||
|
elapsed_time = ccomp_timer_stop();
|
||||||
|
|
||||||
|
max_time = MAX(elapsed_time, max_time);
|
||||||
|
min_time = MIN(elapsed_time, min_time);
|
||||||
|
total_elapsed_time += elapsed_time;
|
||||||
|
}
|
||||||
|
mean_elapsed_time = total_elapsed_time / loop_count;
|
||||||
|
deviation = ((double)(max_time - mean_elapsed_time) / mean_elapsed_time);
|
||||||
|
|
||||||
|
TEST_ASSERT_LESS_THAN_DOUBLE(CONST_TIME_DEVIATION_PERCENT, deviation);
|
||||||
|
|
||||||
|
/* P192 */
|
||||||
|
ecc_be_to_le(ecc_p192_scalar, scalar_le, 24);
|
||||||
|
ecc_be_to_le(ecc_p192_point_x, x_le, 24);
|
||||||
|
ecc_be_to_le(ecc_p192_point_y, y_le, 24);
|
||||||
|
|
||||||
|
max_time = 0;
|
||||||
|
min_time = UINT32_MAX;
|
||||||
|
total_elapsed_time = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < loop_count; i++) {
|
||||||
|
ccomp_timer_start();
|
||||||
|
ecc_point_mul(scalar_le, x_le, y_le, 24, 0, x_res_le, y_res_le);
|
||||||
|
elapsed_time = ccomp_timer_stop();
|
||||||
|
|
||||||
|
max_time = MAX(elapsed_time, max_time);
|
||||||
|
min_time = MIN(elapsed_time, min_time);
|
||||||
|
total_elapsed_time += elapsed_time;
|
||||||
|
}
|
||||||
|
mean_elapsed_time = total_elapsed_time / loop_count;
|
||||||
|
deviation = ((double)(max_time - mean_elapsed_time) / mean_elapsed_time);
|
||||||
|
|
||||||
|
TEST_ASSERT_LESS_THAN_DOUBLE(CONST_TIME_DEVIATION_PERCENT, deviation);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ecc, ecc_point_multiplication_const_time_check_on_SECP192R1_and_SECP256R1)
|
||||||
|
{
|
||||||
|
test_ecc_point_mul_inner_constant_time();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SOC_ECC_SUPPORT_POINT_VERIFY && !defined(SOC_ECC_SUPPORT_POINT_VERIFY_QUIRK)
|
#if SOC_ECC_SUPPORT_POINT_VERIFY && !defined(SOC_ECC_SUPPORT_POINT_VERIFY_QUIRK)
|
||||||
@ -493,6 +562,9 @@ TEST_GROUP_RUNNER(ecc)
|
|||||||
{
|
{
|
||||||
#if SOC_ECC_SUPPORT_POINT_MULT
|
#if SOC_ECC_SUPPORT_POINT_MULT
|
||||||
RUN_TEST_CASE(ecc, ecc_point_multiplication_on_SECP192R1_and_SECP256R1);
|
RUN_TEST_CASE(ecc, ecc_point_multiplication_on_SECP192R1_and_SECP256R1);
|
||||||
|
#if SOC_ECC_CONSTANT_TIME_POINT_MUL || (CONFIG_IDF_TARGET_ESP32H2 && CONFIG_ESP32H2_REV_MIN_FULL >= 102)
|
||||||
|
RUN_TEST_CASE(ecc, ecc_point_multiplication_const_time_check_on_SECP192R1_and_SECP256R1);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SOC_ECC_SUPPORT_POINT_VERIFY && !defined(SOC_ECC_SUPPORT_POINT_VERIFY_QUIRK)
|
#if SOC_ECC_SUPPORT_POINT_VERIFY && !defined(SOC_ECC_SUPPORT_POINT_VERIFY_QUIRK)
|
||||||
|
@ -586,11 +586,10 @@ menu "mbedTLS"
|
|||||||
|
|
||||||
menu "Enable Software Countermeasure for ECDSA signing using on-chip ECDSA peripheral"
|
menu "Enable Software Countermeasure for ECDSA signing using on-chip ECDSA peripheral"
|
||||||
depends on MBEDTLS_HARDWARE_ECDSA_SIGN
|
depends on MBEDTLS_HARDWARE_ECDSA_SIGN
|
||||||
depends on IDF_TARGET_ESP32H2
|
depends on IDF_TARGET_ESP32H2 && ESP32H2_REV_MIN_FULL < 102
|
||||||
config MBEDTLS_HARDWARE_ECDSA_SIGN_MASKING_CM
|
config MBEDTLS_HARDWARE_ECDSA_SIGN_MASKING_CM
|
||||||
bool "Mask original ECDSA sign operation under dummy sign operations"
|
bool "Mask original ECDSA sign operation under dummy sign operations"
|
||||||
select HAL_ECDSA_GEN_SIG_CM
|
select HAL_ECDSA_GEN_SIG_CM
|
||||||
# ToDo: IDF-11051
|
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
The ECDSA peripheral before ECO5 does not offer constant time ECDSA sign operation.
|
The ECDSA peripheral before ECO5 does not offer constant time ECDSA sign operation.
|
||||||
|
@ -44,6 +44,14 @@ int esp_ecc_point_multiply(const ecc_point_t *point, const uint8_t *scalar, ecc_
|
|||||||
|
|
||||||
ecc_hal_write_mul_param(scalar, point->x, point->y, len);
|
ecc_hal_write_mul_param(scalar, point->x, point->y, len);
|
||||||
ecc_hal_set_mode(work_mode);
|
ecc_hal_set_mode(work_mode);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable constant-time point multiplication operations for the ECC hardware accelerator,
|
||||||
|
* if supported for the given target. This protects the ECC multiplication operation from
|
||||||
|
* timing attacks. This increases the time taken (by almost 50%) for some point
|
||||||
|
* multiplication operations performed by the ECC hardware accelerator.
|
||||||
|
*/
|
||||||
|
ecc_hal_enable_constant_time_point_mul(true);
|
||||||
ecc_hal_start_calc();
|
ecc_hal_start_calc();
|
||||||
|
|
||||||
memset(result, 0, sizeof(ecc_point_t));
|
memset(result, 0, sizeof(ecc_point_t));
|
||||||
|
@ -1239,6 +1239,10 @@ config SOC_CRYPTO_DPA_PROTECTION_SUPPORTED
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_ECC_CONSTANT_TIME_POINT_MUL
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config SOC_ECDSA_USES_MPI
|
config SOC_ECDSA_USES_MPI
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
@ -502,6 +502,9 @@
|
|||||||
/*------------------------ Anti DPA (Security) CAPS --------------------------*/
|
/*------------------------ Anti DPA (Security) CAPS --------------------------*/
|
||||||
#define SOC_CRYPTO_DPA_PROTECTION_SUPPORTED 1
|
#define SOC_CRYPTO_DPA_PROTECTION_SUPPORTED 1
|
||||||
|
|
||||||
|
/*--------------------------- ECC CAPS ---------------------------------------*/
|
||||||
|
#define SOC_ECC_CONSTANT_TIME_POINT_MUL 1
|
||||||
|
|
||||||
/*------------------------- ECDSA CAPS -------------------------*/
|
/*------------------------- ECDSA CAPS -------------------------*/
|
||||||
#define SOC_ECDSA_USES_MPI (1)
|
#define SOC_ECDSA_USES_MPI (1)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user