From cca2a54624c032b184611abb7cf551b4b7f91c14 Mon Sep 17 00:00:00 2001 From: Ashish Sharma Date: Tue, 23 Dec 2025 10:29:32 +0800 Subject: [PATCH] feat: migrates esp-tls to PSA APIs --- components/esp-tls/Kconfig | 4 +- .../esp-tls/esp-tls-crypto/esp_tls_crypto.c | 22 ++- components/esp-tls/esp_tls.h | 7 - components/esp-tls/esp_tls_mbedtls.c | 129 +++++++++--------- .../esp-tls/private_include/esp_tls_private.h | 10 +- components/esp-tls/test_apps/main/app_main.c | 39 ++++-- 6 files changed, 101 insertions(+), 110 deletions(-) diff --git a/components/esp-tls/Kconfig b/components/esp-tls/Kconfig index d8f5dd84cc..427607ca4d 100644 --- a/components/esp-tls/Kconfig +++ b/components/esp-tls/Kconfig @@ -26,7 +26,7 @@ menu "ESP-TLS" 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 && MBEDTLS_PK_RSA_ALT_SUPPORT + depends on ESP_TLS_USING_MBEDTLS && SOC_DIG_SIGN_SUPPORTED default y help Enable use of the Digital Signature Peripheral for ESP-TLS.The DS peripheral @@ -76,9 +76,7 @@ menu "ESP-TLS" bool "Enable PSK verification" select MBEDTLS_PSK_MODES if ESP_TLS_USING_MBEDTLS select MBEDTLS_KEY_EXCHANGE_PSK if ESP_TLS_USING_MBEDTLS - select MBEDTLS_KEY_EXCHANGE_DHE_PSK if ESP_TLS_USING_MBEDTLS && MBEDTLS_DHM_C select MBEDTLS_KEY_EXCHANGE_ECDHE_PSK if ESP_TLS_USING_MBEDTLS && MBEDTLS_ECDH_C - select MBEDTLS_KEY_EXCHANGE_RSA_PSK if ESP_TLS_USING_MBEDTLS help Enable support for pre shared key ciphers, supported for both mbedTLS as well as wolfSSL TLS library. diff --git a/components/esp-tls/esp-tls-crypto/esp_tls_crypto.c b/components/esp-tls/esp-tls-crypto/esp_tls_crypto.c index 64e8246288..8589164cc5 100644 --- a/components/esp-tls/esp-tls-crypto/esp_tls_crypto.c +++ b/components/esp-tls/esp-tls-crypto/esp_tls_crypto.c @@ -10,9 +10,9 @@ #include "sdkconfig.h" __attribute__((unused)) static const char *TAG = "esp_crypto"; #ifdef CONFIG_ESP_TLS_USING_MBEDTLS -#include "mbedtls/sha1.h" #include "mbedtls/base64.h" #include "mbedtls/error.h" +#include "psa/crypto.h" #define _esp_crypto_sha1 esp_crypto_sha1_mbedtls #define _esp_crypto_base64_encode esp_crypto_bas64_encode_mbedtls #elif CONFIG_ESP_TLS_USING_WOLFSSL @@ -28,29 +28,25 @@ static int esp_crypto_sha1_mbedtls( const unsigned char *input, unsigned char output[20]) { #if CONFIG_MBEDTLS_SHA1_C || CONFIG_MBEDTLS_HARDWARE_SHA - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_sha1_context ctx; + psa_hash_operation_t ctx = PSA_HASH_OPERATION_INIT; - mbedtls_sha1_init(&ctx); - - if ((ret = mbedtls_sha1_starts(&ctx)) != 0) { + psa_status_t status = psa_hash_setup(&ctx, PSA_ALG_SHA_1); + if (status != PSA_SUCCESS) { goto exit; } - if ((ret = mbedtls_sha1_update(&ctx, input, ilen)) != 0) { + if ((status = psa_hash_update(&ctx, input, ilen)) != PSA_SUCCESS) { goto exit; } - if ((ret = mbedtls_sha1_finish(&ctx, output)) != 0) { + size_t hash_len; + if ((status = psa_hash_finish(&ctx, output, 20, &hash_len)) != PSA_SUCCESS) { goto exit; } exit: - mbedtls_sha1_free(&ctx); - if (ret != 0) { - ESP_LOGE(TAG, "Error in calculating sha1 sum , Returned 0x%02X", ret); - } - return ret; + psa_hash_abort(&ctx); + return status == PSA_SUCCESS ? 0 : -1; #else ESP_LOGE(TAG, "Please enable CONFIG_MBEDTLS_SHA1_C or CONFIG_MBEDTLS_HARDWARE_SHA to support SHA1 operations"); return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED; diff --git a/components/esp-tls/esp_tls.h b/components/esp-tls/esp_tls.h index 1e2c57340f..a72c33ff05 100644 --- a/components/esp-tls/esp_tls.h +++ b/components/esp-tls/esp_tls.h @@ -15,8 +15,6 @@ #include "mbedtls/x509_crt.h" #ifdef CONFIG_ESP_TLS_SERVER_SESSION_TICKETS #include "mbedtls/ssl_ticket.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" #endif #elif CONFIG_ESP_TLS_USING_WOLFSSL #include "wolfssl/wolfcrypt/settings.h" @@ -246,11 +244,6 @@ typedef struct esp_tls_cfg { * @brief Data structures necessary to support TLS session tickets according to RFC5077 */ typedef struct esp_tls_server_session_ticket_ctx { - mbedtls_entropy_context entropy; /*!< mbedTLS entropy context structure */ - - mbedtls_ctr_drbg_context ctr_drbg; /*!< mbedTLS ctr drbg context structure. - CTR_DRBG is deterministic random - bit generation based on AES-256 */ mbedtls_ssl_ticket_context ticket_ctx; /*!< Session ticket generation context */ } esp_tls_server_session_ticket_ctx_t; #endif diff --git a/components/esp-tls/esp_tls_mbedtls.c b/components/esp-tls/esp_tls_mbedtls.c index 73bee131a3..42f31565ab 100644 --- a/components/esp-tls/esp_tls_mbedtls.c +++ b/components/esp-tls/esp_tls_mbedtls.c @@ -22,6 +22,7 @@ #include "esp_check.h" #include "soc/soc_caps.h" #include "mbedtls/esp_mbedtls_dynamic.h" +#include "mbedtls/private/pk_private.h" #ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN #include "mbedtls/ecp.h" #include "ecdsa/ecdsa_alt.h" @@ -47,6 +48,9 @@ static esp_err_t esp_set_atecc608a_pki_context(esp_tls_t *tls, const void *pki); static esp_err_t esp_mbedtls_init_pk_ctx_for_ds(const void *pki); #endif /* CONFIG_ESP_TLS_USE_DS_PERIPHERAL */ +#include "psa/crypto.h" +#include "mbedtls/psa_util.h" + static const char *TAG = "esp-tls-mbedtls"; static mbedtls_x509_crt *global_cacert = NULL; @@ -118,30 +122,9 @@ esp_err_t esp_create_mbedtls_handle(const char *hostname, size_t hostlen, const int ret; esp_err_t esp_ret = ESP_FAIL; -#ifdef CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 - psa_status_t status = psa_crypto_init(); - if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "Failed to initialize PSA crypto, returned %d", (int) status); - return esp_ret; - } -#endif // CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 - tls->server_fd.fd = tls->sockfd; mbedtls_ssl_init(&tls->ssl); - mbedtls_ctr_drbg_init(&tls->ctr_drbg); mbedtls_ssl_config_init(&tls->conf); - mbedtls_entropy_init(&tls->entropy); - - if ((ret = mbedtls_ctr_drbg_seed(&tls->ctr_drbg, - mbedtls_entropy_func, &tls->entropy, NULL, 0)) != 0) { - ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned -0x%04X", -ret); - mbedtls_print_error_msg(ret); - ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_MBEDTLS, -ret); - esp_ret = ESP_ERR_MBEDTLS_CTR_DRBG_SEED_FAILED; - goto exit; - } - - mbedtls_ssl_conf_rng(&tls->conf, mbedtls_ctr_drbg_random, &tls->ctr_drbg); #if CONFIG_MBEDTLS_DYNAMIC_BUFFER tls->esp_tls_dyn_buf_strategy = ((esp_tls_cfg_t *)cfg)->esp_tls_dyn_buf_strategy; @@ -202,7 +185,6 @@ esp_err_t esp_create_mbedtls_handle(const char *hostname, size_t hostlen, const exit: esp_mbedtls_cleanup(tls); return esp_ret; - } void *esp_mbedtls_get_ssl_context(esp_tls_t *tls) @@ -506,30 +488,54 @@ void esp_mbedtls_cleanup(esp_tls_t *tls) mbedtls_x509_crt_free(&tls->clientcert); #ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL - if (mbedtls_pk_get_type(&tls->clientkey) == MBEDTLS_PK_RSA_ALT) { - mbedtls_rsa_alt_context *rsa_alt = tls->clientkey.MBEDTLS_PRIVATE(pk_ctx); - if (rsa_alt && rsa_alt->key != NULL) { - mbedtls_rsa_free(rsa_alt->key); - mbedtls_free(rsa_alt->key); - rsa_alt->key = NULL; + if (mbedtls_pk_get_type(&tls->clientkey) == MBEDTLS_PK_RSASSA_PSS) { + mbedtls_rsa_context *rsa = tls->clientkey.MBEDTLS_PRIVATE(pk_ctx); + if (rsa != NULL) { + mbedtls_rsa_free(rsa); + mbedtls_free(rsa); + rsa = NULL; } + tls->clientkey.MBEDTLS_PRIVATE(pk_ctx) = NULL; } // Similar cleanup for server key - if (mbedtls_pk_get_type(&tls->serverkey) == MBEDTLS_PK_RSA_ALT) { - mbedtls_rsa_alt_context *rsa_alt = tls->serverkey.MBEDTLS_PRIVATE(pk_ctx); - if (rsa_alt && rsa_alt->key != NULL) { - mbedtls_rsa_free(rsa_alt->key); - mbedtls_free(rsa_alt->key); - rsa_alt->key = NULL; + if (mbedtls_pk_get_type(&tls->serverkey) == MBEDTLS_PK_RSASSA_PSS) { + mbedtls_rsa_context *rsa = tls->serverkey.MBEDTLS_PRIVATE(pk_ctx); + if (rsa != NULL) { + mbedtls_rsa_free(rsa); + mbedtls_free(rsa); + rsa = NULL; } + tls->serverkey.MBEDTLS_PRIVATE(pk_ctx) = NULL; + } +#endif + +#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN + /* In mbedtls v4.0, ECDSA keys require manual cleanup of the keypair structure */ + if (mbedtls_pk_get_type(&tls->clientkey) == MBEDTLS_PK_ECDSA) { + mbedtls_ecp_keypair *keypair = tls->clientkey.MBEDTLS_PRIVATE(pk_ctx); + if (keypair != NULL) { + mbedtls_ecp_keypair_free(keypair); + mbedtls_free(keypair); + keypair = NULL; + } + tls->clientkey.MBEDTLS_PRIVATE(pk_ctx) = NULL; + } + + // Similar cleanup for server key + if (mbedtls_pk_get_type(&tls->serverkey) == MBEDTLS_PK_ECDSA) { + mbedtls_ecp_keypair *keypair = tls->serverkey.MBEDTLS_PRIVATE(pk_ctx); + if (keypair != NULL) { + mbedtls_ecp_keypair_free(keypair); + mbedtls_free(keypair); + keypair = NULL; + } + tls->serverkey.MBEDTLS_PRIVATE(pk_ctx) = NULL; } #endif mbedtls_pk_free(&tls->clientkey); - mbedtls_entropy_free(&tls->entropy); mbedtls_ssl_config_free(&tls->conf); - mbedtls_ctr_drbg_free(&tls->ctr_drbg); mbedtls_ssl_free(&tls->ssl); #ifdef CONFIG_ESP_TLS_USE_SECURE_ELEMENT atcab_release(); @@ -614,8 +620,7 @@ static esp_err_t set_pki_context(esp_tls_t *tls, const esp_tls_pki_t *pki) #endif if (pki->privkey_pem_buf != NULL) { ret = mbedtls_pk_parse_key(pki->pk_key, pki->privkey_pem_buf, pki->privkey_pem_bytes, - pki->privkey_password, pki->privkey_password_len, - mbedtls_ctr_drbg_random, &tls->ctr_drbg); + pki->privkey_password, pki->privkey_password_len); } else { return ESP_ERR_INVALID_ARG; } @@ -683,22 +688,11 @@ esp_err_t esp_mbedtls_server_session_ticket_ctx_init(esp_tls_server_session_tick if (!ctx) { return ESP_ERR_INVALID_ARG; } - mbedtls_ctr_drbg_init(&ctx->ctr_drbg); - mbedtls_entropy_init(&ctx->entropy); mbedtls_ssl_ticket_init(&ctx->ticket_ctx); int ret; esp_err_t esp_ret; - if ((ret = mbedtls_ctr_drbg_seed(&ctx->ctr_drbg, - mbedtls_entropy_func, &ctx->entropy, NULL, 0)) != 0) { - ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned -0x%04X", -ret); - mbedtls_print_error_msg(ret); - esp_ret = ESP_ERR_MBEDTLS_CTR_DRBG_SEED_FAILED; - goto exit; - } - - if((ret = mbedtls_ssl_ticket_setup(&ctx->ticket_ctx, - mbedtls_ctr_drbg_random, &ctx->ctr_drbg, - MBEDTLS_CIPHER_AES_256_GCM, + if ((ret = mbedtls_ssl_ticket_setup(&ctx->ticket_ctx, + PSA_ALG_GCM, PSA_KEY_TYPE_AES, 256, CONFIG_ESP_TLS_SERVER_SESSION_TICKET_TIMEOUT)) != 0) { ESP_LOGE(TAG, "mbedtls_ssl_ticket_setup returned -0x%04X", -ret); mbedtls_print_error_msg(ret); @@ -715,8 +709,6 @@ void esp_mbedtls_server_session_ticket_ctx_free(esp_tls_server_session_ticket_ct { if (ctx) { mbedtls_ssl_ticket_free(&ctx->ticket_ctx); - mbedtls_ctr_drbg_init(&ctx->ctr_drbg); - mbedtls_entropy_free(&ctx->entropy); } } #endif @@ -958,12 +950,6 @@ esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t #endif /* CONFIG_MBEDTLS_SSL_RENEGOTIATION */ #endif /* CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS */ -#if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 -#if CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS || CONFIG_MBEDTLS_DYNAMIC_BUFFER - mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets(&tls->conf, MBEDTLS_SSL_SESSION_TICKETS_ENABLED); -#endif -#endif - if (cfg->crt_bundle_attach != NULL) { #ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE ESP_LOGD(TAG, "Use certificate bundle"); @@ -1381,6 +1367,13 @@ static esp_err_t esp_set_atecc608a_pki_context(esp_tls_t *tls, const void *pki) #endif /* CONFIG_ESP_TLS_USE_SECURE_ELEMENT */ #ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL + +int esp_mbedtls_ds_can_do(mbedtls_pk_type_t type) +{ + ESP_LOGI(TAG, "esp_mbedtls_ds_can_do called with type %d", type); + return type == MBEDTLS_PK_RSA || type == MBEDTLS_PK_RSASSA_PSS; +} + static esp_err_t esp_mbedtls_init_pk_ctx_for_ds(const void *pki) { int ret = -1; @@ -1391,15 +1384,23 @@ static esp_err_t esp_mbedtls_init_pk_ctx_for_ds(const void *pki) return ESP_ERR_NO_MEM; } mbedtls_rsa_init(rsakey); - if ((ret = mbedtls_pk_setup_rsa_alt(((const esp_tls_pki_t*)pki)->pk_key, rsakey, NULL, esp_ds_rsa_sign, - esp_ds_get_keylen )) != 0) { - ESP_LOGE(TAG, "Error in mbedtls_pk_setup_rsa_alt, returned -0x%04X", -ret); - mbedtls_print_error_msg(ret); + esp_tls_pki_t *pki_l = (esp_tls_pki_t *) pki; + mbedtls_pk_context *pk_context = (mbedtls_pk_context *) pki_l->pk_key; + mbedtls_pk_info_t *esp_ds_pk_info = calloc(1, sizeof(mbedtls_pk_info_t)); + if (esp_ds_pk_info == NULL) { + ESP_LOGE(TAG, "Failed to allocate memory for mbedtls_pk_info_t"); + ret = ESP_ERR_NO_MEM; mbedtls_rsa_free(rsakey); free(rsakey); - ret = ESP_FAIL; goto exit; } + + esp_ds_pk_info->sign_func = esp_ds_rsa_sign_alt; + esp_ds_pk_info->get_bitlen = esp_ds_get_keylen_alt; + esp_ds_pk_info->can_do = esp_mbedtls_ds_can_do; + esp_ds_pk_info->type = MBEDTLS_PK_RSASSA_PSS; + pk_context->pk_info = esp_ds_pk_info; + pk_context->pk_ctx = rsakey; ret = esp_ds_init_data_ctx(((const esp_tls_pki_t*)pki)->esp_ds_data); if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to initialize DS parameters from nvs"); diff --git a/components/esp-tls/private_include/esp_tls_private.h b/components/esp-tls/private_include/esp_tls_private.h index 728b538d13..a4cbc9d4bd 100644 --- a/components/esp-tls/private_include/esp_tls_private.h +++ b/components/esp-tls/private_include/esp_tls_private.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,8 +20,6 @@ #include "mbedtls/net_sockets.h" #include "mbedtls/esp_debug.h" #include "mbedtls/ssl.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" #include "mbedtls/error.h" #ifdef CONFIG_ESP_TLS_SERVER_SESSION_TICKETS #include "mbedtls/ssl_ticket.h" @@ -38,12 +36,6 @@ struct esp_tls { #ifdef CONFIG_ESP_TLS_USING_MBEDTLS mbedtls_ssl_context ssl; /*!< TLS/SSL context */ - mbedtls_entropy_context entropy; /*!< mbedTLS entropy context structure */ - - mbedtls_ctr_drbg_context ctr_drbg; /*!< mbedTLS ctr drbg context structure. - CTR_DRBG is deterministic random - bit generation based on AES-256 */ - mbedtls_ssl_config conf; /*!< TLS/SSL configuration to be shared between mbedtls_ssl_context structures */ diff --git a/components/esp-tls/test_apps/main/app_main.c b/components/esp-tls/test_apps/main/app_main.c index 2c1a5935ab..6a5f035179 100644 --- a/components/esp-tls/test_apps/main/app_main.c +++ b/components/esp-tls/test_apps/main/app_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,7 +7,6 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "unity.h" -#include "mbedtls/aes.h" #include "memory_checks.h" #include "soc/soc_caps.h" #if SOC_SHA_SUPPORT_PARALLEL_ENG @@ -16,12 +15,16 @@ #include "sha/sha_core.h" #endif #include "esp_newlib.h" - +#include "psa/crypto.h" #if SOC_SHA_SUPPORT_SHA512 #define SHA_TYPE SHA2_512 #else #define SHA_TYPE SHA2_256 #endif //SOC_SHA_SUPPORT_SHA512 +#include + + +#define CALL_SZ (32 * 1024) /* setUp runs before every test */ void setUp(void) @@ -34,23 +37,31 @@ void setUp(void) esp_sha(SHA_TYPE, input_buffer, sizeof(input_buffer), output_buffer); #endif // SOC_SHA_SUPPORTED -#if SOC_AES_SUPPORTED // Execute mbedtls_aes_init operation to allocate AES interrupt // allocation memory which is considered as leak otherwise - const uint8_t plaintext[16] = {0}; - uint8_t ciphertext[16]; - const uint8_t key[16] = { 0 }; - mbedtls_aes_context ctx; - mbedtls_aes_init(&ctx); - mbedtls_aes_setkey_enc(&ctx, key, 128); - mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, plaintext, ciphertext); - mbedtls_aes_free(&ctx); -#endif // SOC_AES_SUPPORTED + uint8_t iv[16]; + uint8_t key[16]; + memset(iv, 0xEE, 16); + memset(key, 0x44, 16); + + uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + TEST_ASSERT_NOT_NULL(buf); + psa_key_id_t key_id; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_ECB_NO_PADDING); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); + psa_import_key(&attributes, key, sizeof(key), &key_id); + + size_t output_length = 0; + psa_cipher_encrypt(key_id, PSA_ALG_ECB_NO_PADDING, buf, CALL_SZ, buf, CALL_SZ, &output_length); + heap_caps_free(buf); + psa_destroy_key(key_id); test_utils_record_free_mem(); TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL)); TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_GENERAL)); - } /* tearDown runs after every test */