feat: added new config member to provide ecdsa curve type

This commit is contained in:
nilesh.kale
2025-07-14 13:49:36 +05:30
parent 68f06a94bd
commit 08e781c876
16 changed files with 114 additions and 84 deletions

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 */

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)
{
@@ -636,11 +592,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 = {
@@ -833,6 +789,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,
@@ -1080,6 +1037,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,
@@ -1096,10 +1054,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

View File

@@ -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. */

View File

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

View File

@@ -928,6 +928,8 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
if (config->use_ecdsa_peripheral) {
esp_transport_ssl_set_client_key_ecdsa_peripheral(ssl, config->ecdsa_key_efuse_blk);
// Set the ECDSA curve
esp_transport_ssl_set_ecdsa_curve(ssl, config->ecdsa_curve);
}
#endif
if (config->client_key_password && config->client_key_password_len > 0) {

View File

@@ -11,6 +11,7 @@
#include "sdkconfig.h"
#include "esp_err.h"
#include <sys/socket.h>
#include "esp_tls.h"
#ifdef __cplusplus
extern "C" {
@@ -179,6 +180,7 @@ typedef struct {
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
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 */
esp_tls_ecdsa_curve_t ecdsa_curve; /*!< ECDSA curve to use (SECP256R1 or SECP384R1) */
#endif
const char *user_agent; /*!< The User Agent string to send with HTTP requests */
esp_http_client_method_t method; /*!< HTTP Method */

View File

@@ -103,6 +103,9 @@ struct httpd_ssl_config {
/*!< 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;
/*!< ECDSA curve to use (SECP256R1 or SECP384R1) */
esp_tls_ecdsa_curve_t ecdsa_curve;
/** Transport Mode (default secure) */
httpd_ssl_transport_mode_t transport_mode;
@@ -186,6 +189,7 @@ typedef struct httpd_ssl_config httpd_ssl_config_t;
.prvtkey_len = 0, \
.use_ecdsa_peripheral = false, \
.ecdsa_key_efuse_blk = 0, \
.ecdsa_curve = ESP_TLS_ECDSA_CURVE_SECP256R1, \
.transport_mode = HTTPD_SSL_TRANSPORT_SECURE, \
.port_secure = 443, \
.port_insecure = 80, \

View File

@@ -333,6 +333,7 @@ static esp_err_t create_secure_context(const struct httpd_ssl_config *config, ht
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
(*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_curve = config->ecdsa_curve;
#else
ESP_LOGE(TAG, "Please enable the support for signing using ECDSA peripheral in menuconfig.");
ret = ESP_ERR_NOT_SUPPORTED;

View File

@@ -97,6 +97,14 @@ void esp_transport_ssl_set_client_cert_data(esp_transport_handle_t t, const char
* @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
*/
void esp_transport_ssl_set_client_key_ecdsa_peripheral(esp_transport_handle_t t, uint8_t ecdsa_efuse_blk);
/**
* @brief Set ECDSA curve for SSL client when using ECDSA peripheral.
*
* @param t ssl transport
* @param[in] curve ECDSA curve to use
*/
void esp_transport_ssl_set_ecdsa_curve(esp_transport_handle_t t, esp_tls_ecdsa_curve_t curve);
#endif
/**

View File

@@ -421,6 +421,12 @@ void esp_transport_ssl_set_client_key_ecdsa_peripheral(esp_transport_handle_t t,
ssl->cfg.use_ecdsa_peripheral = true;
ssl->cfg.ecdsa_key_efuse_blk = ecdsa_efuse_blk;
}
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);
ssl->cfg.ecdsa_curve = curve;
}
#endif
void esp_transport_ssl_set_client_cert_data_der(esp_transport_handle_t t, const char *data, int len)

View File

@@ -44,6 +44,20 @@ A secure element (ATECC608) can be also used for the underlying TLS connection i
.use_secure_element = true,
};
Use ECDSA Peripheral for TLS
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The ECDSA peripheral can be used for the underlying TLS connection in the HTTP client connection. Please refer to the **ECDSA Peripheral with ESP-TLS** section in the :doc:`ESP-TLS documentation </api-reference/protocols/esp_tls>` for more details. The HTTP client can be configured to use ECDSA peripheral as follows:
.. code-block:: c
esp_http_client_config_t cfg = {
/* other configurations options */
.use_ecdsa_peripheral = true,
.ecdsa_key_efuse_blk = /* efuse block with ecdsa private key */,
.ecdsa_curve = ESP_TLS_ECDSA_CURVE_SECP256R1, // or ESP_TLS_ECDSA_CURVE_SECP384R1
};
HTTPS Request
-------------

View File

@@ -217,7 +217,7 @@ 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.
To use ECDSA peripheral with ESP-TLS, set :cpp:member:`esp_tls_cfg_t::use_ecdsa_peripheral` to `true`, and set :cpp:member:`esp_tls_cfg_t::ecdsa_key_efuse_blk` to the eFuse block ID in which ECDSA private key is stored.
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 needs not be supplied to the :cpp:type:`esp_tls_cfg_t` structure.
@@ -227,6 +227,7 @@ To enable the secure element support, and use it in your project for TLS connect
esp_tls_cfg_t cfg = {
.use_ecdsa_peripheral = true,
.ecdsa_key_efuse_blk = /* efuse block with ecdsa private key */,
.ecdsa_curve = ESP_TLS_ECDSA_CURVE_SECP256R1, // or ESP_TLS_ECDSA_CURVE_SECP384R1
};
.. note::

View File

@@ -156,6 +156,9 @@ 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:`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:`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
^^^^^^^^^^^

View File

@@ -44,6 +44,20 @@ HTTP 基本请求
.use_secure_element = true,
};
为 TLS 使用 ECDSA 外设
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ECDSA 外设可用于 HTTP 客户端连接中的底层 TLS 连接。详细内容请参考 :doc:`ESP-TLS 文档 </api-reference/protocols/esp_tls>` 中的 **ECDSA 外设与 ESP-TLS** 小节。可以按如下方式配置 HTTP 客户端以使用 ECDSA 外设:
.. code-block:: c
esp_http_client_config_t cfg = {
/* other configurations options */
.use_ecdsa_peripheral = true,
.ecdsa_key_efuse_blk = /* 存储 ECDSA 私钥的 eFuse 块 */,
.ecdsa_curve = ESP_TLS_ECDSA_CURVE_SECP256R1, // 或 ESP_TLS_ECDSA_CURVE_SECP384R1
};
HTTPS 请求
-----------

View File

@@ -217,7 +217,7 @@ 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 中启用 ECDSA 外设前,请将 :cpp:member:`esp_tls_cfg_t::use_ecdsa_peripheral` 设置为 `true`:cpp:member:`esp_tls_cfg_t::ecdsa_key_efuse_blk` 设置为存储了 ECDSA 密钥的 eFuse 块 ID。
在 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`
@@ -227,6 +227,7 @@ ESP-TLS 支持在 ESP32 系列芯片上使用 ATECC608A 加密芯片,但必须
esp_tls_cfg_t cfg = {
.use_ecdsa_peripheral = true,
.ecdsa_key_efuse_blk = /* 存储 ECDSA 私钥的 eFuse 块 */,
.ecdsa_curve = ESP_TLS_ECDSA_CURVE_SECP256R1, // 或 ESP_TLS_ECDSA_CURVE_SECP384R1
};
.. note::

View File

@@ -156,6 +156,9 @@ 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:`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:`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
会话
^^^^^^^^^^^^