feat: added new config member to provide ecdsa curve type

This commit is contained in:
nilesh.kale
2025-10-16 14:48:13 +08:00
committed by Nilesh Kale
parent 851602ed8e
commit ba0618b672
16 changed files with 120 additions and 84 deletions
+11
View File
@@ -112,6 +112,13 @@ typedef enum {
ESP_TLS_DYN_BUF_STRATEGY_MAX, /*!< to indicate max */
} esp_tls_dyn_buf_strategy_t;
/**
* @brief ECDSA curve options for TLS connections
*/
typedef enum {
ESP_TLS_ECDSA_CURVE_SECP256R1 = 0, /*!< Use SECP256R1 curve */
ESP_TLS_ECDSA_CURVE_SECP384R1, /*!< Use SECP384R1 curve */
} esp_tls_ecdsa_curve_t;
/**
* @brief ESP-TLS configuration parameters
@@ -187,6 +194,8 @@ typedef struct esp_tls_cfg {
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. */
esp_tls_ecdsa_curve_t ecdsa_curve; /*!< ECDSA curve to use (SECP256R1 or SECP384R1) */
bool non_block; /*!< Configure non-blocking mode. If set to true the
underneath socket will be configured in non
blocking mode after tls session is established */
@@ -331,6 +340,8 @@ typedef struct esp_tls_cfg_server {
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. */
esp_tls_ecdsa_curve_t ecdsa_curve; /*!< ECDSA curve to use (SECP256R1 or SECP384R1) */
bool use_secure_element; /*!< Enable this option to use secure element or
atecc608a chip */
+39 -81
View File
@@ -51,78 +51,6 @@ static esp_err_t esp_mbedtls_init_pk_ctx_for_ds(const void *pki);
static const char *TAG = "esp-tls-mbedtls";
static mbedtls_x509_crt *global_cacert = NULL;
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
/**
* @brief Determine the ECDSA curve group ID based on the efuse block's key purpose
*
* This function reads the key purpose from the specified efuse block and returns the appropriate
* ECDSA curve group ID. It handles both curve-specific key purposes (when SOC_ECDSA_SUPPORT_CURVE_SPECIFIC_KEY_PURPOSES
* is defined) and generic ECDSA key purpose.
*
* For SECP384R1 curve, it checks both high and low key blocks when supported.
* For SECP192R1 and SECP256R1 curves, it checks the single block.
* For generic ECDSA key purpose, it defaults to SECP256R1.
*
* @param[in] efuse_blk The efuse block(s) to check (can be combined for 384-bit keys)
*
* @return
* - MBEDTLS_ECP_DP_SECP192R1 if block has P192 key purpose
* - MBEDTLS_ECP_DP_SECP256R1 if block has P256 key purpose or generic ECDSA key purpose
* - MBEDTLS_ECP_DP_SECP384R1 if blocks have P384 key purposes
* - MBEDTLS_ECP_DP_NONE if block has invalid or unsupported key purpose
*/
static mbedtls_ecp_group_id esp_tls_get_curve_from_efuse_block(uint8_t efuse_blk)
{
#if SOC_ECDSA_SUPPORT_CURVE_SPECIFIC_KEY_PURPOSES
esp_efuse_purpose_t key_purpose;
// For P384, we need to check both blocks
if (efuse_blk > 0xF) { // Combined blocks for P384
#if SOC_ECDSA_SUPPORT_CURVE_P384
int high_blk, low_blk;
MBEDTLS_ECDSA_EXTRACT_KEY_BLOCKS(efuse_blk, high_blk, low_blk);
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 (low_purpose == ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY_P384_L && high_purpose == ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY_P384_H) {
return MBEDTLS_ECP_DP_SECP384R1;
}
// If we reach here, the key purposes don't match P384 requirements
ESP_LOGE(TAG, "Efuse blocks %d,%d have invalid P384 key purposes: low=%d, high=%d",
low_blk, high_blk, low_purpose, high_purpose);
return MBEDTLS_ECP_DP_NONE;
#else
// P384 not supported but combined blocks provided
ESP_LOGE(TAG, "P384 curve not supported but combined efuse blocks provided: %d", efuse_blk);
return MBEDTLS_ECP_DP_NONE;
#endif
} else { // Single block for P192 or P256
key_purpose = esp_efuse_get_key_purpose((esp_efuse_block_t)efuse_blk);
switch (key_purpose) {
case ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY_P192:
return MBEDTLS_ECP_DP_SECP192R1;
case ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY_P256:
return MBEDTLS_ECP_DP_SECP256R1;
default:
ESP_LOGE(TAG, "Efuse block %d has unsupported key purpose %d", efuse_blk, key_purpose);
return MBEDTLS_ECP_DP_NONE;
}
}
#else /* SOC_ECDSA_SUPPORT_CURVE_SPECIFIC_KEY_PURPOSES */
// For generic ECDSA key purpose, default to P256
esp_efuse_purpose_t key_purpose = esp_efuse_get_key_purpose((esp_efuse_block_t)efuse_blk);
if (key_purpose == ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY) {
return MBEDTLS_ECP_DP_SECP256R1;
}
#endif /* !SOC_ECDSA_SUPPORT_CURVE_SPECIFIC_KEY_PURPOSES */
ESP_LOGE(TAG, "Efuse block %d has invalid key purpose", efuse_blk);
return MBEDTLS_ECP_DP_NONE;
}
#endif /* CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN */
#if CONFIG_NEWLIB_NANO_FORMAT
#define NEWLIB_NANO_SSIZE_T_COMPAT_FORMAT "X"
#define NEWLIB_NANO_SIZE_T_COMPAT_FORMAT PRIu32
@@ -133,6 +61,34 @@ static mbedtls_ecp_group_id esp_tls_get_curve_from_efuse_block(uint8_t efuse_blk
#define NEWLIB_NANO_SIZE_T_COMPAT_CAST(size_t_var) size_t_var
#endif
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
/**
* @brief Convert ESP-TLS ECDSA curve enum to mbedTLS group ID
* @param curve ESP-TLS ECDSA curve enum value
* @param grp_id Pointer to store the converted mbedTLS group ID
* @return ESP_OK on success, ESP_ERR_INVALID_ARG on invalid curve
*/
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) {
case ESP_TLS_ECDSA_CURVE_SECP256R1:
*grp_id = MBEDTLS_ECP_DP_SECP256R1;
break;
case ESP_TLS_ECDSA_CURVE_SECP384R1:
*grp_id = MBEDTLS_ECP_DP_SECP384R1;
break;
default:
ESP_LOGE(TAG, "Invalid ECDSA curve specified: %d", curve);
return ESP_ERR_INVALID_ARG;
}
return ESP_OK;
}
#endif
/* This function shall return the error message when appropriate log level has been set, otherwise this function shall do nothing */
static void mbedtls_print_error_msg(int error)
{
@@ -641,11 +597,11 @@ static esp_err_t set_pki_context(esp_tls_t *tls, const esp_tls_pki_t *pki)
#endif
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
if (tls->use_ecdsa_peripheral) {
// Determine the curve group ID based on the efuse block's key purpose
mbedtls_ecp_group_id grp_id = esp_tls_get_curve_from_efuse_block(tls->ecdsa_efuse_blk);
if (grp_id == MBEDTLS_ECP_DP_NONE) {
ESP_LOGE(TAG, "Failed to determine curve group ID from efuse block %d", tls->ecdsa_efuse_blk);
return ESP_ERR_INVALID_ARG;
// Determine the curve group ID based on user preference
mbedtls_ecp_group_id grp_id;
esp_err_t esp_ret = esp_tls_ecdsa_curve_to_mbedtls_group_id(tls->ecdsa_curve, &grp_id);
if (esp_ret != ESP_OK) {
return esp_ret;
}
esp_ecdsa_pk_conf_t conf = {
@@ -838,6 +794,7 @@ static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls)
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
tls->use_ecdsa_peripheral = cfg->use_ecdsa_peripheral;
tls->ecdsa_efuse_blk = cfg->ecdsa_key_efuse_blk;
tls->ecdsa_curve = cfg->ecdsa_curve;
esp_tls_pki_t pki = {
.public_cert = &tls->servercert,
.pk_key = &tls->serverkey,
@@ -1085,6 +1042,7 @@ esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
tls->use_ecdsa_peripheral = cfg->use_ecdsa_peripheral;
tls->ecdsa_efuse_blk = cfg->ecdsa_key_efuse_blk;
tls->ecdsa_curve = cfg->ecdsa_curve;
esp_tls_pki_t pki = {
.public_cert = &tls->clientcert,
.pk_key = &tls->clientkey,
@@ -1101,10 +1059,10 @@ esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t
return esp_ret;
}
mbedtls_ecp_group_id grp_id = esp_tls_get_curve_from_efuse_block(tls->ecdsa_efuse_blk);
if (grp_id == MBEDTLS_ECP_DP_NONE) {
ESP_LOGE(TAG, "Failed to determine curve group ID from efuse block %d", tls->ecdsa_efuse_blk);
return ESP_ERR_INVALID_ARG;
mbedtls_ecp_group_id grp_id;
esp_ret = esp_tls_ecdsa_curve_to_mbedtls_group_id(tls->ecdsa_curve, &grp_id);
if (esp_ret != ESP_OK) {
return esp_ret;
}
// Create dynamic ciphersuite array based on curve
@@ -15,6 +15,7 @@
#include <fcntl.h>
#include "esp_err.h"
#include "esp_tls_errors.h"
#include "esp_tls.h"
#ifdef CONFIG_ESP_TLS_USING_MBEDTLS
#include "mbedtls/platform.h"
#include "mbedtls/net_sockets.h"
@@ -67,6 +68,7 @@ struct esp_tls {
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
bool use_ecdsa_peripheral; /*!< Use the ECDSA peripheral for the private key operations. */
uint8_t ecdsa_efuse_blk; /*!< The efuse block number where the ECDSA key is stored. */
esp_tls_ecdsa_curve_t ecdsa_curve; /*!< ECDSA curve to use (SECP256R1 or SECP384R1) */
#endif
#if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 && CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS
unsigned char *client_session; /*!< Pointer for the serialized client session ticket context. */