feat: migrates esp-tls to PSA APIs

This commit is contained in:
Ashish Sharma
2025-12-23 10:29:32 +08:00
committed by Mahavir Jain
parent f22006e2f0
commit cca2a54624
6 changed files with 101 additions and 110 deletions
+1 -3
View File
@@ -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.
@@ -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;
-7
View File
@@ -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
+65 -64
View File
@@ -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");
@@ -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 */
+25 -14
View File
@@ -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 <string.h>
#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 */