diff --git a/components/esp-tls/CMakeLists.txt b/components/esp-tls/CMakeLists.txt index 14a8503cd5c..44207ecab90 100644 --- a/components/esp-tls/CMakeLists.txt +++ b/components/esp-tls/CMakeLists.txt @@ -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() diff --git a/components/esp-tls/Kconfig b/components/esp-tls/Kconfig index ef9904e3a4e..185c158e6c8 100644 --- a/components/esp-tls/Kconfig +++ b/components/esp-tls/Kconfig @@ -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 diff --git a/components/esp-tls/esp_tls.h b/components/esp-tls/esp_tls.h index c7802b94185..3d7596959ec 100644 --- a/components/esp-tls/esp_tls.h +++ b/components/esp-tls/esp_tls.h @@ -9,6 +9,7 @@ #include #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 diff --git a/components/esp-tls/esp_tls_mbedtls.c b/components/esp-tls/esp_tls_mbedtls.c index 901d4ba713b..5c0050091b8 100644 --- a/components/esp-tls/esp_tls_mbedtls.c +++ b/components/esp-tls/esp_tls_mbedtls.c @@ -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 #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 diff --git a/components/esp_http_client/CMakeLists.txt b/components/esp_http_client/CMakeLists.txt index 4a353e33ca0..b52b45bb847 100644 --- a/components/esp_http_client/CMakeLists.txt +++ b/components/esp_http_client/CMakeLists.txt @@ -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" diff --git a/components/esp_http_client/esp_http_client.c b/components/esp_http_client/esp_http_client.c index 1567cd21cdb..52dfd0f2544 100644 --- a/components/esp_http_client/esp_http_client.c +++ b/components/esp_http_client/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) { diff --git a/components/esp_http_client/include/esp_http_client.h b/components/esp_http_client/include/esp_http_client.h index 4a257808778..1a6225b76be 100644 --- a/components/esp_http_client/include/esp_http_client.h +++ b/components/esp_http_client/include/esp_http_client.h @@ -10,6 +10,7 @@ #include "freertos/FreeRTOS.h" #include "sdkconfig.h" #include "esp_err.h" +#include "esp_key_config.h" #include #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 diff --git a/components/esp_https_server/include/esp_https_server.h b/components/esp_https_server/include/esp_https_server.h index 2a34eb7ebad..58d568e21ea 100644 --- a/components/esp_https_server/include/esp_https_server.h +++ b/components/esp_https_server/include/esp_https_server.h @@ -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, \ diff --git a/components/esp_https_server/src/https_server.c b/components/esp_https_server/src/https_server.c index 865560777d8..2184228087a 100644 --- a/components/esp_https_server/src/https_server.c +++ b/components/esp_https_server/src/https_server.c @@ -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; diff --git a/components/esp_security/CMakeLists.txt b/components/esp_security/CMakeLists.txt index c3568afce4e..530e72325f1 100644 --- a/components/esp_security/CMakeLists.txt +++ b/components/esp_security/CMakeLists.txt @@ -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 "") diff --git a/components/esp_security/include/esp_key_config.h b/components/esp_security/include/esp_key_config.h new file mode 100644 index 00000000000..35da2f4babb --- /dev/null +++ b/components/esp_security/include/esp_key_config.h @@ -0,0 +1,69 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include + +#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 diff --git a/components/tcp_transport/include/esp_transport_ssl.h b/components/tcp_transport/include/esp_transport_ssl.h index 4dcd5c1338a..b0ec044a305 100644 --- a/components/tcp_transport/include/esp_transport_ssl.h +++ b/components/tcp_transport/include/esp_transport_ssl.h @@ -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: diff --git a/components/tcp_transport/transport_ssl.c b/components/tcp_transport/transport_ssl.c index 790ebd37c10..0f01ebecb87 100644 --- a/components/tcp_transport/transport_ssl.c +++ b/components/tcp_transport/transport_ssl.c @@ -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); diff --git a/examples/protocols/esp_local_ctrl/main/esp_local_ctrl_service.c b/examples/protocols/esp_local_ctrl/main/esp_local_ctrl_service.c index f0ff5b9d274..084e80a1249 100644 --- a/examples/protocols/esp_local_ctrl/main/esp_local_ctrl_service.c +++ b/examples/protocols/esp_local_ctrl/main/esp_local_ctrl_service.c @@ -20,6 +20,7 @@ #include #include #include +#include #include 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 diff --git a/examples/protocols/https_server/simple/main/main.c b/examples/protocols/https_server/simple/main/main.c index 30878614d17..deb33c722e1 100644 --- a/examples/protocols/https_server/simple/main/main.c +++ b/examples/protocols/https_server/simple/main/main.c @@ -25,6 +25,7 @@ #include #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[] = { diff --git a/examples/protocols/https_server/wss_server/main/wss_server_example.c b/examples/protocols/https_server/wss_server/main/wss_server_example.c index 7588c839749..b3c529f06f1 100644 --- a/examples/protocols/https_server/wss_server/main/wss_server_example.c +++ b/examples/protocols/https_server/wss_server/main/wss_server_example.c @@ -22,6 +22,7 @@ #include #endif // !CONFIG_IDF_TARGET_LINUX #include +#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) { diff --git a/tools/mocks/esp-tls/CMakeLists.txt b/tools/mocks/esp-tls/CMakeLists.txt index 8e0406e2958..450513b9f00 100644 --- a/tools/mocks/esp-tls/CMakeLists.txt +++ b/tools/mocks/esp-tls/CMakeLists.txt @@ -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)