forked from espressif/esp-idf
Merge branch 'feat/support_ecc_constant_time_mul_operations' into 'master'
feat(mbedtls/ecc): Support ECC hardware constant-time point multiplication operations Closes IDF-10327 See merge request espressif/esp-idf!31888
This commit is contained in:
@@ -37,4 +37,17 @@ menu "ESP Security Specific"
|
||||
default 3 if ESP_CRYPTO_DPA_PROTECTION_LEVEL_HIGH
|
||||
endmenu
|
||||
|
||||
config ESP_CRYPTO_FORCE_ECC_CONSTANT_TIME_POINT_MUL
|
||||
bool "Forcfully 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.
|
||||
endmenu
|
||||
|
@@ -16,10 +16,12 @@ static inline void esp_crypto_dpa_set_level(esp_crypto_dpa_sec_level_t level)
|
||||
REG_SET_FIELD(HP_SYSTEM_SEC_DPA_CONF_REG, HP_SYSTEM_SEC_DPA_LEVEL, level);
|
||||
}
|
||||
|
||||
#if CONFIG_ESP_CRYPTO_DPA_PROTECTION_AT_STARTUP
|
||||
void esp_crypto_dpa_protection_startup(void)
|
||||
{
|
||||
esp_crypto_dpa_set_level(CONFIG_ESP_CRYPTO_DPA_PROTECTION_LEVEL);
|
||||
}
|
||||
#endif
|
||||
|
||||
void esp_crypto_dpa_protection_enable(esp_crypto_dpa_sec_level_t level)
|
||||
{
|
||||
|
@@ -5,7 +5,10 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "sdkconfig.h"
|
||||
|
||||
/* Private interface file */
|
||||
|
||||
#if CONFIG_ESP_CRYPTO_DPA_PROTECTION_AT_STARTUP
|
||||
void esp_crypto_dpa_protection_startup(void);
|
||||
#endif
|
||||
|
@@ -7,7 +7,12 @@
|
||||
#include "esp_private/startup_internal.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_crypto_clk.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_table.h"
|
||||
#include "esp_security_priv.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
__attribute__((unused)) static const char *TAG = "esp_security";
|
||||
|
||||
ESP_SYSTEM_INIT_FN(esp_security_init, SECONDARY, BIT(0), 103)
|
||||
{
|
||||
@@ -15,6 +20,17 @@ ESP_SYSTEM_INIT_FN(esp_security_init, SECONDARY, BIT(0), 103)
|
||||
#if CONFIG_ESP_CRYPTO_DPA_PROTECTION_AT_STARTUP
|
||||
esp_crypto_dpa_protection_startup();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP_CRYPTO_FORCE_ECC_CONSTANT_TIME_POINT_MUL
|
||||
if (!esp_efuse_read_field_bit(ESP_EFUSE_ECC_FORCE_CONST_TIME)) {
|
||||
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);
|
||||
if (err != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Enabling ECC constant time operations forcefully failed.");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -177,3 +177,10 @@ int ecc_hal_read_mod_op_result(uint8_t *r, uint16_t len)
|
||||
}
|
||||
|
||||
#endif /* SOC_ECC_EXTENDED_MODES_SUPPORTED */
|
||||
|
||||
#ifdef SOC_ECC_CONSTANT_TIME_POINT_MUL
|
||||
void ecc_hal_enable_constant_time_point_mul(bool enable)
|
||||
{
|
||||
ecc_ll_enable_constant_time_point_mul(enable);
|
||||
}
|
||||
#endif /* SOC_ECC_CONSTANT_TIME_POINT_MUL */
|
||||
|
@@ -148,6 +148,15 @@ static inline void ecc_ll_set_mod_base(ecc_mod_base_t base)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ecc_ll_enable_constant_time_point_mul(bool enable)
|
||||
{
|
||||
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_write_param(ecc_ll_param_t param, const uint8_t *buf, uint16_t len)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
@@ -148,6 +148,15 @@ static inline void ecc_ll_set_mod_base(ecc_mod_base_t base)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ecc_ll_enable_constant_time_point_mul(bool enable)
|
||||
{
|
||||
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_write_param(ecc_ll_param_t param, const uint8_t *buf, uint16_t len)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -195,6 +195,15 @@ int ecc_hal_read_mod_op_result(uint8_t *r, uint16_t len);
|
||||
|
||||
#endif /* SOC_ECC_EXTENDED_MODES_SUPPORTED */
|
||||
|
||||
#ifdef SOC_ECC_CONSTANT_TIME_POINT_MUL
|
||||
/**
|
||||
* @brief Enable constant time multiplication operations
|
||||
*
|
||||
* @param true: enable; false: disable
|
||||
*/
|
||||
void ecc_hal_enable_constant_time_point_mul(bool enable);
|
||||
#endif /* SOC_ECC_CONSTANT_TIME_POINT_MUL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_private/esp_crypto_lock_internal.h"
|
||||
#include "esp_log.h"
|
||||
@@ -17,8 +18,8 @@
|
||||
|
||||
#include "memory_checks.h"
|
||||
#include "unity_fixture.h"
|
||||
#include "ccomp_timer.h"
|
||||
|
||||
#define _DEBUG_ 0
|
||||
#define SOC_ECC_SUPPORT_POINT_MULT 1
|
||||
#define SOC_ECC_SUPPORT_POINT_VERIFY 1
|
||||
|
||||
@@ -86,6 +87,9 @@ static void ecc_point_mul(const uint8_t *k_le, const uint8_t *x_le, const uint8_
|
||||
} else {
|
||||
ecc_hal_set_mode(ECC_MODE_POINT_MUL);
|
||||
}
|
||||
#ifdef SOC_ECC_CONSTANT_TIME_POINT_MUL
|
||||
ecc_hal_enable_constant_time_point_mul(true);
|
||||
#endif /* SOC_ECC_CONSTANT_TIME_POINT_MUL */
|
||||
ecc_hal_start_calc();
|
||||
|
||||
while (!ecc_hal_is_calc_finished()) {
|
||||
@@ -118,13 +122,11 @@ static void test_ecc_point_mul_inner(bool verify_first)
|
||||
ecc_be_to_le(ecc_p256_mul_res_x, x_mul_le, 32);
|
||||
ecc_be_to_le(ecc_p256_mul_res_y, y_mul_le, 32);
|
||||
|
||||
#if _DEBUG_
|
||||
ESP_LOG_BUFFER_HEX("Expected X:", x_mul_le, 32);
|
||||
ESP_LOG_BUFFER_HEX("Got X:", x_res_le, 32);
|
||||
ESP_LOG_BUFFER_HEXDUMP("Expected X:", x_mul_le, 32, ESP_LOG_DEBUG);
|
||||
ESP_LOG_BUFFER_HEXDUMP("Got X:", x_res_le, 32, ESP_LOG_DEBUG);
|
||||
|
||||
ESP_LOG_BUFFER_HEX("Expected Y:", y_mul_le, 32);
|
||||
ESP_LOG_BUFFER_HEX("Got Y:", y_res_le, 32);
|
||||
#endif
|
||||
ESP_LOG_BUFFER_HEXDUMP("Expected Y:", y_mul_le, 32, ESP_LOG_DEBUG);
|
||||
ESP_LOG_BUFFER_HEXDUMP("Got Y:", y_res_le, 32, ESP_LOG_DEBUG);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(x_mul_le, x_res_le, 32, "X coordinate of P256 point multiplication ");
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(y_mul_le, y_res_le, 32, "Y coordinate of P256 point multiplication ");
|
||||
@@ -144,13 +146,11 @@ static void test_ecc_point_mul_inner(bool verify_first)
|
||||
ecc_be_to_le(ecc_p192_mul_res_x, x_mul_le, 24);
|
||||
ecc_be_to_le(ecc_p192_mul_res_y, y_mul_le, 24);
|
||||
|
||||
#if _DEBUG_
|
||||
ESP_LOG_BUFFER_HEX("Expected X:", x_mul_le, 32);
|
||||
ESP_LOG_BUFFER_HEX("Got X:", x_res_le, 32);
|
||||
ESP_LOG_BUFFER_HEXDUMP("Expected X:", x_mul_le, 32, ESP_LOG_DEBUG);
|
||||
ESP_LOG_BUFFER_HEXDUMP("Got X:", x_res_le, 32, ESP_LOG_DEBUG);
|
||||
|
||||
ESP_LOG_BUFFER_HEX("Expected Y:", y_mul_le, 32);
|
||||
ESP_LOG_BUFFER_HEX("Got Y:", y_res_le, 32);
|
||||
#endif
|
||||
ESP_LOG_BUFFER_HEXDUMP("Expected Y:", y_mul_le, 32, ESP_LOG_DEBUG);
|
||||
ESP_LOG_BUFFER_HEXDUMP("Got Y:", y_res_le, 32, ESP_LOG_DEBUG);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(x_mul_le, x_res_le, 24, "X coordinate of P192 point multiplication ");
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(y_mul_le, y_res_le, 24, "Y coordinate of P192 point multiplication ");
|
||||
@@ -160,6 +160,74 @@ TEST(ecc, ecc_point_multiplication_on_SECP192R1_and_SECP256R1)
|
||||
{
|
||||
test_ecc_point_mul_inner(false);
|
||||
}
|
||||
|
||||
#if SOC_ECC_CONSTANT_TIME_POINT_MUL
|
||||
|
||||
#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
|
||||
|
||||
#if SOC_ECC_SUPPORT_POINT_VERIFY && !defined(SOC_ECC_SUPPORT_POINT_VERIFY_QUIRK)
|
||||
@@ -493,6 +561,9 @@ TEST_GROUP_RUNNER(ecc)
|
||||
{
|
||||
#if SOC_ECC_SUPPORT_POINT_MULT
|
||||
RUN_TEST_CASE(ecc, ecc_point_multiplication_on_SECP192R1_and_SECP256R1);
|
||||
#if SOC_ECC_CONSTANT_TIME_POINT_MUL
|
||||
RUN_TEST_CASE(ecc, ecc_point_multiplication_const_time_check_on_SECP192R1_and_SECP256R1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if SOC_ECC_SUPPORT_POINT_VERIFY && !defined(SOC_ECC_SUPPORT_POINT_VERIFY_QUIRK)
|
||||
@@ -534,5 +605,4 @@ TEST_GROUP_RUNNER(ecc)
|
||||
#if SOC_ECC_SUPPORT_MOD_MUL
|
||||
RUN_TEST_CASE(ecc, ecc_mod_multiplication_using_SECP192R1_and_SECP256R1_order_of_curve);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
3
components/hal/test_apps/crypto/main/idf_component.yml
Normal file
3
components/hal/test_apps/crypto/main/idf_component.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
espressif/ccomp_timer: ">=1.0.0"
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "ecc_impl.h"
|
||||
#include "hal/ecc_hal.h"
|
||||
#include "hal/ecc_ll.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
static void esp_ecc_acquire_hardware(void)
|
||||
{
|
||||
@@ -44,6 +45,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_set_mode(work_mode);
|
||||
#ifdef SOC_ECC_CONSTANT_TIME_POINT_MUL
|
||||
/* Enable constant-time point multiplication operations for the ECC hardware accelerator
|
||||
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);
|
||||
#endif /* SOC_ECC_CONSTANT_TIME_POINT_MUL */
|
||||
ecc_hal_start_calc();
|
||||
|
||||
memset(result, 0, sizeof(ecc_point_t));
|
||||
|
@@ -943,6 +943,10 @@ config SOC_SHA_SUPPORT_SHA256
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_ECC_CONSTANT_TIME_POINT_MUL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_ECDSA_SUPPORT_EXPORT_PUBKEY
|
||||
bool
|
||||
default y
|
||||
|
@@ -396,6 +396,9 @@
|
||||
#define SOC_SHA_SUPPORT_SHA224 (1)
|
||||
#define SOC_SHA_SUPPORT_SHA256 (1)
|
||||
|
||||
/*--------------------------- ECC CAPS ---------------------------------------*/
|
||||
#define SOC_ECC_CONSTANT_TIME_POINT_MUL 1
|
||||
|
||||
/*--------------------------- ECDSA CAPS ---------------------------------------*/
|
||||
#define SOC_ECDSA_SUPPORT_EXPORT_PUBKEY (1)
|
||||
|
||||
|
@@ -523,6 +523,10 @@ config SOC_SHA_SUPPORT_SHA256
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_ECC_CONSTANT_TIME_POINT_MUL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_ECDSA_SUPPORT_EXPORT_PUBKEY
|
||||
bool
|
||||
default y
|
||||
|
@@ -288,6 +288,9 @@
|
||||
#define SOC_SHA_SUPPORT_SHA224 (1)
|
||||
#define SOC_SHA_SUPPORT_SHA256 (1)
|
||||
|
||||
/*--------------------------- ECC CAPS ---------------------------------------*/
|
||||
#define SOC_ECC_CONSTANT_TIME_POINT_MUL 1
|
||||
|
||||
/*--------------------------- ECDSA CAPS ---------------------------------------*/
|
||||
#define SOC_ECDSA_SUPPORT_EXPORT_PUBKEY (1)
|
||||
#define SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE (1)
|
||||
|
Reference in New Issue
Block a user