mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
feat(esp-tls): Add unified private key interface via esp_key_config_t
Add ESP_KEY_SOURCE_BUFFER and ESP_KEY_SOURCE_PSA key sources so all
hardware backends (DS, ECDSA, secure element) are accessed via PSA
key IDs through a single esp_tls_cfg_t.client_key field.
(cherry picked from commit 36090b7161)
This commit is contained in:
@@ -22,7 +22,10 @@ endif()
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} esp-tls-crypto
|
||||
PRIV_INCLUDE_DIRS "private_include"
|
||||
REQUIRES mbedtls
|
||||
# mbedtls is public requirements because esp_tls.h
|
||||
# includes mbedtls header files.
|
||||
# esp_security is public because esp_tls.h includes esp_key_config.h
|
||||
REQUIRES mbedtls esp_security
|
||||
PRIV_REQUIRES ${priv_req})
|
||||
|
||||
|
||||
@@ -34,8 +37,3 @@ else()
|
||||
target_compile_definitions(${COMPONENT_LIB} PRIVATE ESP_TLS_WITH_LWIP=1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
if(CONFIG_ESP_TLS_USE_SECURE_ELEMENT)
|
||||
idf_component_optional_requires(PRIVATE espressif__esp-cryptoauthlib esp-cryptoauthlib)
|
||||
endif()
|
||||
|
||||
@@ -22,16 +22,6 @@ menu "ESP-TLS"
|
||||
esp_tls_stack_ops_t interface.
|
||||
endchoice
|
||||
|
||||
config ESP_TLS_USE_SECURE_ELEMENT
|
||||
bool "Use Secure Element (ATECC608A) with ESP-TLS"
|
||||
depends on ESP_TLS_USING_MBEDTLS
|
||||
select ATCA_MBEDTLS_ECDSA
|
||||
select ATCA_MBEDTLS_ECDSA_SIGN
|
||||
select ATCA_MBEDTLS_ECDSA_VERIFY
|
||||
help
|
||||
Enable use of Secure Element for ESP-TLS, this enables internal support for
|
||||
ATECC608A peripheral, which can be used for TLS connection.
|
||||
|
||||
config ESP_TLS_USE_DS_PERIPHERAL
|
||||
bool "Use Digital Signature (DS) Peripheral with ESP-TLS"
|
||||
depends on ESP_TLS_USING_MBEDTLS && SOC_DIG_SIGN_SUPPORTED
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_tls_errors.h"
|
||||
#include "esp_key_config.h"
|
||||
#include "sdkconfig.h"
|
||||
#ifdef CONFIG_ESP_TLS_USING_MBEDTLS
|
||||
#include "mbedtls/ssl.h"
|
||||
@@ -160,6 +161,8 @@ typedef struct esp_tls_cfg {
|
||||
const unsigned char *clientkey_pem_buf; /*!< Client key legacy name */
|
||||
};
|
||||
|
||||
const esp_key_config_t *client_key; /*!< Unified key config. Must remain valid for session lifetime */
|
||||
|
||||
union {
|
||||
unsigned int clientkey_bytes; /*!< Size of client key pointed to by
|
||||
clientkey_pem_buf
|
||||
@@ -184,9 +187,6 @@ typedef struct esp_tls_cfg {
|
||||
underneath socket will be configured in non
|
||||
blocking mode after tls session is established */
|
||||
|
||||
bool use_secure_element; /*!< Enable this option to use secure element or
|
||||
atecc608a chip */
|
||||
|
||||
int timeout_ms; /*!< Network timeout in milliseconds.
|
||||
Note: If this value is not set, by default the timeout is
|
||||
set to 10 seconds. If you wish that the session should wait
|
||||
@@ -315,6 +315,8 @@ typedef struct esp_tls_cfg_server {
|
||||
const unsigned char *serverkey_pem_buf; /*!< Server key legacy name */
|
||||
};
|
||||
|
||||
const esp_key_config_t *server_key; /*!< Unified key config. Must remain valid for session lifetime */
|
||||
|
||||
union {
|
||||
unsigned int serverkey_bytes; /*!< Size of server key pointed to by
|
||||
serverkey_pem_buf */
|
||||
@@ -334,9 +336,6 @@ typedef struct esp_tls_cfg_server {
|
||||
|
||||
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 */
|
||||
|
||||
uint32_t tls_handshake_timeout_ms; /*!< TLS handshake timeout in milliseconds.
|
||||
Note: If this value is not set, by default the timeout is
|
||||
set to 10 seconds. If you wish that the session should wait
|
||||
|
||||
@@ -32,16 +32,6 @@
|
||||
#include "esp_crt_bundle.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP_TLS_USE_SECURE_ELEMENT
|
||||
/* cryptoauthlib includes */
|
||||
#include "mbedtls/atca_mbedtls_wrap.h"
|
||||
#include "tng_atca.h"
|
||||
#include "cryptoauthlib.h"
|
||||
static const atcacert_def_t *cert_def = NULL;
|
||||
/* Prototypes for functions */
|
||||
static esp_err_t esp_set_atecc608a_pki_context(esp_tls_t *tls, const void *pki);
|
||||
#endif /* CONFIG_ESP_TLS_USE_SECURE_ELEMENT */
|
||||
|
||||
#if defined(CONFIG_ESP_TLS_USE_DS_PERIPHERAL)
|
||||
#include <pk_wrap.h>
|
||||
#include "psa/crypto.h"
|
||||
@@ -486,6 +476,7 @@ void esp_mbedtls_cleanup(esp_tls_t *tls)
|
||||
if (!tls) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tls->cacert_ptr != global_cacert) {
|
||||
mbedtls_x509_crt_free(tls->cacert_ptr);
|
||||
}
|
||||
@@ -511,9 +502,6 @@ void esp_mbedtls_cleanup(esp_tls_t *tls)
|
||||
mbedtls_pk_free(&tls->clientkey);
|
||||
mbedtls_ssl_config_free(&tls->conf);
|
||||
mbedtls_ssl_free(&tls->ssl);
|
||||
#ifdef CONFIG_ESP_TLS_USE_SECURE_ELEMENT
|
||||
atcab_release();
|
||||
#endif
|
||||
}
|
||||
|
||||
static esp_err_t set_ca_cert(esp_tls_t *tls, const unsigned char *cacert, size_t cacert_len)
|
||||
@@ -757,28 +745,51 @@ static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls)
|
||||
#endif // CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL
|
||||
}
|
||||
|
||||
if (cfg->use_secure_element) {
|
||||
#ifdef CONFIG_ESP_TLS_USE_SECURE_ELEMENT
|
||||
if (cfg->server_key != NULL && cfg->server_key->source == ESP_KEY_SOURCE_BUFFER) {
|
||||
/* Unified key config with buffer source */
|
||||
esp_tls_pki_t pki = {
|
||||
.public_cert = &tls->servercert,
|
||||
.pk_key = &tls->serverkey,
|
||||
.publiccert_pem_buf = cfg->servercert_buf,
|
||||
.publiccert_pem_bytes = cfg->servercert_bytes,
|
||||
.privkey_pem_buf = NULL,
|
||||
.privkey_pem_bytes = 0,
|
||||
.privkey_password = NULL,
|
||||
.privkey_password_len = 0,
|
||||
.privkey_pem_buf = cfg->server_key->buffer.data,
|
||||
.privkey_pem_bytes = cfg->server_key->buffer.len,
|
||||
.privkey_password = (const unsigned char *)cfg->server_key->buffer.password,
|
||||
.privkey_password_len = cfg->server_key->buffer.password_len,
|
||||
};
|
||||
|
||||
ret = esp_set_atecc608a_pki_context(tls, (void*) &pki);
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
esp_ret = set_pki_context(tls, &pki);
|
||||
if (esp_ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set server pki context");
|
||||
return esp_ret;
|
||||
}
|
||||
#else
|
||||
ESP_LOGE(TAG, "Please enable secure element support for ESP-TLS in menuconfig");
|
||||
return ESP_FAIL;
|
||||
#endif /* CONFIG_ESP_TLS_USE_SECURE_ELEMENT */
|
||||
} else if (cfg->use_ecdsa_peripheral) {
|
||||
} else if (cfg->server_key != NULL && cfg->server_key->source == ESP_KEY_SOURCE_PSA) {
|
||||
mbedtls_svc_key_id_t key_id = cfg->server_key->psa.key_id;
|
||||
mbedtls_pk_init(&tls->serverkey);
|
||||
ret = mbedtls_pk_wrap_psa(&tls->serverkey, key_id);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "mbedtls_pk_wrap_psa returned -0x%04X", -ret);
|
||||
mbedtls_print_error_msg(ret);
|
||||
ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_MBEDTLS, -ret);
|
||||
return ESP_ERR_MBEDTLS_PK_PARSE_KEY_FAILED;
|
||||
}
|
||||
if (cfg->servercert_buf != NULL) {
|
||||
mbedtls_x509_crt_init(&tls->servercert);
|
||||
ret = mbedtls_x509_crt_parse(&tls->servercert, cfg->servercert_buf, cfg->servercert_bytes);
|
||||
if (ret < 0) {
|
||||
ESP_LOGE(TAG, "mbedtls_x509_crt_parse returned -0x%04X", -ret);
|
||||
mbedtls_print_error_msg(ret);
|
||||
ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_MBEDTLS, -ret);
|
||||
return ESP_ERR_MBEDTLS_X509_CRT_PARSE_FAILED;
|
||||
}
|
||||
ret = mbedtls_ssl_conf_own_cert(&tls->conf, &tls->servercert, &tls->serverkey);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "mbedtls_ssl_conf_own_cert returned -0x%04X", -ret);
|
||||
mbedtls_print_error_msg(ret);
|
||||
ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_MBEDTLS, -ret);
|
||||
return ESP_ERR_MBEDTLS_SSL_CONF_OWN_CERT_FAILED;
|
||||
}
|
||||
}
|
||||
} else if (cfg->use_ecdsa_peripheral) {
|
||||
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
|
||||
tls->use_ecdsa_peripheral = cfg->use_ecdsa_peripheral;
|
||||
#if SOC_ECDSA_SUPPORT_CURVE_P384
|
||||
@@ -997,26 +1008,50 @@ esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t
|
||||
#endif
|
||||
}
|
||||
|
||||
if (cfg->use_secure_element) {
|
||||
#ifdef CONFIG_ESP_TLS_USE_SECURE_ELEMENT
|
||||
if (cfg->client_key != NULL && cfg->client_key->source == ESP_KEY_SOURCE_BUFFER) {
|
||||
/* Unified key config with buffer source */
|
||||
esp_tls_pki_t pki = {
|
||||
.public_cert = &tls->clientcert,
|
||||
.pk_key = &tls->clientkey,
|
||||
.publiccert_pem_buf = cfg->clientcert_buf,
|
||||
.publiccert_pem_bytes = cfg->clientcert_bytes,
|
||||
.privkey_pem_buf = NULL,
|
||||
.privkey_pem_bytes = 0,
|
||||
.privkey_password = NULL,
|
||||
.privkey_password_len = 0,
|
||||
.privkey_pem_buf = cfg->client_key->buffer.data,
|
||||
.privkey_pem_bytes = cfg->client_key->buffer.len,
|
||||
.privkey_password = (const unsigned char *)cfg->client_key->buffer.password,
|
||||
.privkey_password_len = cfg->client_key->buffer.password_len,
|
||||
};
|
||||
ret = esp_set_atecc608a_pki_context(tls, (void*) &pki);
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
esp_err_t esp_ret = set_pki_context(tls, &pki);
|
||||
if (esp_ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set client pki context");
|
||||
return esp_ret;
|
||||
}
|
||||
} else if (cfg->client_key != NULL && cfg->client_key->source == ESP_KEY_SOURCE_PSA) {
|
||||
mbedtls_svc_key_id_t key_id = cfg->client_key->psa.key_id;
|
||||
mbedtls_pk_init(&tls->clientkey);
|
||||
ret = mbedtls_pk_wrap_psa(&tls->clientkey, key_id);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "mbedtls_pk_wrap_psa returned -0x%04X", -ret);
|
||||
mbedtls_print_error_msg(ret);
|
||||
ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_MBEDTLS, -ret);
|
||||
return ESP_ERR_MBEDTLS_PK_PARSE_KEY_FAILED;
|
||||
}
|
||||
if (cfg->clientcert_buf != NULL) {
|
||||
mbedtls_x509_crt_init(&tls->clientcert);
|
||||
ret = mbedtls_x509_crt_parse(&tls->clientcert, cfg->clientcert_buf, cfg->clientcert_bytes);
|
||||
if (ret < 0) {
|
||||
ESP_LOGE(TAG, "mbedtls_x509_crt_parse returned -0x%04X", -ret);
|
||||
mbedtls_print_error_msg(ret);
|
||||
ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_MBEDTLS, -ret);
|
||||
return ESP_ERR_MBEDTLS_X509_CRT_PARSE_FAILED;
|
||||
}
|
||||
ret = mbedtls_ssl_conf_own_cert(&tls->conf, &tls->clientcert, &tls->clientkey);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "mbedtls_ssl_conf_own_cert returned -0x%04X", -ret);
|
||||
mbedtls_print_error_msg(ret);
|
||||
ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_MBEDTLS, -ret);
|
||||
return ESP_ERR_MBEDTLS_SSL_CONF_OWN_CERT_FAILED;
|
||||
}
|
||||
}
|
||||
#else
|
||||
ESP_LOGE(TAG, "Please enable secure element support for ESP-TLS in menuconfig");
|
||||
return ESP_FAIL;
|
||||
#endif /* CONFIG_ESP_TLS_USE_SECURE_ELEMENT */
|
||||
} else if (cfg->ds_data != NULL) {
|
||||
#ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL
|
||||
if (cfg->clientcert_pem_buf == NULL) {
|
||||
@@ -1278,92 +1313,6 @@ const int *esp_mbedtls_get_ciphersuites_list(void)
|
||||
return mbedtls_ssl_list_ciphersuites();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESP_TLS_USE_SECURE_ELEMENT
|
||||
static esp_err_t esp_init_atecc608a(uint8_t i2c_addr)
|
||||
{
|
||||
cfg_ateccx08a_i2c_default.atcai2c.address = i2c_addr;
|
||||
int ret = atcab_init(&cfg_ateccx08a_i2c_default);
|
||||
if(ret != 0) {
|
||||
ESP_LOGE(TAG, "Failed to initialize atca device, returned -0x%04X", -ret);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_set_atecc608a_pki_context(esp_tls_t *tls, const void *pki)
|
||||
{
|
||||
int ret = 0;
|
||||
esp_err_t esp_ret = ESP_FAIL;
|
||||
ESP_LOGI(TAG, "Initialize the ATECC interface...");
|
||||
(void)esp_ret;
|
||||
(void)cert_def;
|
||||
#if defined(CONFIG_ATECC608A_TNG) || defined(CONFIG_ATECC608A_TFLEX)
|
||||
#ifdef CONFIG_ATECC608A_TNG
|
||||
esp_ret = esp_init_atecc608a(CONFIG_ATCA_I2C_ADDRESS);
|
||||
if (ret != ESP_OK) {
|
||||
return ESP_ERR_ESP_TLS_SE_FAILED;
|
||||
}
|
||||
#elif CONFIG_ATECC608A_TFLEX /* CONFIG_ATECC608A_TNG */
|
||||
esp_ret = esp_init_atecc608a(CONFIG_ATCA_I2C_ADDRESS);
|
||||
if (ret != ESP_OK) {
|
||||
return ESP_ERR_ESP_TLS_SE_FAILED;
|
||||
}
|
||||
#endif /* CONFIG_ATECC608A_TFLEX */
|
||||
mbedtls_x509_crt_init(&tls->clientcert);
|
||||
ret = tng_get_device_cert_def(&cert_def);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Failed to get device cert def");
|
||||
return ESP_ERR_ESP_TLS_SE_FAILED;
|
||||
}
|
||||
|
||||
/* Extract the device certificate and convert to mbedtls cert */
|
||||
ret = atca_mbedtls_cert_add(&tls->clientcert, cert_def);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Failed to parse cert from device, return 0x%04X", ret);
|
||||
mbedtls_print_error_msg(ret);
|
||||
return ESP_ERR_ESP_TLS_SE_FAILED;
|
||||
}
|
||||
#elif CONFIG_ATECC608A_TCUSTOM
|
||||
esp_ret = esp_init_atecc608a(CONFIG_ATCA_I2C_ADDRESS);
|
||||
if (ret != ESP_OK) {
|
||||
return ESP_ERR_ESP_TLS_SE_FAILED;
|
||||
}
|
||||
mbedtls_x509_crt_init(&tls->clientcert);
|
||||
|
||||
esp_tls_pki_t *pki_l = (esp_tls_pki_t *) pki;
|
||||
if (pki_l->publiccert_pem_buf != NULL) {
|
||||
ret = mbedtls_x509_crt_parse(&tls->clientcert, pki_l->publiccert_pem_buf, pki_l->publiccert_pem_bytes);
|
||||
if (ret < 0) {
|
||||
ESP_LOGE(TAG, "mbedtls_x509_crt_parse of client cert returned -0x%04X", -ret);
|
||||
mbedtls_print_error_msg(ret);
|
||||
ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_MBEDTLS, -ret);
|
||||
return ESP_ERR_MBEDTLS_X509_CRT_PARSE_FAILED;
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Device certificate must be provided for TrustCustom Certs");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif /* CONFIG_ATECC608A_TCUSTOM */
|
||||
ret = atca_mbedtls_pk_init(&tls->clientkey, 0);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Failed to parse key from device");
|
||||
ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_MBEDTLS, -ret);
|
||||
mbedtls_print_error_msg(ret);
|
||||
return ESP_ERR_ESP_TLS_SE_FAILED;
|
||||
}
|
||||
|
||||
ret = mbedtls_ssl_conf_own_cert(&tls->conf, &tls->clientcert, &tls->clientkey);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Failed to configure client cert, returned -0x%04X", ret);
|
||||
mbedtls_print_error_msg(ret);
|
||||
ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_MBEDTLS, -ret);
|
||||
return ESP_ERR_ESP_TLS_SE_FAILED;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif /* CONFIG_ESP_TLS_USE_SECURE_ELEMENT */
|
||||
|
||||
#ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL
|
||||
/*
|
||||
* tf-psa-crypto 1.1 made mbedtls_pk_wrap_psa() call psa_export_public_key() on
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
if(NOT ${IDF_TARGET} STREQUAL "linux")
|
||||
set(req lwip esp_event)
|
||||
set(req lwip esp_event esp_security)
|
||||
else()
|
||||
set(req linux esp_event)
|
||||
set(req linux esp_event esp_security)
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS "esp_http_client.c"
|
||||
|
||||
@@ -938,12 +938,6 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_ESP_TLS_USE_SECURE_ELEMENT
|
||||
if (config->use_secure_element) {
|
||||
esp_transport_ssl_use_secure_element(ssl);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_ESP_TLS_USE_DS_PERIPHERAL
|
||||
if (config->ds_data != NULL) {
|
||||
esp_transport_ssl_set_ds_data(ssl, config->ds_data);
|
||||
@@ -962,26 +956,32 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co
|
||||
}
|
||||
#endif
|
||||
|
||||
if (config->client_key_pem) {
|
||||
if (!config->client_key_len) {
|
||||
esp_transport_ssl_set_client_key_data(ssl, config->client_key_pem, strlen(config->client_key_pem));
|
||||
} else {
|
||||
esp_transport_ssl_set_client_key_data_der(ssl, config->client_key_pem, config->client_key_len);
|
||||
/* Check for unified key config */
|
||||
if (config->client_key != NULL) {
|
||||
esp_transport_ssl_set_client_key_config(ssl, config->client_key);
|
||||
} else {
|
||||
/* Legacy key configuration */
|
||||
if (config->client_key_pem) {
|
||||
if (!config->client_key_len) {
|
||||
esp_transport_ssl_set_client_key_data(ssl, config->client_key_pem, strlen(config->client_key_pem));
|
||||
} else {
|
||||
esp_transport_ssl_set_client_key_data_der(ssl, config->client_key_pem, config->client_key_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
#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);
|
||||
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
|
||||
esp_transport_ssl_set_ecdsa_curve(ssl, config->ecdsa_curve);
|
||||
}
|
||||
// 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) {
|
||||
esp_transport_ssl_set_client_key_password(ssl, config->client_key_password, config->client_key_password_len);
|
||||
if (config->client_key_password && config->client_key_password_len > 0) {
|
||||
esp_transport_ssl_set_client_key_password(ssl, config->client_key_password, config->client_key_password_len);
|
||||
}
|
||||
}
|
||||
|
||||
if (config->skip_cert_common_name_check) {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_key_config.h"
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -200,6 +201,7 @@ typedef struct {
|
||||
DER Certificate - Length of the buffer pointed to by client_cert_der. Should be the length of the certificate. */
|
||||
const char *client_key_pem; /*!< SSL client key, PEM format as string, if the server requires to verify client */
|
||||
size_t client_key_len; /*!< Length of the buffer pointed to by client_key_pem. May be 0 for null-terminated pem */
|
||||
const esp_key_config_t *client_key; /*!< Unified client key configuration. Takes precedence over client_key_pem when set */
|
||||
const char *client_key_password; /*!< Client key decryption password string */
|
||||
size_t client_key_password_len; /*!< String length of the password pointed to by client_key_password */
|
||||
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) */
|
||||
@@ -237,9 +239,6 @@ typedef struct {
|
||||
const char **alpn_protos; /*!< Application protocols required for HTTP2. If HTTP2/ALPN support is required, a list of protocols that should be negotiated. The format is length followed by protocol
|
||||
name. For the most common cases the following is ok: const char **alpn_protos = { "h2", NULL }; - where 'h2' is the protocol name */
|
||||
#endif
|
||||
#if CONFIG_ESP_TLS_USE_SECURE_ELEMENT
|
||||
bool use_secure_element; /*!< Enable this option to use secure element */
|
||||
#endif
|
||||
#if CONFIG_ESP_TLS_USE_DS_PERIPHERAL
|
||||
void *ds_data; /*!< Pointer for digital signature peripheral context, see ESP-TLS Documentation for more details */
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2018-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -105,6 +105,9 @@ struct httpd_ssl_config {
|
||||
/** Private key byte length */
|
||||
size_t prvtkey_len;
|
||||
|
||||
/** Unified key config. Takes precedence over prvtkey_pem when set */
|
||||
const esp_key_config_t *server_key;
|
||||
|
||||
/** Use ECDSA peripheral to use private key */
|
||||
bool use_ecdsa_peripheral;
|
||||
|
||||
@@ -129,9 +132,6 @@ struct httpd_ssl_config {
|
||||
/** Enable tls session tickets */
|
||||
bool session_tickets;
|
||||
|
||||
/** Enable secure element for server session */
|
||||
bool use_secure_element;
|
||||
|
||||
/** User callback for esp_https_server */
|
||||
esp_https_server_user_cb *user_cb;
|
||||
|
||||
@@ -227,7 +227,6 @@ typedef struct httpd_ssl_config httpd_ssl_config_t;
|
||||
.port_secure = 443, \
|
||||
.port_insecure = 80, \
|
||||
.session_tickets = false, \
|
||||
.use_secure_element = false, \
|
||||
.user_cb = NULL, \
|
||||
.ssl_userdata = NULL, \
|
||||
.cert_select_cb = NULL, \
|
||||
|
||||
@@ -348,48 +348,47 @@ static esp_err_t create_secure_context(const struct httpd_ssl_config *config, ht
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Pass on secure element boolean */
|
||||
cfg->use_secure_element = config->use_secure_element;
|
||||
if (!cfg->use_secure_element) {
|
||||
if (config->use_ecdsa_peripheral) {
|
||||
if (config->use_ecdsa_peripheral) {
|
||||
#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->use_ecdsa_peripheral = config->use_ecdsa_peripheral;
|
||||
(*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;
|
||||
(*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
|
||||
ESP_LOGE(TAG, "Please enable the support for signing using ECDSA peripheral in menuconfig.");
|
||||
ret = ESP_ERR_NOT_SUPPORTED;
|
||||
goto exit;
|
||||
ESP_LOGE(TAG, "Please enable the support for signing using ECDSA peripheral in menuconfig.");
|
||||
ret = ESP_ERR_NOT_SUPPORTED;
|
||||
goto exit;
|
||||
#endif
|
||||
} else if (config->prvtkey_pem != NULL && config->prvtkey_len > 0) {
|
||||
cfg->serverkey_buf = malloc(config->prvtkey_len);
|
||||
} else if (config->server_key != NULL) {
|
||||
/* Unified key config - pass directly to esp_tls */
|
||||
cfg->server_key = config->server_key;
|
||||
} else if (config->prvtkey_pem != NULL && config->prvtkey_len > 0) {
|
||||
cfg->serverkey_buf = malloc(config->prvtkey_len);
|
||||
|
||||
if (cfg->serverkey_buf) {
|
||||
memcpy((char *) cfg->serverkey_buf, config->prvtkey_pem, config->prvtkey_len);
|
||||
cfg->serverkey_bytes = config->prvtkey_len;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Could not allocate memory for server key");
|
||||
ret = ESP_ERR_NO_MEM;
|
||||
goto exit;
|
||||
}
|
||||
if (cfg->serverkey_buf) {
|
||||
memcpy((char *) cfg->serverkey_buf, config->prvtkey_pem, config->prvtkey_len);
|
||||
cfg->serverkey_bytes = config->prvtkey_len;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Could not allocate memory for server key");
|
||||
ret = ESP_ERR_NO_MEM;
|
||||
goto exit;
|
||||
}
|
||||
} else {
|
||||
#if defined(CONFIG_ESP_HTTPS_SERVER_CERT_SELECT_HOOK)
|
||||
if (config->cert_select_cb == NULL) {
|
||||
ESP_LOGE(TAG, "No Server key supplied and no certificate selection hook is present");
|
||||
ret = ESP_ERR_INVALID_ARG;
|
||||
goto exit;
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Server key not supplied, make sure to supply it in the certificate selection hook");
|
||||
}
|
||||
#else
|
||||
ESP_LOGE(TAG, "No Server key supplied");
|
||||
if (config->cert_select_cb == NULL) {
|
||||
ESP_LOGE(TAG, "No Server key supplied and no certificate selection hook is present");
|
||||
ret = ESP_ERR_INVALID_ARG;
|
||||
goto exit;
|
||||
#endif
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Server key not supplied, make sure to supply it in the certificate selection hook");
|
||||
}
|
||||
#else
|
||||
ESP_LOGE(TAG, "No Server key supplied");
|
||||
ret = ESP_ERR_INVALID_ARG;
|
||||
goto exit;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -2,7 +2,9 @@ idf_build_get_property(target IDF_TARGET)
|
||||
idf_build_get_property(non_os_build NON_OS_BUILD)
|
||||
|
||||
if(${target} STREQUAL "linux")
|
||||
return() # This component is not supported by the POSIX/Linux simulator
|
||||
# On linux, only provide headers (esp_key_config.h) without any source files
|
||||
idf_component_register(INCLUDE_DIRS "include")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(srcs "")
|
||||
|
||||
69
components/esp_security/include/esp_key_config.h
Normal file
69
components/esp_security/include/esp_key_config.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Key format */
|
||||
typedef enum {
|
||||
ESP_KEY_FORMAT_AUTO = 0, /*!< Auto-detect */
|
||||
ESP_KEY_FORMAT_PEM, /*!< PEM (base64) */
|
||||
ESP_KEY_FORMAT_DER, /*!< DER (binary) */
|
||||
ESP_KEY_FORMAT_RAW, /*!< Raw key bytes */
|
||||
} esp_key_format_t;
|
||||
|
||||
/**
|
||||
* Key source types
|
||||
*
|
||||
* Hardware-backed key sources (DS peripheral, ECDSA peripheral,
|
||||
* secure element, key manager) as well as software PSA imported keys
|
||||
* are accessed via PSA Crypto drivers. Use ESP_KEY_SOURCE_PSA with
|
||||
* the PSA key ID obtained from psa_import_key() or the corresponding
|
||||
* hardware setup helper API.
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_KEY_SOURCE_NONE = 0, /*!< No private key configured */
|
||||
ESP_KEY_SOURCE_BUFFER, /*!< Key in memory buffer (PEM/DER/RAW) */
|
||||
ESP_KEY_SOURCE_PSA, /*!< PSA Crypto key (opaque or transparent) */
|
||||
} esp_key_source_t;
|
||||
|
||||
/**
|
||||
* Unified private key configuration
|
||||
*
|
||||
* For hardware-backed keys (DS peripheral, ECDSA peripheral, ATECC608,
|
||||
* key manager), use ESP_KEY_SOURCE_PSA with the key ID returned by
|
||||
* the respective setup helper (e.g., esp_secure_element_psa_setup()).
|
||||
*
|
||||
* @note Must remain valid for the entire TLS session lifetime
|
||||
*/
|
||||
typedef struct esp_key_config {
|
||||
esp_key_source_t source; /*!< Key source type */
|
||||
|
||||
union {
|
||||
struct {
|
||||
const void *data; /*!< Key data (PEM/DER/RAW) */
|
||||
size_t len; /*!< Length (0 for null-terminated PEM) */
|
||||
const char *password; /*!< Decryption password */
|
||||
size_t password_len; /*!< Password length */
|
||||
esp_key_format_t format; /*!< Key format */
|
||||
} buffer;
|
||||
|
||||
struct {
|
||||
uint32_t key_id; /*!< PSA key identifier */
|
||||
} psa;
|
||||
};
|
||||
|
||||
} esp_key_config_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -206,15 +206,6 @@ void esp_transport_ssl_set_common_name(esp_transport_handle_t t, const char *com
|
||||
*/
|
||||
void esp_transport_ssl_set_ciphersuites_list(esp_transport_handle_t t, const int *ciphersuites_list);
|
||||
|
||||
/**
|
||||
* @brief Set the ssl context to use secure element (atecc608a) for client(device) private key and certificate
|
||||
*
|
||||
* @note Recommended to be used with ESP32 series interfaced to ATECC608A based secure element
|
||||
*
|
||||
* @param t ssl transport
|
||||
*/
|
||||
void esp_transport_ssl_use_secure_element(esp_transport_handle_t t);
|
||||
|
||||
/**
|
||||
* @brief Set the ds_data handle in ssl context.(used for the digital signature operation)
|
||||
*
|
||||
@@ -223,6 +214,26 @@ void esp_transport_ssl_use_secure_element(esp_transport_handle_t t);
|
||||
*/
|
||||
void esp_transport_ssl_set_ds_data(esp_transport_handle_t t, void *ds_data);
|
||||
|
||||
/**
|
||||
* @brief Set unified client key configuration for mutual authentication
|
||||
*
|
||||
* This function provides a unified way to configure client private keys
|
||||
* from various sources (buffer, ECDSA peripheral, secure element, etc.)
|
||||
* using the esp_key_config_t structure.
|
||||
*
|
||||
* @note This function stores the pointer to config, rather than making a copy.
|
||||
* So the config must remain valid until after the connection is cleaned up.
|
||||
*
|
||||
* @note When client_key is set, it takes precedence over legacy key configuration
|
||||
* functions (set_client_key_data, set_client_key_ecdsa_peripheral, etc.)
|
||||
*
|
||||
* @param t ssl transport
|
||||
* @param[in] client_key Pointer to the unified key configuration
|
||||
*
|
||||
* @see esp_key_config_t for configuration options
|
||||
*/
|
||||
void esp_transport_ssl_set_client_key_config(esp_transport_handle_t t, const esp_key_config_t *client_key);
|
||||
|
||||
/**
|
||||
* @brief Set PSK key and hint for PSK server/client verification in esp-tls component.
|
||||
* Important notes:
|
||||
|
||||
@@ -502,14 +502,6 @@ void esp_transport_ssl_set_ciphersuites_list(esp_transport_handle_t t, const int
|
||||
ssl->cfg.ciphersuites_list = ciphersuites_list;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESP_TLS_USE_SECURE_ELEMENT
|
||||
void esp_transport_ssl_use_secure_element(esp_transport_handle_t t)
|
||||
{
|
||||
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
|
||||
ssl->cfg.use_secure_element = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
|
||||
void esp_transport_ssl_crt_bundle_attach(esp_transport_handle_t t, esp_err_t ((*crt_bundle_attach)(void *conf)))
|
||||
{
|
||||
@@ -575,6 +567,12 @@ void esp_transport_ssl_set_ds_data(esp_transport_handle_t t, void *ds_data)
|
||||
}
|
||||
#endif
|
||||
|
||||
void esp_transport_ssl_set_client_key_config(esp_transport_handle_t t, const esp_key_config_t *client_key)
|
||||
{
|
||||
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
|
||||
ssl->cfg.client_key = client_key;
|
||||
}
|
||||
|
||||
void esp_transport_ssl_set_keep_alive(esp_transport_handle_t t, esp_transport_keep_alive_t *keep_alive_cfg)
|
||||
{
|
||||
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <esp_log.h>
|
||||
#include <esp_timer.h>
|
||||
#include <esp_local_ctrl.h>
|
||||
#include <esp_key_config.h>
|
||||
#include <protocomm_ble.h>
|
||||
|
||||
static const char *TAG = "control";
|
||||
@@ -239,8 +240,14 @@ void start_esp_local_ctrl_service(void)
|
||||
/* Load server private key */
|
||||
extern const unsigned char prvtkey_pem_start[] asm("_binary_prvtkey_pem_start");
|
||||
extern const unsigned char prvtkey_pem_end[] asm("_binary_prvtkey_pem_end");
|
||||
https_conf.prvtkey_pem = prvtkey_pem_start;
|
||||
https_conf.prvtkey_len = prvtkey_pem_end - prvtkey_pem_start;
|
||||
static esp_key_config_t server_key = {
|
||||
.source = ESP_KEY_SOURCE_BUFFER,
|
||||
.buffer = {
|
||||
.data = prvtkey_pem_start,
|
||||
.len = prvtkey_pem_end - prvtkey_pem_start,
|
||||
}
|
||||
};
|
||||
https_conf.server_key = &server_key;
|
||||
#else
|
||||
httpd_config_t http_conf = HTTPD_DEFAULT_CONFIG();
|
||||
#endif
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <esp_https_server.h>
|
||||
#include "esp_tls.h"
|
||||
#include "esp_key_config.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_EXAMPLE_ENABLE_HTTPS_SERVER_CUSTOM_CIPHERSUITES
|
||||
@@ -206,8 +207,14 @@ static httpd_handle_t start_webserver(void)
|
||||
|
||||
extern const unsigned char prvtkey_pem_start[] asm("_binary_prvtkey_pem_start");
|
||||
extern const unsigned char prvtkey_pem_end[] asm("_binary_prvtkey_pem_end");
|
||||
conf.prvtkey_pem = prvtkey_pem_start;
|
||||
conf.prvtkey_len = prvtkey_pem_end - prvtkey_pem_start;
|
||||
static esp_key_config_t server_key = {
|
||||
.source = ESP_KEY_SOURCE_BUFFER,
|
||||
.buffer = {
|
||||
.data = prvtkey_pem_start,
|
||||
.len = prvtkey_pem_end - prvtkey_pem_start,
|
||||
}
|
||||
};
|
||||
conf.server_key = &server_key;
|
||||
|
||||
#if CONFIG_EXAMPLE_ENABLE_HTTPS_SERVER_CUSTOM_CIPHERSUITES
|
||||
static const int ciphersuites_to_use[] = {
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <unistd.h>
|
||||
#endif // !CONFIG_IDF_TARGET_LINUX
|
||||
#include <esp_https_server.h>
|
||||
#include "esp_key_config.h"
|
||||
#include "keep_alive.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
@@ -211,8 +212,14 @@ static httpd_handle_t start_wss_echo_server(void)
|
||||
|
||||
extern const unsigned char prvtkey_pem_start[] asm("_binary_prvtkey_pem_start");
|
||||
extern const unsigned char prvtkey_pem_end[] asm("_binary_prvtkey_pem_end");
|
||||
conf.prvtkey_pem = prvtkey_pem_start;
|
||||
conf.prvtkey_len = prvtkey_pem_end - prvtkey_pem_start;
|
||||
static esp_key_config_t server_key = {
|
||||
.source = ESP_KEY_SOURCE_BUFFER,
|
||||
.buffer = {
|
||||
.data = prvtkey_pem_start,
|
||||
.len = prvtkey_pem_end - prvtkey_pem_start,
|
||||
}
|
||||
};
|
||||
conf.server_key = &server_key;
|
||||
|
||||
esp_err_t ret = httpd_ssl_start(&server, &conf);
|
||||
if (ESP_OK != ret) {
|
||||
|
||||
@@ -8,6 +8,6 @@ idf_component_mock(INCLUDE_DIRS "${original_esp_tls_dir}"
|
||||
"${original_esp_tls_dir}/esp-tls-crypto"
|
||||
MOCK_HEADER_FILES ${original_esp_tls_dir}/esp_tls.h
|
||||
${original_esp_tls_dir}/esp-tls-crypto/esp_tls_crypto.h
|
||||
REQUIRES mbedtls
|
||||
REQUIRES mbedtls esp_security
|
||||
)
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-array-parameter)
|
||||
|
||||
Reference in New Issue
Block a user