feat: added config member to store block number for hign part of ecdsa key

This commit is contained in:
nilesh.kale
2025-07-21 15:40:52 +05:30
parent 08e781c876
commit dedc9889de
23 changed files with 146 additions and 185 deletions

View File

@@ -19,7 +19,7 @@ idf_component_register(SRCS "${srcs}"
PRIV_INCLUDE_DIRS "private_include" PRIV_INCLUDE_DIRS "private_include"
# mbedtls is public requirements because esp_tls.h # mbedtls is public requirements because esp_tls.h
# includes mbedtls header files. # includes mbedtls header files.
REQUIRES mbedtls efuse REQUIRES mbedtls
PRIV_REQUIRES ${priv_req}) PRIV_REQUIRES ${priv_req})
if(CONFIG_ESP_TLS_USING_WOLFSSL) if(CONFIG_ESP_TLS_USING_WOLFSSL)

View File

@@ -28,22 +28,6 @@
extern "C" { extern "C" {
#endif #endif
/**
* @brief Macro to combine two key blocks into a single integer
* @note Least significant 4 bits stores block number of the low key block, and the next 4 more significant bits store the high key block number.
*/
#define ESP_TLS_ECDSA_COMBINE_KEY_BLOCKS(blk_high, blk_low) (((blk_high) << 4) | (blk_low))
/**
* @brief Macro to extract high and low key block numbers from a combined integer
* @note Extracts high block from bits 4-7 and low block from bits 0-3
*/
#define ESP_TLS_ECDSA_EXTRACT_KEY_BLOCKS(combined_blk, blk_high, blk_low) do { \
(blk_high) = ((combined_blk) >> 4) & 0xF; \
(blk_low) = (combined_blk) & 0xF; \
} while(0)
/** /**
* @brief ESP-TLS Connection State * @brief ESP-TLS Connection State
*/ */
@@ -117,7 +101,10 @@ typedef enum {
*/ */
typedef enum { typedef enum {
ESP_TLS_ECDSA_CURVE_SECP256R1 = 0, /*!< Use SECP256R1 curve */ ESP_TLS_ECDSA_CURVE_SECP256R1 = 0, /*!< Use SECP256R1 curve */
#if SOC_ECDSA_SUPPORT_CURVE_P384
ESP_TLS_ECDSA_CURVE_SECP384R1, /*!< Use SECP384R1 curve */ ESP_TLS_ECDSA_CURVE_SECP384R1, /*!< Use SECP384R1 curve */
#endif
ESP_TLS_ECDSA_CURVE_MAX, /*!< to indicate max */
} esp_tls_ecdsa_curve_t; } esp_tls_ecdsa_curve_t;
/** /**
@@ -192,7 +179,9 @@ typedef struct esp_tls_cfg {
bool use_ecdsa_peripheral; /*!< Use the ECDSA peripheral for the private key operations */ bool use_ecdsa_peripheral; /*!< Use the ECDSA peripheral for the private key operations */
uint8_t ecdsa_key_efuse_blk; /*!< The efuse block where ECDSA key is stored. If two blocks are used to store the key, then the macro ESP_TLS_ECDSA_COMBINE_KEY_BLOCKS() can be used to combine them. */ uint8_t ecdsa_key_efuse_blk; /*!< The efuse block where ECDSA key is stored. For SECP384R1 curve, if two blocks are used, set this to the low block and use ecdsa_key_efuse_blk_high for the high block. */
uint8_t ecdsa_key_efuse_blk_high; /*!< The high efuse block for ECDSA key (used only for SECP384R1 curve). If not set (0), only ecdsa_key_efuse_blk is used. */
esp_tls_ecdsa_curve_t ecdsa_curve; /*!< ECDSA curve to use (SECP256R1 or SECP384R1) */ esp_tls_ecdsa_curve_t ecdsa_curve; /*!< ECDSA curve to use (SECP256R1 or SECP384R1) */
@@ -338,7 +327,9 @@ typedef struct esp_tls_cfg_server {
bool use_ecdsa_peripheral; /*!< Use ECDSA peripheral to use private key */ bool use_ecdsa_peripheral; /*!< Use ECDSA peripheral to use private key */
uint8_t ecdsa_key_efuse_blk; /*!< The efuse block where ECDSA key is stored. If two blocks are used to store the key, then the macro ESP_TLS_ECDSA_COMBINE_KEY_BLOCKS() can be used to combine them. */ uint8_t ecdsa_key_efuse_blk; /*!< The efuse block where ECDSA key is stored. For SECP384R1 curve, if two blocks are used, set this to the low block and use ecdsa_key_efuse_blk_high for the high block. */
uint8_t ecdsa_key_efuse_blk_high; /*!< The high efuse block for ECDSA key (used only for SECP384R1 curve). If not set (0), only ecdsa_key_efuse_blk is used. */
esp_tls_ecdsa_curve_t ecdsa_curve; /*!< ECDSA curve to use (SECP256R1 or SECP384R1) */ esp_tls_ecdsa_curve_t ecdsa_curve; /*!< ECDSA curve to use (SECP256R1 or SECP384R1) */

View File

@@ -23,8 +23,6 @@
#include "mbedtls/esp_mbedtls_dynamic.h" #include "mbedtls/esp_mbedtls_dynamic.h"
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN #ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
#include "mbedtls/ecp.h" #include "mbedtls/ecp.h"
#include "esp_efuse.h"
#include "esp_efuse_chip.h"
#include "ecdsa/ecdsa_alt.h" #include "ecdsa/ecdsa_alt.h"
#endif #endif
@@ -61,7 +59,7 @@ static mbedtls_x509_crt *global_cacert = NULL;
#define NEWLIB_NANO_SIZE_T_COMPAT_CAST(size_t_var) size_t_var #define NEWLIB_NANO_SIZE_T_COMPAT_CAST(size_t_var) size_t_var
#endif #endif
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN #ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
/** /**
* @brief Convert ESP-TLS ECDSA curve enum to mbedTLS group ID * @brief Convert ESP-TLS ECDSA curve enum to mbedTLS group ID
* @param curve ESP-TLS ECDSA curve enum value * @param curve ESP-TLS ECDSA curve enum value
@@ -70,10 +68,6 @@ static mbedtls_x509_crt *global_cacert = NULL;
*/ */
static esp_err_t esp_tls_ecdsa_curve_to_mbedtls_group_id(esp_tls_ecdsa_curve_t curve, mbedtls_ecp_group_id *grp_id) static esp_err_t esp_tls_ecdsa_curve_to_mbedtls_group_id(esp_tls_ecdsa_curve_t curve, mbedtls_ecp_group_id *grp_id)
{ {
if (grp_id == NULL) {
return ESP_ERR_INVALID_ARG;
}
switch (curve) { switch (curve) {
case ESP_TLS_ECDSA_CURVE_SECP256R1: case ESP_TLS_ECDSA_CURVE_SECP256R1:
*grp_id = MBEDTLS_ECP_DP_SECP256R1; *grp_id = MBEDTLS_ECP_DP_SECP256R1;
@@ -82,7 +76,6 @@ static esp_err_t esp_tls_ecdsa_curve_to_mbedtls_group_id(esp_tls_ecdsa_curve_t c
*grp_id = MBEDTLS_ECP_DP_SECP384R1; *grp_id = MBEDTLS_ECP_DP_SECP384R1;
break; break;
default: default:
ESP_LOGE(TAG, "Invalid ECDSA curve specified: %d", curve);
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
return ESP_OK; return ESP_OK;
@@ -788,7 +781,11 @@ static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls)
} else if (cfg->use_ecdsa_peripheral) { } else if (cfg->use_ecdsa_peripheral) {
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN #ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
tls->use_ecdsa_peripheral = cfg->use_ecdsa_peripheral; tls->use_ecdsa_peripheral = cfg->use_ecdsa_peripheral;
#if SOC_ECDSA_SUPPORT_CURVE_P384
tls->ecdsa_efuse_blk = HAL_ECDSA_COMBINE_KEY_BLOCKS(cfg->ecdsa_key_efuse_blk_high, cfg->ecdsa_key_efuse_blk);
#else
tls->ecdsa_efuse_blk = cfg->ecdsa_key_efuse_blk; tls->ecdsa_efuse_blk = cfg->ecdsa_key_efuse_blk;
#endif
tls->ecdsa_curve = cfg->ecdsa_curve; tls->ecdsa_curve = cfg->ecdsa_curve;
esp_tls_pki_t pki = { esp_tls_pki_t pki = {
.public_cert = &tls->servercert, .public_cert = &tls->servercert,
@@ -1036,7 +1033,11 @@ esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t
} else if (cfg->use_ecdsa_peripheral) { } else if (cfg->use_ecdsa_peripheral) {
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN #ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
tls->use_ecdsa_peripheral = cfg->use_ecdsa_peripheral; tls->use_ecdsa_peripheral = cfg->use_ecdsa_peripheral;
#if SOC_ECDSA_SUPPORT_CURVE_P384
tls->ecdsa_efuse_blk = HAL_ECDSA_COMBINE_KEY_BLOCKS(cfg->ecdsa_key_efuse_blk_high, cfg->ecdsa_key_efuse_blk);
#else
tls->ecdsa_efuse_blk = cfg->ecdsa_key_efuse_blk; tls->ecdsa_efuse_blk = cfg->ecdsa_key_efuse_blk;
#endif
tls->ecdsa_curve = cfg->ecdsa_curve; tls->ecdsa_curve = cfg->ecdsa_curve;
esp_tls_pki_t pki = { esp_tls_pki_t pki = {
.public_cert = &tls->clientcert, .public_cert = &tls->clientcert,
@@ -1064,6 +1065,12 @@ esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t
static int ecdsa_peripheral_supported_ciphersuites[4] = {0}; // Max 4 elements static int ecdsa_peripheral_supported_ciphersuites[4] = {0}; // Max 4 elements
int ciphersuite_count = 0; int ciphersuite_count = 0;
if (grp_id == MBEDTLS_ECP_DP_SECP384R1) {
ecdsa_peripheral_supported_ciphersuites[ciphersuite_count++] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
} else {
ecdsa_peripheral_supported_ciphersuites[ciphersuite_count++] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
}
#if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 #if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3
if (grp_id == MBEDTLS_ECP_DP_SECP384R1) { if (grp_id == MBEDTLS_ECP_DP_SECP384R1) {
ecdsa_peripheral_supported_ciphersuites[ciphersuite_count++] = MBEDTLS_TLS1_3_AES_256_GCM_SHA384; ecdsa_peripheral_supported_ciphersuites[ciphersuite_count++] = MBEDTLS_TLS1_3_AES_256_GCM_SHA384;
@@ -1071,11 +1078,6 @@ esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t
ecdsa_peripheral_supported_ciphersuites[ciphersuite_count++] = MBEDTLS_TLS1_3_AES_128_GCM_SHA256; ecdsa_peripheral_supported_ciphersuites[ciphersuite_count++] = MBEDTLS_TLS1_3_AES_128_GCM_SHA256;
} }
#endif #endif
if (grp_id == MBEDTLS_ECP_DP_SECP384R1) {
ecdsa_peripheral_supported_ciphersuites[ciphersuite_count++] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
} else {
ecdsa_peripheral_supported_ciphersuites[ciphersuite_count++] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
}
ESP_LOGD(TAG, "Set the ciphersuites list"); ESP_LOGD(TAG, "Set the ciphersuites list");
mbedtls_ssl_conf_ciphersuites(&tls->conf, ecdsa_peripheral_supported_ciphersuites); mbedtls_ssl_conf_ciphersuites(&tls->conf, ecdsa_peripheral_supported_ciphersuites);

View File

@@ -15,7 +15,6 @@
#include <fcntl.h> #include <fcntl.h>
#include "esp_err.h" #include "esp_err.h"
#include "esp_tls_errors.h" #include "esp_tls_errors.h"
#include "esp_tls.h"
#ifdef CONFIG_ESP_TLS_USING_MBEDTLS #ifdef CONFIG_ESP_TLS_USING_MBEDTLS
#include "mbedtls/platform.h" #include "mbedtls/platform.h"
#include "mbedtls/net_sockets.h" #include "mbedtls/net_sockets.h"

View File

@@ -1,5 +1,5 @@
if(NOT ${IDF_TARGET} STREQUAL "linux") if(NOT ${IDF_TARGET} STREQUAL "linux")
set(req lwip esp_event esp-tls) set(req lwip esp_event)
else() else()
set(req linux esp_event) set(req linux esp_event)
endif() endif()

View File

@@ -36,6 +36,7 @@ ESP_STATIC_ASSERT((int)ESP_HTTP_CLIENT_TLS_VER_ANY == (int)ESP_TLS_VER_ANY, "Enu
ESP_STATIC_ASSERT((int)ESP_HTTP_CLIENT_TLS_VER_MAX <= (int)ESP_TLS_VER_TLS_MAX, "HTTP client supported TLS is not supported in esp-tls"); ESP_STATIC_ASSERT((int)ESP_HTTP_CLIENT_TLS_VER_MAX <= (int)ESP_TLS_VER_TLS_MAX, "HTTP client supported TLS is not supported in esp-tls");
ESP_STATIC_ASSERT((int)HTTP_TLS_DYN_BUF_RX_STATIC == (int)ESP_TLS_DYN_BUF_RX_STATIC, "Enum mismatch in esp_http_client and esp-tls"); ESP_STATIC_ASSERT((int)HTTP_TLS_DYN_BUF_RX_STATIC == (int)ESP_TLS_DYN_BUF_RX_STATIC, "Enum mismatch in esp_http_client and esp-tls");
ESP_STATIC_ASSERT((int)HTTP_TLS_DYN_BUF_STRATEGY_MAX <= (int)ESP_TLS_DYN_BUF_STRATEGY_MAX, "HTTP client supported TLS is not supported in esp-tls"); ESP_STATIC_ASSERT((int)HTTP_TLS_DYN_BUF_STRATEGY_MAX <= (int)ESP_TLS_DYN_BUF_STRATEGY_MAX, "HTTP client supported TLS is not supported in esp-tls");
ESP_STATIC_ASSERT((int)ESP_HTTP_CLIENT_ECDSA_CURVE_MAX <= (int)ESP_TLS_ECDSA_CURVE_MAX, "HTTP client supported ECDSA curve is not supported in esp-tls");
#if CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT == -1 #if CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT == -1
#define ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT portMAX_DELAY #define ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT portMAX_DELAY
@@ -927,7 +928,11 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co
} }
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN #ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
if (config->use_ecdsa_peripheral) { if (config->use_ecdsa_peripheral) {
#if SOC_ECDSA_SUPPORT_CURVE_P384
esp_transport_ssl_set_client_key_ecdsa_peripheral_extended(ssl, config->ecdsa_key_efuse_blk, config->ecdsa_key_efuse_blk_high);
#else
esp_transport_ssl_set_client_key_ecdsa_peripheral(ssl, config->ecdsa_key_efuse_blk); esp_transport_ssl_set_client_key_ecdsa_peripheral(ssl, config->ecdsa_key_efuse_blk);
#endif
// Set the ECDSA curve // Set the ECDSA curve
esp_transport_ssl_set_ecdsa_curve(ssl, config->ecdsa_curve); esp_transport_ssl_set_ecdsa_curve(ssl, config->ecdsa_curve);
} }

View File

@@ -11,7 +11,6 @@
#include "sdkconfig.h" #include "sdkconfig.h"
#include "esp_err.h" #include "esp_err.h"
#include <sys/socket.h> #include <sys/socket.h>
#include "esp_tls.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@@ -98,6 +97,17 @@ typedef enum {
typedef esp_err_t (*http_event_handle_cb)(esp_http_client_event_t *evt); typedef esp_err_t (*http_event_handle_cb)(esp_http_client_event_t *evt);
/**
* @brief ECDSA curve options for TLS connections
*/
typedef enum {
ESP_HTTP_CLIENT_ECDSA_CURVE_SECP256R1 = 0, /*!< Use SECP256R1 curve */
#if SOC_ECDSA_SUPPORT_CURVE_P384
ESP_HTTP_CLIENT_ECDSA_CURVE_SECP384R1, /*!< Use SECP384R1 curve */
#endif
ESP_HTTP_CLIENT_ECDSA_CURVE_MAX, /*!< to indicate max */
} esp_http_client_ecdsa_curve_t;
/** /**
* @brief HTTP method * @brief HTTP method
*/ */
@@ -179,8 +189,9 @@ typedef struct {
esp_http_client_proto_ver_t tls_version; /*!< TLS protocol version of the connection, e.g., TLS 1.2, TLS 1.3 (default - no preference) */ esp_http_client_proto_ver_t tls_version; /*!< TLS protocol version of the connection, e.g., TLS 1.2, TLS 1.3 (default - no preference) */
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN #ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
bool use_ecdsa_peripheral; /*!< Use ECDSA peripheral to use private key. */ bool use_ecdsa_peripheral; /*!< Use ECDSA peripheral to use private key. */
uint8_t ecdsa_key_efuse_blk; /*!< The efuse block where ECDSA key is stored. If two blocks are used to store the key, then the macro ESP_TLS_ECDSA_COMBINE_KEY_BLOCKS() can be used to combine them. The macro is defined in esp_tls.h */ uint8_t ecdsa_key_efuse_blk; /*!< The efuse block where ECDSA key is stored. For SECP384R1 curve, if two blocks are used, set this to the low block and use ecdsa_key_efuse_blk_high for the high block. */
esp_tls_ecdsa_curve_t ecdsa_curve; /*!< ECDSA curve to use (SECP256R1 or SECP384R1) */ uint8_t ecdsa_key_efuse_blk_high; /*!< The high efuse block for ECDSA key (used only for SECP384R1 curve). If not set (0), only ecdsa_key_efuse_blk is used. */
esp_http_client_ecdsa_curve_t ecdsa_curve; /*!< ECDSA curve to use (SECP256R1 or SECP384R1) */
#endif #endif
const char *user_agent; /*!< The User Agent string to send with HTTP requests */ const char *user_agent; /*!< The User Agent string to send with HTTP requests */
esp_http_client_method_t method; /*!< HTTP Method */ esp_http_client_method_t method; /*!< HTTP Method */

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -100,10 +100,13 @@ struct httpd_ssl_config {
/** Use ECDSA peripheral to use private key */ /** Use ECDSA peripheral to use private key */
bool use_ecdsa_peripheral; bool use_ecdsa_peripheral;
/*!< The efuse block where ECDSA key is stored. If two blocks are used to store the key, then the macro ESP_TLS_ECDSA_COMBINE_KEY_BLOCKS() can be used to combine them. The macro is defined in esp_tls.h */ /** The efuse block where ECDSA key is stored. For SECP384R1 curve, if two blocks are used, set this to the low block and use ecdsa_key_efuse_blk_high for the high block. */
uint8_t ecdsa_key_efuse_blk; uint8_t ecdsa_key_efuse_blk;
/*!< ECDSA curve to use (SECP256R1 or SECP384R1) */ /** The high efuse block for ECDSA key (used only for SECP384R1 curve). If not set (0), only ecdsa_key_efuse_blk is used. */
uint8_t ecdsa_key_efuse_blk_high;
/** ECDSA curve to use (SECP256R1 or SECP384R1) */
esp_tls_ecdsa_curve_t ecdsa_curve; esp_tls_ecdsa_curve_t ecdsa_curve;
/** Transport Mode (default secure) */ /** Transport Mode (default secure) */
@@ -189,6 +192,7 @@ typedef struct httpd_ssl_config httpd_ssl_config_t;
.prvtkey_len = 0, \ .prvtkey_len = 0, \
.use_ecdsa_peripheral = false, \ .use_ecdsa_peripheral = false, \
.ecdsa_key_efuse_blk = 0, \ .ecdsa_key_efuse_blk = 0, \
.ecdsa_key_efuse_blk_high = 0, \
.ecdsa_curve = ESP_TLS_ECDSA_CURVE_SECP256R1, \ .ecdsa_curve = ESP_TLS_ECDSA_CURVE_SECP256R1, \
.transport_mode = HTTPD_SSL_TRANSPORT_SECURE, \ .transport_mode = HTTPD_SSL_TRANSPORT_SECURE, \
.port_secure = 443, \ .port_secure = 443, \

View File

@@ -333,6 +333,9 @@ static esp_err_t create_secure_context(const struct httpd_ssl_config *config, ht
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN #ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
(*ssl_ctx)->tls_cfg->use_ecdsa_peripheral = config->use_ecdsa_peripheral; (*ssl_ctx)->tls_cfg->use_ecdsa_peripheral = config->use_ecdsa_peripheral;
(*ssl_ctx)->tls_cfg->ecdsa_key_efuse_blk = config->ecdsa_key_efuse_blk; (*ssl_ctx)->tls_cfg->ecdsa_key_efuse_blk = config->ecdsa_key_efuse_blk;
#if SOC_ECDSA_SUPPORT_CURVE_P384
(*ssl_ctx)->tls_cfg->ecdsa_key_efuse_blk_high = config->ecdsa_key_efuse_blk_high;
#endif
(*ssl_ctx)->tls_cfg->ecdsa_curve = config->ecdsa_curve; (*ssl_ctx)->tls_cfg->ecdsa_curve = config->ecdsa_curve;
#else #else
ESP_LOGE(TAG, "Please enable the support for signing using ECDSA peripheral in menuconfig."); ESP_LOGE(TAG, "Please enable the support for signing using ECDSA peripheral in menuconfig.");

View File

@@ -50,7 +50,7 @@ typedef enum {
/** /**
* @brief Macro to combine two key blocks into a single integer * @brief Macro to combine two key blocks into a single integer
* @note Least significant 4 bits stores block number of the low key block, and the next 4 more significant bits store the high key block number. * @note Least significant 4 bits stores block number of the low key block, and the next 4 bits store the high key block number.
*/ */
#define HAL_ECDSA_COMBINE_KEY_BLOCKS(blk_high, blk_low) (((blk_high) << 4) | (blk_low)) #define HAL_ECDSA_COMBINE_KEY_BLOCKS(blk_high, blk_low) (((blk_high) << 4) | (blk_low))

View File

@@ -148,60 +148,44 @@ static void esp_ecdsa_release_hardware(void)
*/ */
static int esp_ecdsa_validate_efuse_block(mbedtls_ecp_group_id grp_id, int efuse_blk) static int esp_ecdsa_validate_efuse_block(mbedtls_ecp_group_id grp_id, int efuse_blk)
{ {
int low_blk = efuse_blk;
esp_efuse_purpose_t expected_key_purpose_low;
#if SOC_ECDSA_SUPPORT_CURVE_SPECIFIC_KEY_PURPOSES #if SOC_ECDSA_SUPPORT_CURVE_SPECIFIC_KEY_PURPOSES
esp_efuse_purpose_t expected_purpose; #if SOC_ECDSA_SUPPORT_CURVE_P384
esp_efuse_purpose_t actual_purpose; int high_blk;
HAL_ECDSA_EXTRACT_KEY_BLOCKS(efuse_blk, high_blk, low_blk);
esp_efuse_purpose_t expected_key_purpose_high;
#endif
switch (grp_id) { switch (grp_id) {
case MBEDTLS_ECP_DP_SECP192R1: case MBEDTLS_ECP_DP_SECP192R1:
expected_purpose = ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY_P192; expected_key_purpose_low = ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY_P192;
actual_purpose = esp_efuse_get_key_purpose((esp_efuse_block_t)efuse_blk);
if (actual_purpose != expected_purpose) {
ESP_LOGE(TAG, "Efuse block %d has purpose %d, expected %d", efuse_blk, actual_purpose, expected_purpose);
return MBEDTLS_ERR_ECP_INVALID_KEY;
}
break; break;
case MBEDTLS_ECP_DP_SECP256R1: case MBEDTLS_ECP_DP_SECP256R1:
expected_purpose = ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY_P256; expected_key_purpose_low = ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY_P256;
actual_purpose = esp_efuse_get_key_purpose((esp_efuse_block_t)efuse_blk);
if (actual_purpose != expected_purpose) {
ESP_LOGE(TAG, "Efuse block %d has purpose %d, expected %d", efuse_blk, actual_purpose, expected_purpose);
return MBEDTLS_ERR_ECP_INVALID_KEY;
}
break; break;
#if SOC_ECDSA_SUPPORT_CURVE_P384 #if SOC_ECDSA_SUPPORT_CURVE_P384
case MBEDTLS_ECP_DP_SECP384R1: case MBEDTLS_ECP_DP_SECP384R1:
int high_blk, low_blk; expected_key_purpose_low = ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY_P384_L;
MBEDTLS_ECDSA_EXTRACT_KEY_BLOCKS(efuse_blk, high_blk, low_blk); expected_key_purpose_high = ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY_P384_H;
// For P384, we need to check both blocks
esp_efuse_purpose_t high_purpose = esp_efuse_get_key_purpose((esp_efuse_block_t)high_blk);
esp_efuse_purpose_t low_purpose = esp_efuse_get_key_purpose((esp_efuse_block_t)low_blk);
if (high_purpose != ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY_P384_H) {
ESP_LOGE(TAG, "Efuse block %d has purpose %d, expected P384_H (%d)",
high_blk, high_purpose, ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY_P384_H);
return MBEDTLS_ERR_ECP_INVALID_KEY;
}
if (low_purpose != ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY_P384_L) {
ESP_LOGE(TAG, "Efuse block %d has purpose %d, expected P384_L (%d)",
low_blk, low_purpose, ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY_P384_L);
return MBEDTLS_ERR_ECP_INVALID_KEY;
}
break; break;
#endif #endif
default: default:
ESP_LOGE(TAG, "Invalid ECDSA curve id"); ESP_LOGE(TAG, "Unsupported ECDSA curve ID: %d", grp_id);
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
} }
#else /* SOC_ECDSA_SUPPORT_CURVE_SPECIFIC_KEY_PURPOSES */ #else /* SOC_ECDSA_SUPPORT_CURVE_SPECIFIC_KEY_PURPOSES */
// For generic ECDSA key purpose, validate the single block (efuse_blk) expected_key_purpose_low = ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY;
esp_efuse_purpose_t actual_purpose = esp_efuse_get_key_purpose((esp_efuse_block_t)efuse_blk); #endif /* !SOC_ECDSA_SUPPORT_CURVE_SPECIFIC_KEY_PURPOSES */
if (actual_purpose != ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY) {
ESP_LOGE(TAG, "Efuse block %d has purpose %d, expected ECDSA_KEY (%d)", if (expected_key_purpose_low != esp_efuse_get_key_purpose((esp_efuse_block_t)low_blk)
efuse_blk, actual_purpose, ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY); #if SOC_ECDSA_SUPPORT_CURVE_SPECIFIC_KEY_PURPOSES && SOC_ECDSA_SUPPORT_CURVE_P384
|| expected_key_purpose_high != esp_efuse_get_key_purpose((esp_efuse_block_t)high_blk)
#endif
) {
ESP_LOGE(TAG, "Key burned in efuse has incorrect purpose");
return MBEDTLS_ERR_ECP_INVALID_KEY; return MBEDTLS_ERR_ECP_INVALID_KEY;
} }
#endif /* !SOC_ECDSA_SUPPORT_CURVE_SPECIFIC_KEY_PURPOSES */
return 0; return 0;
} }
@@ -224,7 +208,7 @@ int esp_ecdsa_load_pubkey(mbedtls_ecp_keypair *keypair, int efuse_blk)
bool use_km_key = (efuse_blk == USE_ECDSA_KEY_FROM_KEY_MANAGER)? true: false; bool use_km_key = (efuse_blk == USE_ECDSA_KEY_FROM_KEY_MANAGER)? true: false;
if (!use_km_key) { if (!use_km_key) {
int high_blk, low_blk; int high_blk, low_blk;
MBEDTLS_ECDSA_EXTRACT_KEY_BLOCKS(efuse_blk, high_blk, low_blk); HAL_ECDSA_EXTRACT_KEY_BLOCKS(efuse_blk, high_blk, low_blk);
if (!is_efuse_blk_valid(high_blk, low_blk)) { if (!is_efuse_blk_valid(high_blk, low_blk)) {
ESP_LOGE(TAG, "Invalid efuse block selected"); ESP_LOGE(TAG, "Invalid efuse block selected");
@@ -339,7 +323,7 @@ int esp_ecdsa_privkey_load_mpi(mbedtls_mpi *key, int efuse_blk)
bool use_km_key = (efuse_blk == USE_ECDSA_KEY_FROM_KEY_MANAGER)? true: false; bool use_km_key = (efuse_blk == USE_ECDSA_KEY_FROM_KEY_MANAGER)? true: false;
if (!use_km_key) { if (!use_km_key) {
int high_blk, low_blk; int high_blk, low_blk;
MBEDTLS_ECDSA_EXTRACT_KEY_BLOCKS(efuse_blk, high_blk, low_blk); HAL_ECDSA_EXTRACT_KEY_BLOCKS(efuse_blk, high_blk, low_blk);
if (!is_efuse_blk_valid(high_blk, low_blk)) { if (!is_efuse_blk_valid(high_blk, low_blk)) {
ESP_LOGE(TAG, "Invalid efuse block selected"); ESP_LOGE(TAG, "Invalid efuse block selected");
@@ -380,7 +364,7 @@ int esp_ecdsa_privkey_load_pk_context(mbedtls_pk_context *key_ctx, int efuse_blk
bool use_km_key = (efuse_blk == USE_ECDSA_KEY_FROM_KEY_MANAGER)? true: false; bool use_km_key = (efuse_blk == USE_ECDSA_KEY_FROM_KEY_MANAGER)? true: false;
if (!use_km_key) { if (!use_km_key) {
int high_blk, low_blk; int high_blk, low_blk;
MBEDTLS_ECDSA_EXTRACT_KEY_BLOCKS(efuse_blk, high_blk, low_blk); HAL_ECDSA_EXTRACT_KEY_BLOCKS(efuse_blk, high_blk, low_blk);
if (!is_efuse_blk_valid(high_blk, low_blk)) { if (!is_efuse_blk_valid(high_blk, low_blk)) {
ESP_LOGE(TAG, "Invalid efuse block selected"); ESP_LOGE(TAG, "Invalid efuse block selected");

View File

@@ -20,22 +20,6 @@ extern "C" {
#define USE_ECDSA_KEY_FROM_KEY_MANAGER INT_MAX #define USE_ECDSA_KEY_FROM_KEY_MANAGER INT_MAX
/* ECDSA key block combination macros - aliases to HAL macros */
/**
* @brief Macro to combine two key blocks into a single integer
* @note Least significant 4 bits stores block number of the low key block, and the next 4 more significant bits store the high key block number.
* @note example: HAL_ECDSA_COMBINE_KEY_BLOCKS(blk_high, blk_low)
*/
#define MBEDTLS_ECDSA_COMBINE_KEY_BLOCKS HAL_ECDSA_COMBINE_KEY_BLOCKS
/**
* @brief Macro to extract high and low key block numbers from a combined integer
* @note Extracts high block from bits 4-7 and low block from bits 0-3
* @note example: HAL_ECDSA_EXTRACT_KEY_BLOCKS(combined_blk, blk_high, blk_low)
*/
#define MBEDTLS_ECDSA_EXTRACT_KEY_BLOCKS HAL_ECDSA_EXTRACT_KEY_BLOCKS
/** /**
* @brief ECDSA private key context initialization config structure * @brief ECDSA private key context initialization config structure
* @note Contains configuration information like the efuse key block that should be used as the private key, * @note Contains configuration information like the efuse key block that should be used as the private key,
@@ -67,7 +51,7 @@ typedef struct {
* *
* @param keypair The mbedtls ECP key-pair structure * @param keypair The mbedtls ECP key-pair structure
* @param efuse_blk The efuse key block that should be used as the private key. * @param efuse_blk The efuse key block that should be used as the private key.
* The efuse block where ECDSA key is stored. If two blocks are used to store the key, then the macro MBEDTLS_ECDSA_COMBINE_KEY_BLOCKS() can be used to combine them. The macro is defined in this header file. * The efuse block where ECDSA key is stored. If two blocks are used to store the key, then the macro HAL_ECDSA_COMBINE_KEY_BLOCKS() can be used to combine them. The macro is defined in hal/ecdsa_types.h.
* @return - 0 if successful * @return - 0 if successful
* - MBEDTLS_ERR_ECP_BAD_INPUT_DATA if invalid ecp group id specified * - MBEDTLS_ERR_ECP_BAD_INPUT_DATA if invalid ecp group id specified
* - MBEDTLS_ERR_ECP_INVALID_KEY if efuse block with purpose ECDSA_KEY is not found * - MBEDTLS_ERR_ECP_INVALID_KEY if efuse block with purpose ECDSA_KEY is not found
@@ -87,7 +71,7 @@ int esp_ecdsa_load_pubkey(mbedtls_ecp_keypair *keypair, int efuse_blk);
* @param key The MPI in which this functions stores the hardware context. * @param key The MPI in which this functions stores the hardware context.
* This must be uninitialized * This must be uninitialized
* @param efuse_blk The efuse key block that should be used as the private key. * @param efuse_blk The efuse key block that should be used as the private key.
* The efuse block where ECDSA key is stored. If two blocks are used to store the key, then the macro MBEDTLS_ECDSA_COMBINE_KEY_BLOCKS() can be used to combine them. The macro is defined in this header file. * The efuse block where ECDSA key is stored. If two blocks are used to store the key, then the macro HAL_ECDSA_COMBINE_KEY_BLOCKS() can be used to combine them. The macro is defined in hal/ecdsa_types.h.
* *
* @return - 0 if successful * @return - 0 if successful
* - -1 otherwise * - -1 otherwise
@@ -103,7 +87,7 @@ int esp_ecdsa_privkey_load_mpi(mbedtls_mpi *key, int efuse_blk);
* @param key_ctx The context in which this functions stores the hardware context. * @param key_ctx The context in which this functions stores the hardware context.
* This must be uninitialized * This must be uninitialized
* @param efuse_blk The efuse key block that should be used as the private key. * @param efuse_blk The efuse key block that should be used as the private key.
* The efuse block where ECDSA key is stored. If two blocks are used to store the key, then the macro MBEDTLS_ECDSA_COMBINE_KEY_BLOCKS() can be used to combine them. The macro is defined in this header file. * The efuse block where ECDSA key is stored. If two blocks are used to store the key, then the macro HAL_ECDSA_COMBINE_KEY_BLOCKS() can be used to combine them. The macro is defined in hal/ecdsa_types.h.
* *
* @return - 0 if successful * @return - 0 if successful
* - -1 otherwise * - -1 otherwise

View File

@@ -375,7 +375,7 @@ TEST_CASE("mbedtls ECDSA signature generation on SECP256R1", "[mbedtls][efuse_ke
#ifdef SOC_ECDSA_SUPPORT_CURVE_P384 #ifdef SOC_ECDSA_SUPPORT_CURVE_P384
TEST_CASE("mbedtls ECDSA signature generation on SECP384R1", "[mbedtls][efuse_key]") TEST_CASE("mbedtls ECDSA signature generation on SECP384R1", "[mbedtls][efuse_key]")
{ {
uint8_t efuse_key_block = MBEDTLS_ECDSA_COMBINE_KEY_BLOCKS(SECP384R1_EFUSE_BLOCK_HIGH, SECP384R1_EFUSE_BLOCK_LOW); uint8_t efuse_key_block = HAL_ECDSA_COMBINE_KEY_BLOCKS(SECP384R1_EFUSE_BLOCK_HIGH, SECP384R1_EFUSE_BLOCK_LOW);
test_ecdsa_sign(MBEDTLS_ECP_DP_SECP384R1, sha, ecdsa384_pub_x, ecdsa384_pub_y, false, efuse_key_block); test_ecdsa_sign(MBEDTLS_ECP_DP_SECP384R1, sha, ecdsa384_pub_x, ecdsa384_pub_y, false, efuse_key_block);
} }
#endif /* SOC_ECDSA_SUPPORT_CURVE_P384 */ #endif /* SOC_ECDSA_SUPPORT_CURVE_P384 */
@@ -444,7 +444,7 @@ TEST_CASE("mbedtls ECDSA deterministic signature generation on SECP256R1", "[mbe
#ifdef SOC_ECDSA_SUPPORT_CURVE_P384 #ifdef SOC_ECDSA_SUPPORT_CURVE_P384
TEST_CASE("mbedtls ECDSA deterministic signature generation on SECP384R1", "[mbedtls][efuse_key]") TEST_CASE("mbedtls ECDSA deterministic signature generation on SECP384R1", "[mbedtls][efuse_key]")
{ {
uint8_t efuse_key_block = MBEDTLS_ECDSA_COMBINE_KEY_BLOCKS(SECP384R1_EFUSE_BLOCK_HIGH, SECP384R1_EFUSE_BLOCK_LOW); uint8_t efuse_key_block = HAL_ECDSA_COMBINE_KEY_BLOCKS(SECP384R1_EFUSE_BLOCK_HIGH, SECP384R1_EFUSE_BLOCK_LOW);
test_ecdsa_sign(MBEDTLS_ECP_DP_SECP384R1, sha, ecdsa384_pub_x, ecdsa384_pub_y, true, efuse_key_block); test_ecdsa_sign(MBEDTLS_ECP_DP_SECP384R1, sha, ecdsa384_pub_x, ecdsa384_pub_y, true, efuse_key_block);
} }
#endif /* SOC_ECDSA_SUPPORT_CURVE_P384 */ #endif /* SOC_ECDSA_SUPPORT_CURVE_P384 */
@@ -532,7 +532,7 @@ TEST_CASE("mbedtls ECDSA export public key on SECP256R1", "[mbedtls][efuse_key]"
#ifdef SOC_ECDSA_SUPPORT_CURVE_P384 #ifdef SOC_ECDSA_SUPPORT_CURVE_P384
TEST_CASE("mbedtls ECDSA export public key on SECP384R1", "[mbedtls][efuse_key]") TEST_CASE("mbedtls ECDSA export public key on SECP384R1", "[mbedtls][efuse_key]")
{ {
uint8_t efuse_key_block = MBEDTLS_ECDSA_COMBINE_KEY_BLOCKS(SECP384R1_EFUSE_BLOCK_HIGH, SECP384R1_EFUSE_BLOCK_LOW); uint8_t efuse_key_block = HAL_ECDSA_COMBINE_KEY_BLOCKS(SECP384R1_EFUSE_BLOCK_HIGH, SECP384R1_EFUSE_BLOCK_LOW);
test_ecdsa_export_pubkey(MBEDTLS_ECP_DP_SECP384R1, ecdsa384_pub_x, ecdsa384_pub_y, efuse_key_block); test_ecdsa_export_pubkey(MBEDTLS_ECP_DP_SECP384R1, ecdsa384_pub_x, ecdsa384_pub_y, efuse_key_block);
} }
#endif /* SOC_ECDSA_SUPPORT_CURVE_P384 */ #endif /* SOC_ECDSA_SUPPORT_CURVE_P384 */

View File

@@ -94,10 +94,22 @@ void esp_transport_ssl_set_client_cert_data(esp_transport_handle_t t, const char
* @brief Set SSL client key data for mutual authentication when using ECDSA peripheral. * @brief Set SSL client key data for mutual authentication when using ECDSA peripheral.
* *
* @param t ssl transport * @param t ssl transport
* @param[in] efuse_blk. The efuse block where ECDSA key is stored. If two blocks are used to store the key, then the macro ESP_TLS_ECDSA_COMBINE_KEY_BLOCKS() can be used to combine them. The macro is defined in esp_tls.h * @param[in] ecdsa_efuse_blk. The efuse block where ECDSA key is stored.
*/ */
void esp_transport_ssl_set_client_key_ecdsa_peripheral(esp_transport_handle_t t, uint8_t ecdsa_efuse_blk); void esp_transport_ssl_set_client_key_ecdsa_peripheral(esp_transport_handle_t t, uint8_t ecdsa_efuse_blk);
#if SOC_ECDSA_SUPPORT_CURVE_P384
/**
* @brief Set SSL client key data for mutual authentication when using ECDSA peripheral with extended key storage.
* This function is used when the ECDSA key requires multiple efuse blocks for storage (e.g., P-384 curve).
*
* @param t ssl transport
* @param[in] ecdsa_efuse_blk The efuse block where the lower part of ECDSA key is stored
* @param[in] ecdsa_efuse_blk_high The efuse block where the upper part of ECDSA key is stored (required for P-384 and larger curves)
*/
void esp_transport_ssl_set_client_key_ecdsa_peripheral_extended(esp_transport_handle_t t, uint8_t ecdsa_efuse_blk, uint8_t ecdsa_efuse_blk_high);
#endif
/** /**
* @brief Set ECDSA curve for SSL client when using ECDSA peripheral. * @brief Set ECDSA curve for SSL client when using ECDSA peripheral.
* *

View File

@@ -422,6 +422,16 @@ void esp_transport_ssl_set_client_key_ecdsa_peripheral(esp_transport_handle_t t,
ssl->cfg.ecdsa_key_efuse_blk = ecdsa_efuse_blk; ssl->cfg.ecdsa_key_efuse_blk = ecdsa_efuse_blk;
} }
#if SOC_ECDSA_SUPPORT_CURVE_P384
void esp_transport_ssl_set_client_key_ecdsa_peripheral_extended(esp_transport_handle_t t, uint8_t ecdsa_efuse_blk, uint8_t ecdsa_efuse_blk_high)
{
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
ssl->cfg.use_ecdsa_peripheral = true;
ssl->cfg.ecdsa_key_efuse_blk = ecdsa_efuse_blk;
ssl->cfg.ecdsa_key_efuse_blk_high = ecdsa_efuse_blk_high;
}
#endif
void esp_transport_ssl_set_ecdsa_curve(esp_transport_handle_t t, esp_tls_ecdsa_curve_t curve) void esp_transport_ssl_set_ecdsa_curve(esp_transport_handle_t t, esp_tls_ecdsa_curve_t curve)
{ {
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t); GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);

View File

@@ -25,46 +25,27 @@ On {IDF_TARGET_NAME}, the ECDSA module works with a secret key burnt into an eFu
ECDSA Key Storage ECDSA Key Storage
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
ECDSA private keys are stored in eFuse key blocks. The number of key blocks required depends on the curve size: .. only:: SOC_ECDSA_SUPPORT_CURVE_P384
- **P-192 and P-256 curves**: Require one eFuse key block (256 bits) ECDSA private keys are stored in eFuse key blocks. The number of key blocks required depends on the curve size:
- **P-384 curve**: Requires two eFuse key blocks (512 bits total)
When using the P-384 curve or any other curves that require two key blocks, you must use the appropriate macro to combine the block numbers into a single integer that the ECDSA peripheral can understand: - **P-256 curve**: Require one eFuse key block (256 bits)
- **P-384 curve**: Requires two eFuse key blocks (512 bits total)
- **For mbedTLS applications**: Use :c:macro:`MBEDTLS_ECDSA_COMBINE_KEY_BLOCKS` macro (defined in ``ecdsa/ecdsa_alt.h``) For curves requiring two key blocks (like P-384), configure the following fields:
- **For HAL applications**: Use :c:macro:`HAL_ECDSA_COMBINE_KEY_BLOCKS` macro (defined in ``hal/ecdsa_types.h``)
- **For ESP-TLS applications**: Use :c:macro:`ESP_TLS_ECDSA_COMBINE_KEY_BLOCKS` macro (defined in ``esp_tls.h``)
You can also extract the individual block numbers using the corresponding extract macro: - Set :cpp:member:`esp_tls_cfg_t::ecdsa_key_efuse_blk` to the low block number
- Set :cpp:member:`esp_tls_cfg_t::ecdsa_key_efuse_blk_high` to the high block number
- **For mbedTLS applications**: Use :c:macro:`MBEDTLS_ECDSA_EXTRACT_KEY_BLOCKS` macro For single-block curves (like P-256), only set :cpp:member:`esp_tls_cfg_t::ecdsa_key_efuse_blk` and leave :cpp:member:`esp_tls_cfg_t::ecdsa_key_efuse_blk_high` as 0 or unassigned.
- **For HAL applications**: Use :c:macro:`HAL_ECDSA_EXTRACT_KEY_BLOCKS` macro
- **For ESP-TLS applications**: Use :c:macro:`ESP_TLS_ECDSA_EXTRACT_KEY_BLOCKS` macro
Here is an example of how to use these macros: .. only:: not SOC_ECDSA_SUPPORT_CURVE_P384
.. code-block:: c ECDSA private keys are stored in eFuse key blocks. One eFuse key block (256 bits) is required for P-256 curve.
#include "ecdsa/ecdsa_alt.h" Configure the following field:
// Example: Using P-384 curve which requires two key blocks - Set :cpp:member:`esp_tls_cfg_t::ecdsa_key_efuse_blk` to the block number and leave :cpp:member:`esp_tls_cfg_t::ecdsa_key_efuse_blk_high` as 0 or unassigned.
// Assuming you want to use key blocks 4 and 5
uint8_t block_low = 4; // Lower key block
uint8_t block_high = 5; // Higher key block
// Combine the two block numbers into a single integer
// Note: First parameter is high block, second parameter is low block
uint16_t combined_blocks = MBEDTLS_ECDSA_COMBINE_KEY_BLOCKS(block_high, block_low);
// Use the combined_blocks value in your ECDSA operations
// This value can be passed to mbedTLS ECDSA functions
// To extract the individual block numbers later
uint8_t extracted_block_low, extracted_block_high;
MBEDTLS_ECDSA_EXTRACT_KEY_BLOCKS(combined_blocks, &extracted_block_high, &extracted_block_low);
// extracted_block_low will be 4, extracted_block_high will be 5
ECDSA key can be programmed externally through ``idf.py`` script. Here is an example of how to program the ECDSA key: ECDSA key can be programmed externally through ``idf.py`` script. Here is an example of how to program the ECDSA key:

View File

@@ -54,8 +54,9 @@ The ECDSA peripheral can be used for the underlying TLS connection in the HTTP c
esp_http_client_config_t cfg = { esp_http_client_config_t cfg = {
/* other configurations options */ /* other configurations options */
.use_ecdsa_peripheral = true, .use_ecdsa_peripheral = true,
.ecdsa_key_efuse_blk = /* efuse block with ecdsa private key */, .ecdsa_key_efuse_blk = 4, // Low eFuse block for ECDSA key
.ecdsa_curve = ESP_TLS_ECDSA_CURVE_SECP256R1, // or ESP_TLS_ECDSA_CURVE_SECP384R1 .ecdsa_key_efuse_blk_high = 5, // High eFuse block for ECDSA key (SECP384R1 only)
.ecdsa_curve = ESP_TLS_ECDSA_CURVE_SECP384R1, // set this to ESP_TLS_ECDSA_CURVE_SECP256R1 for SECP256R1 curve
}; };

View File

@@ -217,17 +217,16 @@ To enable the secure element support, and use it in your project for TLS connect
ESP-TLS provides support for using the ECDSA peripheral with {IDF_TARGET_NAME}. The use of ECDSA peripheral is supported only when ESP-TLS is used with MbedTLS as its underlying SSL/TLS stack. The ECDSA private key should be present in the eFuse for using the ECDSA peripheral. Please refer to :doc:`ECDSA Guide <../peripherals/ecdsa>` for programming the ECDSA key in the eFuse. ESP-TLS provides support for using the ECDSA peripheral with {IDF_TARGET_NAME}. The use of ECDSA peripheral is supported only when ESP-TLS is used with MbedTLS as its underlying SSL/TLS stack. The ECDSA private key should be present in the eFuse for using the ECDSA peripheral. Please refer to :doc:`ECDSA Guide <../peripherals/ecdsa>` for programming the ECDSA key in the eFuse.
To use ECDSA peripheral with ESP-TLS, set :cpp:member:`esp_tls_cfg_t::use_ecdsa_peripheral` to `true`, set :cpp:member:`esp_tls_cfg_t::ecdsa_key_efuse_blk` to the eFuse block ID in which ECDSA private key is stored, and set :cpp:member:`esp_tls_cfg_t::ecdsa_curve` to specify the ECDSA curve to use. This will enable the use of ECDSA peripheral for private key operations. As the client private key is already present in the eFuse, it need not be supplied to the :cpp:type:`esp_tls_cfg_t` structure. Please see the below code snippet for enabling the use of ECDSA peripheral for a given ESP-TLS connection.
This will enable the use of ECDSA peripheral for private key operations. As the client private key is already present in the eFuse, it needs not be supplied to the :cpp:type:`esp_tls_cfg_t` structure.
.. code-block:: c .. code-block:: c
#include "esp_tls.h" #include "esp_tls.h"
esp_tls_cfg_t cfg = { esp_tls_cfg_t cfg = {
.use_ecdsa_peripheral = true, .use_ecdsa_peripheral = true,
.ecdsa_key_efuse_blk = /* efuse block with ecdsa private key */, .ecdsa_key_efuse_blk = 4, // Low eFuse block for ECDSA key
.ecdsa_curve = ESP_TLS_ECDSA_CURVE_SECP256R1, // or ESP_TLS_ECDSA_CURVE_SECP384R1 .ecdsa_key_efuse_blk_high = 5, // High eFuse block for ECDSA key (SECP384R1 only)
.ecdsa_curve = ESP_TLS_ECDSA_CURVE_SECP384R1, // set this to ESP_TLS_ECDSA_CURVE_SECP256R1 for SECP256R1 curve
}; };
.. note:: .. note::

View File

@@ -156,9 +156,6 @@ It is possible to set authentication parameters through the :cpp:class:`authenti
* :cpp:member:`certificate <esp_mqtt_client_config_t::credentials_t::authentication_t::certificate>` and :cpp:member:`key <esp_mqtt_client_config_t::credentials_t::authentication_t::key>`: mutual authentication with TLS, and both can be provided in PEM or DER format * :cpp:member:`certificate <esp_mqtt_client_config_t::credentials_t::authentication_t::certificate>` and :cpp:member:`key <esp_mqtt_client_config_t::credentials_t::authentication_t::key>`: mutual authentication with TLS, and both can be provided in PEM or DER format
* :cpp:member:`use_secure_element <esp_mqtt_client_config_t::credentials_t::authentication_t::use_secure_element>`: use secure element (ATECC608A) interfaced to ESP32 series * :cpp:member:`use_secure_element <esp_mqtt_client_config_t::credentials_t::authentication_t::use_secure_element>`: use secure element (ATECC608A) interfaced to ESP32 series
* :cpp:member:`ds_data <esp_mqtt_client_config_t::credentials_t::authentication_t::ds_data>`: use Digital Signature Peripheral available in some Espressif devices * :cpp:member:`ds_data <esp_mqtt_client_config_t::credentials_t::authentication_t::ds_data>`: use Digital Signature Peripheral available in some Espressif devices
* :cpp:member:`use_ecdsa_peripheral <esp_mqtt_client_config_t::credentials_t::authentication_t::use_ecdsa_peripheral>`: use ECDSA Peripheral available in some Espressif devices
* :cpp:member:`ecdsa_key_efuse_blk <esp_mqtt_client_config_t::credentials_t::authentication_t::ecdsa_key_efuse_blk>`: eFuse block containing ECDSA private key
* :cpp:member:`ecdsa_curve <esp_mqtt_client_config_t::credentials_t::authentication_t::ecdsa_curve>`: ECDSA curve to use (ESP_TLS_ECDSA_CURVE_SECP256R1 or ESP_TLS_ECDSA_CURVE_SECP384R1)
Session Session
^^^^^^^^^^^ ^^^^^^^^^^^

View File

@@ -25,46 +25,27 @@ ECDSA 外设可以为 TLS 双向身份验证等用例建立 **安全设备身份
ECDSA 密钥存储 ECDSA 密钥存储
^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
ECDSA 私钥存储在 eFuse 密钥块中。所需的密钥块数量取决于曲线大小: .. only:: SOC_ECDSA_SUPPORT_CURVE_P384
- **P-192 和 P-256 曲线**:需要一个 eFuse 密钥块256 位) ECDSA 私钥存储在 eFuse 密钥块中。所需的密钥块数量取决于曲线大小:
- **P-384 曲线**:需要两个 eFuse 密钥块(总共 512 位)
使用 P-384 曲线或其他需要两个密钥块的曲线时,必须使用相应的宏将两个密钥块编号组合为一个整数,以便 ECDSA 外设能够识别: - **P-256 曲线**:需要一个 eFuse 密钥块256 位)
- **P-384 曲线**:需要两个 eFuse 密钥块(总共 512 位)
- **对于 mbedTLS 应用程序**:使用 :c:macro:`MBEDTLS_ECDSA_COMBINE_KEY_BLOCKS` 宏(定义在 ``ecdsa/ecdsa_alt.h`` 中) 对于需要两个密钥块的曲线(如 P-384配置以下字段
- **对于 HAL 应用程序**:使用 :c:macro:`HAL_ECDSA_COMBINE_KEY_BLOCKS` 宏(定义在 ``hal/ecdsa_types.h`` 中)
- **对于 ESP-TLS 应用程序**:使用 :c:macro:`ESP_TLS_ECDSA_COMBINE_KEY_BLOCKS` 宏(定义在 ``esp_tls.h`` 中)
你还可以使用相应的提取宏来获取各个密钥块编号: -:cpp:member:`esp_tls_cfg_t::ecdsa_key_efuse_blk` 设置为低块号
-:cpp:member:`esp_tls_cfg_t::ecdsa_key_efuse_blk_high` 设置为高块号
- **对于 mbedTLS 应用程序**:使用 :c:macro:`MBEDTLS_ECDSA_EXTRACT_KEY_BLOCKS` 对于单块曲线(如 P-256只需设置 :cpp:member:`esp_tls_cfg_t::ecdsa_key_efuse_blk`,将 :cpp:member:`esp_tls_cfg_t::ecdsa_key_efuse_blk_high` 保持为 0 或不赋值。
- **对于 HAL 应用程序**:使用 :c:macro:`HAL_ECDSA_EXTRACT_KEY_BLOCKS`
- **对于 ESP-TLS 应用程序**:使用 :c:macro:`ESP_TLS_ECDSA_EXTRACT_KEY_BLOCKS`
以下是使用这些宏的示例: .. only:: not SOC_ECDSA_SUPPORT_CURVE_P384
.. code-block:: c ECDSA 私钥存储在 eFuse 密钥块中。一个 eFuse 密钥块256 位)是 P-256 曲线所需的。
#include "ecdsa/ecdsa_alt.h" 配置以下字段:
// 示例:使用需要两个密钥块的 P-384 曲线 -:cpp:member:`esp_tls_cfg_t::ecdsa_key_efuse_blk` 设置为块号,将 :cpp:member:`esp_tls_cfg_t::ecdsa_key_efuse_blk_high` 保持为 0 或不赋值。
// 假设要使用密钥块 4 和 5
uint8_t block_low = 4; // 较低编号的密钥块
uint8_t block_high = 5; // 较高编号的密钥块
// 将两个密钥块编号组合成一个整数
// 注意:第一个参数是高位块,第二个参数是低位块
uint16_t combined_blocks = MBEDTLS_ECDSA_COMBINE_KEY_BLOCKS(block_high, block_low);
// 在 ECDSA 操作中使用 combined_blocks 值
// 此值可以传递给 mbedTLS ECDSA 函数
// 之后提取各个密钥块编号
uint8_t extracted_block_low, extracted_block_high;
MBEDTLS_ECDSA_EXTRACT_KEY_BLOCKS(combined_blocks, &extracted_block_high, &extracted_block_low);
// extracted_block_low 的值为 4extracted_block_high 的值为 5
ECDSA 密钥可以通过 ``idf.py`` 脚本在外部编程。以下是关于编程 ECDSA 密钥的示例: ECDSA 密钥可以通过 ``idf.py`` 脚本在外部编程。以下是关于编程 ECDSA 密钥的示例:

View File

@@ -54,8 +54,9 @@ ECDSA 外设可用于 HTTP 客户端连接中的底层 TLS 连接。详细内容
esp_http_client_config_t cfg = { esp_http_client_config_t cfg = {
/* other configurations options */ /* other configurations options */
.use_ecdsa_peripheral = true, .use_ecdsa_peripheral = true,
.ecdsa_key_efuse_blk = /* 存储 ECDSA 钥的 eFuse 块 */, .ecdsa_key_efuse_blk = 4, // ECDSA 钥的 eFuse 块
.ecdsa_curve = ESP_TLS_ECDSA_CURVE_SECP256R1, // 或 ESP_TLS_ECDSA_CURVE_SECP384R1 .ecdsa_key_efuse_blk_high = 5, // ECDSA 密钥的高 eFuse 块(仅 SECP384R1
.ecdsa_curve = ESP_TLS_ECDSA_CURVE_SECP384R1, // 设置为 ESP_TLS_ECDSA_CURVE_SECP256R1 以使用 SECP256R1 曲线
}; };

View File

@@ -217,8 +217,6 @@ ESP-TLS 支持在 ESP32 系列芯片上使用 ATECC608A 加密芯片,但必须
ESP-TLS 支持在 {IDF_TARGET_NAME} 中使用 ECDSA 外设。使用 ECDSA 外设时ESP-TLS 必须与 MbedTLS 一起作为底层 SSL/TLS 协议栈,并且 ECDSA 的私钥应存储在 eFuse 中。请参考 :doc:`ECDSA 指南 <../peripherals/ecdsa>`,了解如何在 eFuse 中烧写 ECDSA 密钥。 ESP-TLS 支持在 {IDF_TARGET_NAME} 中使用 ECDSA 外设。使用 ECDSA 外设时ESP-TLS 必须与 MbedTLS 一起作为底层 SSL/TLS 协议栈,并且 ECDSA 的私钥应存储在 eFuse 中。请参考 :doc:`ECDSA 指南 <../peripherals/ecdsa>`,了解如何在 eFuse 中烧写 ECDSA 密钥。
在 ESP-TLS 中启用 ECDSA 外设前,请将 :cpp:member:`esp_tls_cfg_t::use_ecdsa_peripheral` 设置为 `true`,将 :cpp:member:`esp_tls_cfg_t::ecdsa_key_efuse_blk` 设置为存储了 ECDSA 密钥的 eFuse 块 ID并将 :cpp:member:`esp_tls_cfg_t::ecdsa_curve` 设置为指定要使用的 ECDSA 曲线。
这样就可以使用 ECDSA 外设进行私钥操作。由于客户私钥已经存储在 eFuse 中,因此无需将其传递给 :cpp:type:`esp_tls_cfg_t` 这样就可以使用 ECDSA 外设进行私钥操作。由于客户私钥已经存储在 eFuse 中,因此无需将其传递给 :cpp:type:`esp_tls_cfg_t`
.. code-block:: c .. code-block:: c
@@ -226,8 +224,9 @@ ESP-TLS 支持在 ESP32 系列芯片上使用 ATECC608A 加密芯片,但必须
#include "esp_tls.h" #include "esp_tls.h"
esp_tls_cfg_t cfg = { esp_tls_cfg_t cfg = {
.use_ecdsa_peripheral = true, .use_ecdsa_peripheral = true,
.ecdsa_key_efuse_blk = /* 存储 ECDSA 钥的 eFuse 块 */, .ecdsa_key_efuse_blk = 4, // ECDSA 钥的 eFuse 块
.ecdsa_curve = ESP_TLS_ECDSA_CURVE_SECP256R1, // 或 ESP_TLS_ECDSA_CURVE_SECP384R1 .ecdsa_key_efuse_blk_high = 5, // ECDSA 密钥的高 eFuse 块(仅 SECP384R1
.ecdsa_curve = ESP_TLS_ECDSA_CURVE_SECP384R1, // 设置为 ESP_TLS_ECDSA_CURVE_SECP256R1 以使用 SECP256R1 曲线
}; };
.. note:: .. note::

View File

@@ -156,9 +156,6 @@ ESP-MQTT 库将始终重新传输未确认的 QoS 1 和 2 发布消息,以避
* * :cpp:member:`certificate <esp_mqtt_client_config_t::credentials_t::authentication_t::certificate>`:cpp:member:`key <esp_mqtt_client_config_t::credentials_t::authentication_t::key>`:进行双向 TLS 身份验证PEM 或 DER 格式均可 * * :cpp:member:`certificate <esp_mqtt_client_config_t::credentials_t::authentication_t::certificate>`:cpp:member:`key <esp_mqtt_client_config_t::credentials_t::authentication_t::key>`:进行双向 TLS 身份验证PEM 或 DER 格式均可
* :cpp:member:`use_secure_element <esp_mqtt_client_config_t::credentials_t::authentication_t::use_secure_element>`:使用 ESP32 系列中的安全元素 (ATECC608A) * :cpp:member:`use_secure_element <esp_mqtt_client_config_t::credentials_t::authentication_t::use_secure_element>`:使用 ESP32 系列中的安全元素 (ATECC608A)
* :cpp:member:`ds_data <esp_mqtt_client_config_t::credentials_t::authentication_t::ds_data>`:使用某些乐鑫设备的数字签名外设 * :cpp:member:`ds_data <esp_mqtt_client_config_t::credentials_t::authentication_t::ds_data>`:使用某些乐鑫设备的数字签名外设
* :cpp:member:`use_ecdsa_peripheral <esp_mqtt_client_config_t::credentials_t::authentication_t::use_ecdsa_peripheral>`:使用某些乐鑫设备中可用的 ECDSA 外设
* :cpp:member:`ecdsa_key_efuse_blk <esp_mqtt_client_config_t::credentials_t::authentication_t::ecdsa_key_efuse_blk>`:包含 ECDSA 私钥的 eFuse 块
* :cpp:member:`ecdsa_curve <esp_mqtt_client_config_t::credentials_t::authentication_t::ecdsa_curve>`:要使用的 ECDSA 曲线ESP_TLS_ECDSA_CURVE_SECP256R1 或 ESP_TLS_ECDSA_CURVE_SECP384R1
会话 会话
^^^^^^^^^^^^ ^^^^^^^^^^^^