mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-28 00:41:02 +02:00
fix(hal): Make the ECDSA countermeasure dynamically applicable
This commit makes the ECDSA countermeasure dynamically applicable across different revisions of the ESP32H2 SoC.
This commit is contained in:
@@ -346,18 +346,4 @@ menu "Hardware Settings"
|
|||||||
time point multiplication operations by changing the default ESP-IDF configurations.
|
time point multiplication operations by changing the default ESP-IDF configurations.
|
||||||
Performing constant time operations protect the ECC multiplication operations from timing attacks.
|
Performing constant time operations protect the ECC multiplication operations from timing attacks.
|
||||||
|
|
||||||
orsource "./port/$IDF_TARGET/Kconfig.dcdc"
|
|
||||||
|
|
||||||
orsource "./port/$IDF_TARGET/Kconfig.ldo"
|
|
||||||
|
|
||||||
# Invisible bringup bypass options for esp_hw_support component
|
|
||||||
config ESP_BRINGUP_BYPASS_CPU_CLK_SETTING
|
|
||||||
bool
|
|
||||||
default y if !SOC_CLK_TREE_SUPPORTED
|
|
||||||
default n
|
|
||||||
help
|
|
||||||
This option is only used for new chip bringup, when
|
|
||||||
clock support isn't done yet. So with this option,
|
|
||||||
we use xtal on FPGA as the clock source.
|
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
@@ -249,7 +249,13 @@ static void start_other_core(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_ESP_CRYPTO_FORCE_ECC_CONSTANT_TIME_POINT_MUL
|
#if CONFIG_ESP_CRYPTO_FORCE_ECC_CONSTANT_TIME_POINT_MUL
|
||||||
if (!esp_efuse_read_field_bit(ESP_EFUSE_ECC_FORCE_CONST_TIME)) {
|
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_EARLY_LOGD(TAG, "Forcefully enabling ECC constant time operations");
|
||||||
esp_err_t err = esp_efuse_write_field_bit(ESP_EFUSE_ECC_FORCE_CONST_TIME);
|
esp_err_t err = esp_efuse_write_field_bit(ESP_EFUSE_ECC_FORCE_CONST_TIME);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
|
@@ -105,7 +105,7 @@ 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
|
depends on IDF_TARGET_ESP32H2
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
Enable this option to apply the countermeasure for ECDSA signature operation
|
Enable this option to apply the countermeasure for ECDSA signature operation
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
#if CONFIG_HAL_ECDSA_GEN_SIG_CM
|
#if CONFIG_HAL_ECDSA_GEN_SIG_CM
|
||||||
#include "esp_fault.h"
|
#include "esp_fault.h"
|
||||||
#include "esp_random.h"
|
#include "esp_random.h"
|
||||||
|
#include "soc/chip_revision.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ECDSA_HAL_P192_COMPONENT_LEN 24
|
#define ECDSA_HAL_P192_COMPONENT_LEN 24
|
||||||
@@ -108,7 +109,11 @@ void ecdsa_hal_gen_signature(ecdsa_hal_config_t *conf, const uint8_t *hash,
|
|||||||
configure_ecdsa_periph(conf);
|
configure_ecdsa_periph(conf);
|
||||||
|
|
||||||
#if CONFIG_HAL_ECDSA_GEN_SIG_CM
|
#if CONFIG_HAL_ECDSA_GEN_SIG_CM
|
||||||
|
if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102)) {
|
||||||
ecdsa_hal_gen_signature_with_countermeasure(hash, r_out, s_out, len);
|
ecdsa_hal_gen_signature_with_countermeasure(hash, r_out, s_out, len);
|
||||||
|
} else {
|
||||||
|
ecdsa_hal_gen_signature_inner(hash, r_out, s_out, len);
|
||||||
|
}
|
||||||
#else /* CONFIG_HAL_ECDSA_GEN_SIG_CM */
|
#else /* CONFIG_HAL_ECDSA_GEN_SIG_CM */
|
||||||
ecdsa_hal_gen_signature_inner(hash, r_out, s_out, len);
|
ecdsa_hal_gen_signature_inner(hash, r_out, s_out, len);
|
||||||
#endif /* !CONFIG_HAL_ECDSA_GEN_SIG_CM */
|
#endif /* !CONFIG_HAL_ECDSA_GEN_SIG_CM */
|
||||||
|
@@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.16)
|
|||||||
|
|
||||||
set(COMPONENTS main)
|
set(COMPONENTS main)
|
||||||
|
|
||||||
|
set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/unit-test-app/components")
|
||||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
|
||||||
|
|
||||||
project(ecc_test)
|
project(ecc_test)
|
||||||
|
@@ -2,5 +2,5 @@ set(srcs "app_main.c"
|
|||||||
"test_ecc.c")
|
"test_ecc.c")
|
||||||
|
|
||||||
idf_component_register(SRCS ${srcs}
|
idf_component_register(SRCS ${srcs}
|
||||||
REQUIRES unity
|
REQUIRES unity test_utils
|
||||||
WHOLE_ARCHIVE)
|
WHOLE_ARCHIVE)
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: CC0-1.0
|
* SPDX-License-Identifier: CC0-1.0
|
||||||
*/
|
*/
|
||||||
@@ -7,6 +7,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "ccomp_timer.h"
|
||||||
|
#include "sys/param.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "test_params.h"
|
#include "test_params.h"
|
||||||
@@ -136,7 +138,7 @@ TEST_CASE("ECC point multiplication on SECP192R1 and SECP256R1", "[ecc][hal]")
|
|||||||
|
|
||||||
#if SOC_ECC_CONSTANT_TIME_POINT_MUL || (CONFIG_IDF_TARGET_ESP32H2 && CONFIG_ESP32H2_REV_MIN_FULL >= 102)
|
#if SOC_ECC_CONSTANT_TIME_POINT_MUL || (CONFIG_IDF_TARGET_ESP32H2 && CONFIG_ESP32H2_REV_MIN_FULL >= 102)
|
||||||
|
|
||||||
#define CONST_TIME_DEVIATION_PERCENT 0.002
|
#define CONST_TIME_DEVIATION_THRESHOLD 2 // 0.2 %
|
||||||
|
|
||||||
static void test_ecc_point_mul_inner_constant_time(void)
|
static void test_ecc_point_mul_inner_constant_time(void)
|
||||||
{
|
{
|
||||||
@@ -152,11 +154,14 @@ static void test_ecc_point_mul_inner_constant_time(void)
|
|||||||
uint8_t x_res_le[32];
|
uint8_t x_res_le[32];
|
||||||
uint8_t y_res_le[32];
|
uint8_t y_res_le[32];
|
||||||
|
|
||||||
double deviation = 0;
|
uint32_t deviation = 0;
|
||||||
uint32_t elapsed_time, mean_elapsed_time, total_elapsed_time = 0;
|
uint32_t elapsed_time, mean_elapsed_time, total_elapsed_time = 0;
|
||||||
uint32_t max_time = 0, min_time = UINT32_MAX;
|
uint32_t max_time = 0, min_time = UINT32_MAX;
|
||||||
int loop_count = 10;
|
int loop_count = 10;
|
||||||
|
|
||||||
|
// performing the operation once to warm up the cache
|
||||||
|
ecc_point_mul(scalar_le, x_le, y_le, 32, 0, x_res_le, y_res_le);
|
||||||
|
|
||||||
for (int i = 0; i < loop_count; i++) {
|
for (int i = 0; i < loop_count; i++) {
|
||||||
ccomp_timer_start();
|
ccomp_timer_start();
|
||||||
ecc_point_mul(scalar_le, x_le, y_le, 32, 0, x_res_le, y_res_le);
|
ecc_point_mul(scalar_le, x_le, y_le, 32, 0, x_res_le, y_res_le);
|
||||||
@@ -167,9 +172,9 @@ static void test_ecc_point_mul_inner_constant_time(void)
|
|||||||
total_elapsed_time += elapsed_time;
|
total_elapsed_time += elapsed_time;
|
||||||
}
|
}
|
||||||
mean_elapsed_time = total_elapsed_time / loop_count;
|
mean_elapsed_time = total_elapsed_time / loop_count;
|
||||||
deviation = ((double)(max_time - mean_elapsed_time) / mean_elapsed_time);
|
deviation = (((max_time - mean_elapsed_time) * 1000) / mean_elapsed_time);
|
||||||
|
|
||||||
TEST_ASSERT_LESS_THAN_DOUBLE(CONST_TIME_DEVIATION_PERCENT, deviation);
|
TEST_ASSERT_LESS_THAN(CONST_TIME_DEVIATION_THRESHOLD, deviation);
|
||||||
|
|
||||||
/* P192 */
|
/* P192 */
|
||||||
ecc_be_to_le(ecc_p192_scalar, scalar_le, 24);
|
ecc_be_to_le(ecc_p192_scalar, scalar_le, 24);
|
||||||
@@ -190,12 +195,12 @@ static void test_ecc_point_mul_inner_constant_time(void)
|
|||||||
total_elapsed_time += elapsed_time;
|
total_elapsed_time += elapsed_time;
|
||||||
}
|
}
|
||||||
mean_elapsed_time = total_elapsed_time / loop_count;
|
mean_elapsed_time = total_elapsed_time / loop_count;
|
||||||
deviation = ((double)(max_time - mean_elapsed_time) / mean_elapsed_time);
|
deviation = (((max_time - mean_elapsed_time) * 1000) / mean_elapsed_time);
|
||||||
|
|
||||||
TEST_ASSERT_LESS_THAN_DOUBLE(CONST_TIME_DEVIATION_PERCENT, deviation);
|
TEST_ASSERT_LESS_THAN(CONST_TIME_DEVIATION_THRESHOLD, deviation);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ecc, ecc_point_multiplication_const_time_check_on_SECP192R1_and_SECP256R1)
|
TEST_CASE("ECC point multiplication constant time check on SECP192R1 and SECP256R1", "[ecc][hal]")
|
||||||
{
|
{
|
||||||
test_ecc_point_mul_inner_constant_time();
|
test_ecc_point_mul_inner_constant_time();
|
||||||
}
|
}
|
||||||
|
@@ -1,2 +1,3 @@
|
|||||||
CONFIG_ESP_TASK_WDT_EN=y
|
CONFIG_ESP_TASK_WDT_EN=y
|
||||||
CONFIG_ESP_TASK_WDT_INIT=n
|
CONFIG_ESP_TASK_WDT_INIT=n
|
||||||
|
CONFIG_ESP_CRYPTO_DPA_PROTECTION_AT_STARTUP=n
|
||||||
|
@@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN_CONSTANT_TIME_CM
|
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN_CONSTANT_TIME_CM
|
||||||
#include "esp_timer.h"
|
#include "esp_timer.h"
|
||||||
|
#include "soc/chip_revision.h"
|
||||||
|
#include "hal/efuse_hal.h"
|
||||||
|
|
||||||
#if CONFIG_ESP_CRYPTO_DPA_PROTECTION_LEVEL_HIGH
|
#if CONFIG_ESP_CRYPTO_DPA_PROTECTION_LEVEL_HIGH
|
||||||
/*
|
/*
|
||||||
@@ -176,10 +178,12 @@ static int esp_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi* r, mbedtls_mpi* s
|
|||||||
#endif
|
#endif
|
||||||
ecdsa_hal_gen_signature(&conf, sha_le, r_le, s_le, len);
|
ecdsa_hal_gen_signature(&conf, sha_le, r_le, s_le, len);
|
||||||
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN_CONSTANT_TIME_CM
|
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN_CONSTANT_TIME_CM
|
||||||
|
if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102)) {
|
||||||
sig_time = esp_timer_get_time() - sig_time;
|
sig_time = esp_timer_get_time() - sig_time;
|
||||||
if (sig_time < ECDSA_CM_FIXED_SIG_TIME) {
|
if (sig_time < ECDSA_CM_FIXED_SIG_TIME) {
|
||||||
esp_rom_delay_us(ECDSA_CM_FIXED_SIG_TIME - sig_time);
|
esp_rom_delay_us(ECDSA_CM_FIXED_SIG_TIME - sig_time);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
process_again = !ecdsa_hal_get_operation_result()
|
process_again = !ecdsa_hal_get_operation_result()
|
||||||
|| !memcmp(r_le, zeroes, len)
|
|| !memcmp(r_le, zeroes, len)
|
||||||
|
Reference in New Issue
Block a user