From 1d185a6548210e9a2b57afc6de46715e383338e6 Mon Sep 17 00:00:00 2001 From: Ashish Sharma Date: Fri, 9 Jan 2026 16:26:05 +0800 Subject: [PATCH 1/3] feat: adds PSA DS driver support --- components/esp-tls/esp_tls_mbedtls.c | 92 ++-- .../test_apps/crypto/main/ds/test_ds.c | 4 +- components/mbedtls/CMakeLists.txt | 10 +- .../mbedtls/port/esp_ds/esp_ds_common.c | 235 --------- .../mbedtls/port/esp_ds/esp_ds_common.h | 62 --- .../mbedtls/port/esp_ds/esp_rsa_dec_alt.c | 297 ----------- .../mbedtls/port/esp_ds/esp_rsa_sign_alt.c | 408 -------------- .../mbedtls/port/include/esp_ds/esp_ds_rsa.h | 140 ----- .../port/include/esp_ds/esp_rsa_sign_alt.h | 78 --- components/mbedtls/port/include/rsa_dec_alt.h | 21 - .../mbedtls/port/include/rsa_sign_alt.h | 21 - .../psa_crypto_driver_esp_ds_utilities.h | 98 ++++ .../esp_ds/psa_crypto_driver_esp_ds.c | 474 +++++++++++++++++ .../psa_crypto_driver_esp_ds_utilities.c | 497 ++++++++++++++++++ .../include/psa_crypto_driver_esp_ds.h | 82 +++ .../psa_crypto_driver_esp_ds_contexts.h | 42 ++ .../mbedtls/test_apps/main/CMakeLists.txt | 6 +- .../test_apps/main/test_ds_sign_and_decrypt.c | 394 ++++++++------ components/mbedtls/test_apps/partitions.csv | 4 + 19 files changed, 1500 insertions(+), 1465 deletions(-) delete mode 100644 components/mbedtls/port/esp_ds/esp_ds_common.c delete mode 100644 components/mbedtls/port/esp_ds/esp_ds_common.h delete mode 100644 components/mbedtls/port/esp_ds/esp_rsa_dec_alt.c delete mode 100644 components/mbedtls/port/esp_ds/esp_rsa_sign_alt.c delete mode 100644 components/mbedtls/port/include/esp_ds/esp_ds_rsa.h delete mode 100644 components/mbedtls/port/include/esp_ds/esp_rsa_sign_alt.h delete mode 100644 components/mbedtls/port/include/rsa_dec_alt.h delete mode 100644 components/mbedtls/port/include/rsa_sign_alt.h create mode 100644 components/mbedtls/port/psa_driver/esp_ds/include/psa_crypto_driver_esp_ds_utilities.h create mode 100644 components/mbedtls/port/psa_driver/esp_ds/psa_crypto_driver_esp_ds.c create mode 100644 components/mbedtls/port/psa_driver/esp_ds/psa_crypto_driver_esp_ds_utilities.c create mode 100644 components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ds.h create mode 100644 components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ds_contexts.h create mode 100644 components/mbedtls/test_apps/partitions.csv diff --git a/components/esp-tls/esp_tls_mbedtls.c b/components/esp-tls/esp_tls_mbedtls.c index c77f07f940..c020262a7a 100644 --- a/components/esp-tls/esp_tls_mbedtls.c +++ b/components/esp-tls/esp_tls_mbedtls.c @@ -44,7 +44,8 @@ static esp_err_t esp_set_atecc608a_pki_context(esp_tls_t *tls, const void *pki); #if defined(CONFIG_ESP_TLS_USE_DS_PERIPHERAL) #include -#include "rsa_sign_alt.h" +#include "psa/crypto.h" +#include "psa_crypto_driver_esp_ds.h" static esp_err_t esp_mbedtls_init_pk_ctx_for_ds(const void *pki); #endif /* CONFIG_ESP_TLS_USE_DS_PERIPHERAL */ @@ -289,9 +290,6 @@ int esp_mbedtls_handshake(esp_tls_t *tls, const esp_tls_cfg_t *cfg) #endif tls->conn_state = ESP_TLS_DONE; -#ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL - esp_ds_release_ds_lock(); -#endif return 1; } else { if (ret != ESP_TLS_ERR_SSL_WANT_READ && ret != ESP_TLS_ERR_SSL_WANT_WRITE) { @@ -503,6 +501,9 @@ void esp_mbedtls_cleanup(esp_tls_t *tls) mbedtls_free(rsa); rsa = NULL; } + if (tls->clientkey.MBEDTLS_PRIVATE(priv_id) != PSA_KEY_ID_NULL) { + psa_destroy_key(tls->clientkey.MBEDTLS_PRIVATE(priv_id)); + } tls->clientkey.MBEDTLS_PRIVATE(pk_ctx) = NULL; } @@ -514,6 +515,9 @@ void esp_mbedtls_cleanup(esp_tls_t *tls) mbedtls_free(rsa); rsa = NULL; } + if (tls->serverkey.MBEDTLS_PRIVATE(priv_id) != PSA_KEY_ID_NULL) { + psa_destroy_key(tls->serverkey.MBEDTLS_PRIVATE(priv_id)); + } tls->serverkey.MBEDTLS_PRIVATE(pk_ctx) = NULL; } #endif @@ -551,9 +555,6 @@ void esp_mbedtls_cleanup(esp_tls_t *tls) #ifdef CONFIG_ESP_TLS_USE_SECURE_ELEMENT atcab_release(); #endif -#ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL - esp_ds_release_ds_lock(); -#endif } static esp_err_t set_ca_cert(esp_tls_t *tls, const unsigned char *cacert, size_t cacert_len) @@ -1062,7 +1063,7 @@ esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t ESP_LOGE(TAG, "Client certificate is also required with the DS parameters"); return ESP_ERR_INVALID_STATE; } - esp_ds_set_session_timeout(cfg->timeout_ms); + esp_ds_opaque_set_session_timeout(cfg->timeout_ms); /* set private key pointer to NULL since the DS peripheral with its own configuration data is used */ esp_tls_pki_t pki = { .public_cert = &tls->clientcert, @@ -1403,47 +1404,48 @@ 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; - /* initialize the mbedtls pk context with rsa context */ - mbedtls_rsa_context *rsakey = calloc(1, sizeof(mbedtls_rsa_context)); - if (rsakey == NULL) { - ESP_LOGE(TAG, "Failed to allocate memory for mbedtls_rsa_context"); - return ESP_ERR_NO_MEM; - } - mbedtls_rsa_init(rsakey); - 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); - goto exit; + esp_ds_data_ctx_t *ds_data = ((const esp_tls_pki_t*)pki)->esp_ds_data; + if (ds_data == NULL) { + ESP_LOGE(TAG, "DS data context is NULL"); + return ESP_ERR_INVALID_ARG; } - 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"); - goto exit; + esp_tls_pki_t *pki_l = (esp_tls_pki_t *) pki; + if (pki_l->pk_key == NULL) { + ESP_LOGE(TAG, "PK key context is NULL"); + return ESP_ERR_INVALID_ARG; } - ESP_LOGD(TAG, "DS peripheral params initialized."); -exit: - return ret; + + psa_key_id_t ds_key_id = 0; + psa_status_t status = PSA_ERROR_GENERIC_ERROR; + psa_key_attributes_t ds_key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH); +#ifdef CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 + psa_set_key_enrollment_algorithm(&ds_key_attributes, PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH)); +#endif /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */ + + psa_set_key_type(&ds_key_attributes, PSA_KEY_TYPE_RSA_KEY_PAIR); + psa_set_key_bits(&ds_key_attributes, ds_data->rsa_length_bits); + psa_set_key_usage_flags(&ds_key_attributes, PSA_KEY_USAGE_SIGN_HASH); + psa_set_key_algorithm(&ds_key_attributes, alg); + psa_set_key_lifetime(&ds_key_attributes, PSA_KEY_LIFETIME_ESP_DS); + status = psa_import_key(&ds_key_attributes, + (const uint8_t *)ds_data, + sizeof(esp_ds_data_ctx_t), + &ds_key_id); + psa_reset_key_attributes(&ds_key_attributes); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to import DS key to PSA, status = %d", status); + return ESP_ERR_INVALID_STATE; + } + int ret = mbedtls_pk_wrap_psa(pki_l->pk_key, ds_key_id); + if (ret != 0) { + ESP_LOGE(TAG, "mbedtls_pk_wrap_psa failed with -0x%04X", -ret); + return ret; + } + ESP_LOGD(TAG, "DS peripheral pk context initialized."); + return ESP_OK; } #endif /* CONFIG_ESP_TLS_USE_DS_PERIPHERAL */ diff --git a/components/esp_hal_security/test_apps/crypto/main/ds/test_ds.c b/components/esp_hal_security/test_apps/crypto/main/ds/test_ds.c index e4a8f31730..ddf5858eb1 100644 --- a/components/esp_hal_security/test_apps/crypto/main/ds/test_ds.c +++ b/components/esp_hal_security/test_apps/crypto/main/ds/test_ds.c @@ -149,7 +149,7 @@ static esp_err_t esp_ds_finish_sign(void *signature, const esp_ds_data_t *data) return return_value; } -esp_err_t esp_ds_sign(const void *message, +static esp_err_t esp_ds_sign(const void *message, const esp_ds_data_t *data, uint32_t key_id, void *signature) @@ -247,7 +247,7 @@ static esp_err_t esp_ds_start_sign(const void *message, return ESP_OK; } -esp_err_t esp_ds_finish_sign(void *signature, const esp_ds_data_t *data) +static esp_err_t esp_ds_finish_sign(void *signature, const esp_ds_data_t *data) { ets_ds_result_t result = ets_ds_finish_sign(signature, (ets_ds_data_t*) data); diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index c7b6ee10e3..dc54525fa0 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -383,14 +383,16 @@ if(CONFIG_SOC_HMAC_SUPPORTED) endif() if(CONFIG_SOC_DIG_SIGN_SUPPORTED) +target_compile_definitions(tfpsacrypto PRIVATE ESP_DS_DRIVER_ENABLED) target_sources(tfpsacrypto PRIVATE - "${COMPONENT_DIR}/port/esp_ds/esp_rsa_sign_alt.c" - "${COMPONENT_DIR}/port/esp_ds/esp_rsa_dec_alt.c" - "${COMPONENT_DIR}/port/esp_ds/esp_ds_common.c") + "${COMPONENT_DIR}/port/psa_driver/esp_ds/psa_crypto_driver_esp_ds.c" + "${COMPONENT_DIR}/port/psa_driver/esp_ds/psa_crypto_driver_esp_ds_utilities.c" +) +target_link_libraries(tfpsacrypto PRIVATE idf::efuse) endif() # # CONFIG_ESP_TLS_USE_DS_PERIPHERAL can be enabled only for the supported targets. if(CONFIG_ESP_TLS_USE_DS_PERIPHERAL) - target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/esp_ds/esp_rsa_sign_alt.c") + # target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/esp_ds/esp_rsa_sign_alt.c") endif() if(CONFIG_SOC_HMAC_SUPPORTED) diff --git a/components/mbedtls/port/esp_ds/esp_ds_common.c b/components/mbedtls/port/esp_ds/esp_ds_common.c deleted file mode 100644 index 9dcaaba004..0000000000 --- a/components/mbedtls/port/esp_ds/esp_ds_common.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "sdkconfig.h" -#include "esp_ds.h" -#include "esp_log.h" -#include "esp_ds_common.h" -#include "esp_memory_utils.h" -#include "esp_ds/esp_ds_rsa.h" -#include "freertos/FreeRTOS.h" -#include "freertos/semphr.h" -#include "psa/crypto.h" - -#ifdef SOC_DIG_SIGN_SUPPORTED -#include "rom/digital_signature.h" -#else -#error "Selected target does not support DS peripheral" -#endif - -#define FACTOR_KEYLEN_IN_BYTES 4 - -static const char *TAG = "ESP_DS_COMMON"; - -static hmac_key_id_t s_esp_ds_hmac_key_id = -1; -static esp_ds_data_t *s_ds_data = NULL; -static SemaphoreHandle_t s_ds_lock = NULL; -static int s_timeout_ms = 0; - -esp_ds_data_t *esp_ds_get_data_ctx(void) -{ - return s_ds_data; -} - -hmac_key_id_t esp_ds_get_hmac_key_id(void) -{ - return s_esp_ds_hmac_key_id; -} - -size_t esp_ds_get_keylen(void *ctx) -{ - if (s_ds_data == NULL) { - ESP_LOGE(TAG, "s_ds_data is NULL, cannot get key length"); - return 0; - } - /* calculating the rsa_length in bytes */ - return ((s_ds_data->rsa_length + 1) * FACTOR_KEYLEN_IN_BYTES); -} - -size_t esp_ds_get_keylen_alt(mbedtls_pk_context *ctx) -{ - if (s_ds_data == NULL) { - ESP_LOGE(TAG, "s_ds_data is NULL, cannot get key length"); - return 0; - } - /* calculating the rsa_length in bytes */ - return ((s_ds_data->rsa_length + 1) * FACTOR_KEYLEN_IN_BYTES); -} - -/* Lock for the DS session, other TLS connections trying to use the DS peripheral will be blocked - * till this DS session is completed (i.e. TLS handshake for this connection is completed) */ -static void __attribute__((constructor)) esp_ds_conn_lock(void) -{ - if ((s_ds_lock = xSemaphoreCreateMutex()) == NULL) { - ESP_EARLY_LOGE(TAG, "mutex for the DS session lock could not be created"); - } -} - -void esp_ds_release_ds_lock(void) -{ - if (s_ds_lock == NULL) { - ESP_LOGE(TAG, "s_ds_lock is NULL, cannot release lock"); - return; - } - if (xSemaphoreGetMutexHolder(s_ds_lock) == xTaskGetCurrentTaskHandle()) { - /* Give back the semaphore (DS lock) */ - xSemaphoreGive(s_ds_lock); - } -} - -void esp_ds_set_session_timeout(int timeout) -{ - /* add additional offset of 1000 ms to have enough time for deleting the TLS connection and free the previous ds context after exceeding timeout value (this offset also helps when timeout is set to 0) */ - if (timeout > s_timeout_ms) { - s_timeout_ms = timeout + 1000; - } -} - -esp_err_t esp_ds_init_data_ctx(esp_ds_data_ctx_t *ds_data) -{ - if (ds_data == NULL || ds_data->esp_ds_data == NULL) { - return ESP_ERR_INVALID_ARG; - } - /* mutex is given back when the DS context is freed after the TLS handshake is completed or in case of failure (at cleanup) */ - if ((xSemaphoreTake(s_ds_lock, s_timeout_ms / portTICK_PERIOD_MS) != pdTRUE)) { - ESP_LOGE(TAG, "ds_lock could not be obtained in specified time"); - return ESP_FAIL; - } - s_ds_data = ds_data->esp_ds_data; - ESP_LOGD(TAG, "Using DS with key block %u, RSA length %u", ds_data->efuse_key_id, ds_data->rsa_length_bits); - s_esp_ds_hmac_key_id = (hmac_key_id_t) ds_data->efuse_key_id; - - const unsigned rsa_length_int = (ds_data->rsa_length_bits / 32) - 1; - if (esp_ptr_byte_accessible(s_ds_data)) { - /* calculate the rsa_length in terms of esp_digital_signature_length_t which is required for the internal DS API */ - s_ds_data->rsa_length = rsa_length_int; - } else if (s_ds_data->rsa_length != rsa_length_int) { - /* - * Configuration data is most likely from DROM segment and it - * is not properly formatted for all parameters consideration. - * Moreover, we can not modify as it is read-only and hence - * the error. - */ - ESP_LOGE(TAG, "RSA length mismatch %u, %u", s_ds_data->rsa_length, rsa_length_int); - return ESP_ERR_INVALID_ARG; - } - - return ESP_OK; -} - -esp_err_t esp_ds_deinit_data_ctx(void) -{ - esp_ds_release_ds_lock(); - s_ds_data = NULL; - s_esp_ds_hmac_key_id = -1; - - return ESP_OK; -} - -int esp_ds_mgf_mask(unsigned char *dst, size_t dlen, unsigned char *src, - size_t slen, mbedtls_md_type_t md_alg) -{ - unsigned char counter[4]; - unsigned char *p; - unsigned int hlen; - size_t i, use_len; - unsigned char mask[MBEDTLS_MD_MAX_SIZE]; - int ret = 0; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - - mbedtls_md_init(&md_ctx); - md_info = mbedtls_md_info_from_type(md_alg); - if (md_info == NULL) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - if ((ret = mbedtls_md_setup(&md_ctx, md_info, 0)) != 0) { - goto exit; - } - - hlen = mbedtls_md_get_size(md_info); - - memset(mask, 0, sizeof(mask)); - memset(counter, 0, 4); - - /* Generate and apply dbMask */ - p = dst; - - while (dlen > 0) { - use_len = hlen; - if (dlen < hlen) { - use_len = dlen; - } - - if ((ret = mbedtls_md_starts(&md_ctx)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_update(&md_ctx, src, slen)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_update(&md_ctx, counter, 4)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_finish(&md_ctx, mask)) != 0) { - goto exit; - } - - for (i = 0; i < use_len; ++i) { - *p++ ^= mask[i]; - } - - counter[3]++; - - dlen -= use_len; - } - -exit: - mbedtls_platform_zeroize(mask, sizeof(mask)); - mbedtls_md_free(&md_ctx); - - return ret; -} - -int esp_ds_hash_mprime(const unsigned char *hash, size_t hlen, - const unsigned char *salt, size_t slen, - unsigned char *out, mbedtls_md_type_t md_alg) -{ - const unsigned char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - - mbedtls_md_context_t md_ctx; - int ret = PSA_ERROR_INVALID_ARGUMENT; - - const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_alg); - if (md_info == NULL) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - mbedtls_md_init(&md_ctx); - if ((ret = mbedtls_md_setup(&md_ctx, md_info, 0)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_starts(&md_ctx)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_update(&md_ctx, zeros, sizeof(zeros))) != 0) { - goto exit; - } - if ((ret = mbedtls_md_update(&md_ctx, hash, hlen)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_update(&md_ctx, salt, slen)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_finish(&md_ctx, out)) != 0) { - goto exit; - } - -exit: - mbedtls_md_free(&md_ctx); - - return ret; -} diff --git a/components/mbedtls/port/esp_ds/esp_ds_common.h b/components/mbedtls/port/esp_ds/esp_ds_common.h deleted file mode 100644 index b80f702a5d..0000000000 --- a/components/mbedtls/port/esp_ds/esp_ds_common.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include "mbedtls/md.h" - -#define FACTOR_KEYLEN_IN_BYTES 4 -#define SWAP_INT32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | ((x) << 24)) - -/** - * @brief Get the data context for the digital signature. - * - * @return esp_ds_data_t* esp ds data context pointer. - */ -esp_ds_data_t *esp_ds_get_data_ctx(void); - -/** - * @brief Get the HMAC key ID used for digital signature operations. - * - * @return hmac_key_id_t HMAC key ID. - */ -hmac_key_id_t esp_ds_get_hmac_key_id(void); - -/** - * @brief Mask generation function (MGF) for TLS 1.3. - * - * @param[in] dst Pointer to the destination buffer. - * @param[in] dlen Length of the destination buffer. - * @param[in] src Pointer to the source buffer. - * @param[in] slen Length of the salt value. - * @param[in] md_alg The message digest algorithm type. - * @return int Returns 0 on success, or a negative error code on failure. - */ -int esp_ds_mgf_mask(unsigned char *dst, size_t dlen, unsigned char *src, - size_t slen, mbedtls_md_type_t md_alg); - -/** - * @brief Generates a hash using the M-Prime algorithm as specified in RFC 8446. - * - * @param hash Pointer to the input hash. - * @param hlen Length of the input hash. - * @param salt Pointer to the salt value. - * @param slen Length of the salt value. - * @param out Pointer to the output buffer where the hash will be stored. - * @param md_alg The message digest algorithm type to use for hashing. - * @return int Returns 0 on success, or a negative error code on failure. - */ -int esp_ds_hash_mprime(const unsigned char *hash, size_t hlen, - const unsigned char *salt, size_t slen, - unsigned char *out, mbedtls_md_type_t md_alg); - -#ifdef __cplusplus -} -#endif diff --git a/components/mbedtls/port/esp_ds/esp_rsa_dec_alt.c b/components/mbedtls/port/esp_ds/esp_rsa_dec_alt.c deleted file mode 100644 index 55b60497a3..0000000000 --- a/components/mbedtls/port/esp_ds/esp_rsa_dec_alt.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - - -#include -#include "sdkconfig.h" -#include "esp_ds.h" -#include "rsa_dec_alt.h" -#include "mbedtls/private/rsa.h" -#include "psa/crypto.h" -#include "esp_ds_common.h" -#include "esp_log.h" - -static const char *TAG = "ESP_RSA_DEC_ALT"; - -#define MIN_V15_PADDING_LEN 11 - -static int esp_ds_rsaes_pkcs1_v15_unpadding(unsigned char *input, - size_t ilen, - unsigned char *output, - size_t output_max_len, - size_t *olen) -{ - if (ilen < MIN_V15_PADDING_LEN) { - return MBEDTLS_ERR_CIPHER_INVALID_PADDING; - } - - unsigned char bad = 0; - size_t msg_len = 0; - size_t msg_max_len = 0; - unsigned char pad_done = 0; - size_t pad_count = 0; - - msg_max_len = (output_max_len > ilen - MIN_V15_PADDING_LEN) ? ilen - MIN_V15_PADDING_LEN : output_max_len; - - /* Check the first byte (0x00) */ - bad |= input[0]; - - /* Check the padding type */ - bad |= input[1] ^ 2; // MBEDTLS_RSA_CRYPT; - - /* Scan for separator (0x00) and count padding bytes in constant time */ - for (size_t i = 2; i < ilen; i++) { - unsigned char found = (input[i] == 0x00); - pad_done = pad_done | found; - pad_count += (pad_done == 0) ? 1 : 0; - } - - /* Check if we found a separator and padding is long enough */ - bad |= (pad_done == 0); /* No separator found */ - bad |= (pad_count < 8); /* Padding too short (need at least 8 non-zero bytes) */ - - /* Calculate message length */ - msg_len = ilen - pad_count - 3; - - /* Check if separator is not at the very end */ - bad |= (msg_len > output_max_len); - if (bad) { - msg_len = msg_max_len; - } - - /* Verify padding bytes are non-zero in constant time */ -#if defined(__clang__) && defined(__xtensa__) - #pragma clang loop vectorize(disable) -#endif - for (size_t i = 2; i < ilen; i++) { - unsigned char in_padding = (i < pad_count + 2); - unsigned char is_zero = (input[i] == 0x00); - bad |= in_padding & is_zero; - } - - if (bad) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - *olen = msg_len; - if (*olen > 0) { - memcpy(output, input + ilen - msg_len, msg_len); - } - return 0; -} - -static int esp_ds_compute_hash(mbedtls_md_type_t md_alg, - const unsigned char *input, size_t ilen, - unsigned char *output) -{ - const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_alg); - if (md_info == NULL) { - return PSA_ERROR_INVALID_ARGUMENT; - } - return mbedtls_md(md_info, input, ilen, output); -} - -static int esp_ds_rsaes_pkcs1_v21_unpadding(unsigned char *input, - size_t ilen, - unsigned char *output, - size_t output_max_len, - size_t *olen) -{ - int ret; - unsigned int hlen = mbedtls_md_get_size_from_type(MBEDTLS_MD_SHA256); - unsigned char bad = 0; - size_t pad_len = 0; - size_t msg_len = 0; - - /* Validate input length */ - bad |= (ilen < 2 * hlen + 2); - - /* Apply MGF masks */ - ret = esp_ds_mgf_mask(input + 1, hlen, input + hlen + 1, ilen - hlen - 1, MBEDTLS_MD_SHA256); - if (ret != 0) { - ESP_LOGE(TAG, "Error in MGF mask, returned %d", ret); - return ret; - } - - ret = esp_ds_mgf_mask(input + hlen + 1, ilen - hlen - 1, input + 1, hlen, MBEDTLS_MD_SHA256); - if (ret != 0) { - ESP_LOGE(TAG, "Error in MGF mask, returned %d", ret); - return ret; - } - - /* Check first byte (should be 0x00) */ - bad |= input[0]; - - /* Skip the first byte and maskSeed */ - unsigned char *db = input + 1 + hlen; - size_t db_len = ilen - hlen - 1; - - /* Compute hash, label is NULL and label_len is 0 */ - unsigned char lhash[MBEDTLS_MD_MAX_SIZE]; - ret = esp_ds_compute_hash(MBEDTLS_MD_SHA256, NULL, 0, lhash); - if (ret != 0) { - ESP_LOGE(TAG, "Error in compute_hash, returned %d", ret); - return ret; - } - - /* Verify hash portion of db against lhash */ - for (size_t i = 0; i < hlen && i < db_len; i++) { - bad |= db[i] ^ lhash[i]; - } - - /* Skip past lhash in DB */ - unsigned char *p = db + hlen; - size_t remaining = db_len - hlen; - - /* Get zero-padding len, following mbedTLS pattern - * Always read till end of buffer (minus one, for the 01 byte) */ - unsigned char in_padding = 1; - for (size_t i = 0; i < remaining - 1; i++) { - unsigned char is_zero = (p[i] == 0); - in_padding = in_padding & is_zero; - pad_len += in_padding; - } - - p += pad_len; - bad |= (*p != 0x01); - p++; - - /* Calculate message length */ - msg_len = remaining - pad_len - 1; - - /* Check output buffer size */ - bad |= (output_max_len < msg_len); - - if (bad) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - /* Copy message in constant time */ - *olen = msg_len; - if (*olen > 0) { - memcpy(output, p, msg_len); - } - - return 0; -} - -int esp_ds_rsa_decrypt(void *ctx, size_t *olen, - const unsigned char *input, unsigned char *output, - size_t output_max_len) -{ - int padding = MBEDTLS_PK_RSA_PKCS_V15; - - if (ctx != NULL) { - mbedtls_rsa_context *rsa_ctx = (mbedtls_rsa_context *)ctx; - if (rsa_ctx->MBEDTLS_PRIVATE(padding) == MBEDTLS_RSA_PKCS_V15) { - padding = MBEDTLS_RSA_PKCS_V15; - } else if (rsa_ctx->MBEDTLS_PRIVATE(padding) == MBEDTLS_RSA_PKCS_V21) { - padding = MBEDTLS_RSA_PKCS_V21; - } else { - ESP_LOGE(TAG, "Unsupported padding type %d", rsa_ctx->MBEDTLS_PRIVATE(padding)); - return -1; - } - } - - size_t ilen = esp_ds_get_keylen(ctx); - if (ilen == 0) { - ESP_LOGE(TAG, "Invalid RSA key length"); - return -1; - } - size_t data_len = ilen / 4; - - uint32_t *output_tmp = NULL; - - uint32_t *input_tmp = calloc(data_len, sizeof(uint32_t)); - if (input_tmp == NULL) { - ESP_LOGE(TAG, "Could not allocate memory for internal DS operations"); - return -1; - } - - for (unsigned int i = 0; i < (data_len); i++) { - input_tmp[i] = SWAP_INT32(((uint32_t *)input)[(data_len) - (i + 1)]); - } - - esp_ds_data_t *s_ds_data = esp_ds_get_data_ctx(); - if (s_ds_data == NULL) { - ESP_LOGE(TAG, "s_ds_data is NULL, cannot perform decryption"); - free(input_tmp); - return -1; - } - hmac_key_id_t s_esp_ds_hmac_key_id = esp_ds_get_hmac_key_id(); - - esp_ds_context_t *esp_ds_ctx = NULL; - esp_err_t ds_r = esp_ds_start_sign((const void *)input_tmp, - s_ds_data, - s_esp_ds_hmac_key_id, - &esp_ds_ctx); - - if (ds_r != ESP_OK) { - ESP_LOGE(TAG, "Error in esp_ds_start_sign, returned %x ", ds_r); - goto exit; - } - - ds_r = esp_ds_finish_sign((void *)input_tmp, esp_ds_ctx); - if (ds_r != ESP_OK) { - if (ds_r == ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST) { - ESP_LOGE(TAG, "Invalid digest in DS data reported by esp_ds_finish_sign"); - } else { - ESP_LOGE(TAG, "Error in esp_ds_finish_sign, returned %x ", ds_r); - } - goto exit; - } - - esp_ds_release_ds_lock(); - - output_tmp = calloc(data_len, sizeof(uint32_t)); - if (output_tmp == NULL) { - ESP_LOGE(TAG, "Could not allocate memory for output_tmp"); - goto exit; - } - - for (unsigned int i = 0; i < (data_len); i++) { - ((uint32_t *)output_tmp)[i] = SWAP_INT32(((uint32_t *)input_tmp)[(data_len) - (i + 1)]); - } - - // Unpad the decrypted data - if (padding == MBEDTLS_PK_RSA_PKCS_V15) { - if (esp_ds_rsaes_pkcs1_v15_unpadding((uint8_t *)output_tmp, ilen, (uint8_t *)output_tmp, ilen, olen) != 0) { - ESP_LOGE(TAG, "Error in v15 unpadding"); - goto exit; - } - } else if (padding == MBEDTLS_PK_RSA_PKCS_V21) { - if (esp_ds_rsaes_pkcs1_v21_unpadding((uint8_t *)output_tmp, ilen, (uint8_t *)output_tmp, ilen, olen) != 0) { - ESP_LOGE(TAG, "Error in v21 unpadding"); - goto exit; - } - } else { - ESP_LOGE(TAG, "Unsupported padding type %d", padding); - goto exit; - } - - // Copy the decrypted data to output buffer - if (output_max_len < *olen) { - ESP_LOGE(TAG, "Output buffer is too small, output_max_len: %zu, olen: %zu", output_max_len, *olen); - goto exit; - } - - memcpy(output, output_tmp, *olen); - free(output_tmp); - free(input_tmp); - return 0; -exit: - esp_ds_release_ds_lock(); - if (input_tmp) { - free(input_tmp); - } - if (output_tmp) { - free(output_tmp); - } - if (olen) { - *olen = 0; // Set olen to 0 in case of error - } - return -1; -} diff --git a/components/mbedtls/port/esp_ds/esp_rsa_sign_alt.c b/components/mbedtls/port/esp_ds/esp_rsa_sign_alt.c deleted file mode 100644 index ff273287d7..0000000000 --- a/components/mbedtls/port/esp_ds/esp_rsa_sign_alt.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - * - * SPDX-FileContributor: The Mbed TLS Contributors - */ - -#include "sdkconfig.h" -#include "rsa_sign_alt.h" -#include "esp_ds.h" -#include "esp_ds_common.h" -#include "esp_log.h" -#include "esp_heap_caps.h" -#include "freertos/FreeRTOS.h" -#include "freertos/semphr.h" -#include "psa/crypto.h" -#include "mbedtls/psa_util.h" -#include "mbedtls/private/rsa.h" -#include "mbedtls/pk.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/asn1.h" -#include "mbedtls/md.h" -#include - -static const char *TAG = "ESP_RSA_SIGN_ALT"; - -/* - * Local OID lookup table for hash algorithms - * This replicates the OID data needed for PKCS#1 v1.5 DigestInfo encoding - * Since OID access has moved to internal driver headers in PSA transition, - * we maintain this local table for the hardware accelerator implementation. - */ -typedef struct { - mbedtls_md_type_t md_alg; - const char *oid; - size_t oid_len; -} oid_md_mapping_t; - -static const oid_md_mapping_t oid_md_table[] = { -#if defined(PSA_WANT_ALG_MD5) - { MBEDTLS_MD_MD5, "\x2a\x86\x48\x86\xf7\x0d\x02\x05", 8 }, -#endif -#if defined(PSA_WANT_ALG_SHA_1) - { MBEDTLS_MD_SHA1, "\x2b\x0e\x03\x02\x1a", 5 }, -#endif -#if defined(PSA_WANT_ALG_SHA_224) - { MBEDTLS_MD_SHA224, "\x60\x86\x48\x01\x65\x03\x04\x02\x04", 9 }, -#endif -#if defined(PSA_WANT_ALG_SHA_256) - { MBEDTLS_MD_SHA256, "\x60\x86\x48\x01\x65\x03\x04\x02\x01", 9 }, -#endif -#if defined(PSA_WANT_ALG_SHA_384) - { MBEDTLS_MD_SHA384, "\x60\x86\x48\x01\x65\x03\x04\x02\x02", 9 }, -#endif -#if defined(PSA_WANT_ALG_SHA_512) - { MBEDTLS_MD_SHA512, "\x60\x86\x48\x01\x65\x03\x04\x02\x03", 9 }, -#endif -#if defined(PSA_WANT_ALG_RIPEMD160) - { MBEDTLS_MD_RIPEMD160, "\x2b\x24\x03\x02\x01", 5 }, -#endif - { MBEDTLS_MD_NONE, NULL, 0 } -}; - -/** - * @brief Get OID for hash algorithm (local implementation) - * - * @param md_alg Hash algorithm type - * @param oid Output pointer for OID string - * @param olen Output pointer for OID length - * @return 0 on success, PSA_ERROR_NOT_SUPPORTED if not found - */ -static int esp_ds_get_oid_by_md(mbedtls_md_type_t md_alg, const char **oid, size_t *olen) -{ - for (size_t i = 0; oid_md_table[i].md_alg != MBEDTLS_MD_NONE; i++) { - if (oid_md_table[i].md_alg == md_alg) { - *oid = oid_md_table[i].oid; - *olen = oid_md_table[i].oid_len; - return 0; - } - } - return PSA_ERROR_NOT_SUPPORTED; -} - -static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - size_t dst_len, - unsigned char *dst ) -{ - size_t oid_size = 0; - size_t nb_pad = dst_len; - unsigned char *p = dst; - const char *oid = NULL; - - /* Are we signing hashed or raw data? */ - if ( md_alg != MBEDTLS_MD_NONE ) { - const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); - if ( md_info == NULL ) { - return ( PSA_ERROR_INVALID_ARGUMENT ); - } - - if ( esp_ds_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) { - return ( PSA_ERROR_INVALID_ARGUMENT ); - } - - hashlen = mbedtls_md_get_size( md_info ); - - /* Double-check that 8 + hashlen + oid_size can be used as a - * 1-byte ASN.1 length encoding and that there's no overflow. */ - if ( 8 + hashlen + oid_size >= 0x80 || - 10 + hashlen < hashlen || - 10 + hashlen + oid_size < 10 + hashlen ) { - return ( PSA_ERROR_INVALID_ARGUMENT ); - } - - /* - * Static bounds check: - * - Need 10 bytes for five tag-length pairs. - * (Insist on 1-byte length encodings to protect against variants of - * Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification) - * - Need hashlen bytes for hash - * - Need oid_size bytes for hash alg OID. - */ - if ( nb_pad < 10 + hashlen + oid_size ) { - return ( PSA_ERROR_INVALID_ARGUMENT ); - } - nb_pad -= 10 + hashlen + oid_size; - } else { - if ( nb_pad < hashlen ) { - return ( PSA_ERROR_INVALID_ARGUMENT ); - } - - nb_pad -= hashlen; - } - - /* Need space for signature header and padding delimiter (3 bytes), - * and 8 bytes for the minimal padding */ - if ( nb_pad < 3 + 8 ) { - return ( PSA_ERROR_INVALID_ARGUMENT ); - } - nb_pad -= 3; - - /* Now nb_pad is the amount of memory to be filled - * with padding, and at least 8 bytes long. */ - - /* Write signature header and padding */ - *p++ = 0; - *p++ = 1; //MBEDTLS_RSA_SIGN; - memset( p, 0xFF, nb_pad ); - p += nb_pad; - *p++ = 0; - - /* Are we signing raw data? */ - if ( md_alg == MBEDTLS_MD_NONE ) { - memcpy( p, hash, hashlen ); - return ( 0 ); - } - - /* Signing hashed data, add corresponding ASN.1 structure - * - * DigestInfo ::= SEQUENCE { - * digestAlgorithm DigestAlgorithmIdentifier, - * digest Digest } - * DigestAlgorithmIdentifier ::= AlgorithmIdentifier - * Digest ::= OCTET STRING - * - * Schematic: - * TAG-SEQ + LEN [ TAG-SEQ + LEN [ TAG-OID + LEN [ OID ] - * TAG-NULL + LEN [ NULL ] ] - * TAG-OCTET + LEN [ HASH ] ] - */ - *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; - *p++ = (unsigned char)( 0x08 + oid_size + hashlen ); - *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; - *p++ = (unsigned char)( 0x04 + oid_size ); - *p++ = MBEDTLS_ASN1_OID; - *p++ = (unsigned char) oid_size; - memcpy( p, oid, oid_size ); - p += oid_size; - *p++ = MBEDTLS_ASN1_NULL; - *p++ = 0x00; - *p++ = MBEDTLS_ASN1_OCTET_STRING; - *p++ = (unsigned char) hashlen; - memcpy( p, hash, hashlen ); - p += hashlen; - - /* Just a sanity-check, should be automatic - * after the initial bounds check. */ - if ( p != dst + dst_len ) { - mbedtls_platform_zeroize( dst, dst_len ); - return ( PSA_ERROR_INVALID_ARGUMENT ); - } - - return ( 0 ); -} - -#ifdef CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 -static int rsa_rsassa_pss_pkcs1_v21_encode( int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - int saltlen, - unsigned char *sig, size_t dst_len) -{ - size_t olen; - unsigned char *p = sig; - unsigned char *salt = NULL; - size_t slen, min_slen, hlen, offset = 0; - int ret = PSA_ERROR_INVALID_ARGUMENT; - size_t msb; - - if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - if (f_rng == NULL) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - olen = dst_len; - - if (md_alg != MBEDTLS_MD_NONE) { - /* Gather length of hash to sign */ - size_t exp_hashlen = mbedtls_md_get_size_from_type(md_alg); - if (exp_hashlen == 0) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - if (hashlen != exp_hashlen) { - return PSA_ERROR_INVALID_ARGUMENT; - } - } - - hlen = mbedtls_md_get_size_from_type(md_alg); - if (hlen == 0) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - if (saltlen == -1) { - /* Calculate the largest possible salt length, up to the hash size. - * Normally this is the hash length, which is the maximum salt length - * according to FIPS 185-4 �5.5 (e) and common practice. If there is not - * enough room, use the maximum salt length that fits. The constraint is - * that the hash length plus the salt length plus 2 bytes must be at most - * the key length. This complies with FIPS 186-4 �5.5 (e) and RFC 8017 - * (PKCS#1 v2.2) �9.1.1 step 3. */ - min_slen = hlen - 2; - if (olen < hlen + min_slen + 2) { - return PSA_ERROR_INVALID_ARGUMENT; - } else if (olen >= hlen + hlen + 2) { - slen = hlen; - } else { - slen = olen - hlen - 2; - } - } else if ((saltlen < 0) || (saltlen + hlen + 2 > olen)) { - return PSA_ERROR_INVALID_ARGUMENT; - } else { - slen = (size_t) saltlen; - } - - memset(sig, 0, olen); - - /* Note: EMSA-PSS encoding is over the length of N - 1 bits */ - msb = dst_len * 8 - 1; - p += olen - hlen - slen - 2; - *p++ = 0x01; - - - /* Generate salt of length slen in place in the encoded message */ - salt = p; - if ((ret = f_rng(p_rng, salt, slen)) != 0) { - return PSA_ERROR_INVALID_ARGUMENT; - } - p += slen; - - /* Generate H = Hash( M' ) */ - ret = esp_ds_hash_mprime(hash, hashlen, salt, slen, p, md_alg); - if (ret != 0) { - return ret; - } - - /* Compensate for boundary condition when applying mask */ - if (msb % 8 == 0) { - offset = 1; - } - - /* maskedDB: Apply dbMask to DB */ - ret = esp_ds_mgf_mask(sig + offset, olen - hlen - 1 - offset, p, hlen, md_alg); - if (ret != 0) { - return ret; - } - - msb = dst_len * 8 - 1; - sig[0] &= 0xFF >> (olen * 8 - msb); - - p += hlen; - *p++ = 0xBC; - return ret; -} - -static int rsa_rsassa_pkcs1_v21_encode(int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - size_t dst_len, - unsigned char *dst ) -{ - return rsa_rsassa_pss_pkcs1_v21_encode(f_rng, p_rng, md_alg, hashlen, hash, -1, dst, dst_len); -} -#endif /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */ - -int esp_ds_rsa_sign( void *ctx, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_md_type_t md_alg, unsigned int hashlen, - const unsigned char *hash, unsigned char *sig ) -{ - mbedtls_pk_context *pk = (mbedtls_pk_context *)ctx; - size_t sig_len = 0; - return esp_ds_rsa_sign_alt(pk, md_alg, hash, hashlen, sig, 0, &sig_len); -} - -int esp_ds_rsa_sign_alt(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, size_t *sig_len) -{ - esp_ds_context_t *esp_ds_ctx = NULL; - esp_err_t ds_r; - int ret = -1; - - /* This check is done to keep the compatibility with the previous versions of the API - * which allows NULL ctx. If ctx is NULL, then the default padding - * MBEDTLS_RSA_PKCS_V15 is used. - */ - int padding = MBEDTLS_PK_RSA_PKCS_V15; - void *ctx = NULL; - if (pk != NULL) { - ctx = pk->MBEDTLS_PRIVATE(pk_ctx); - } - if (ctx != NULL) { - mbedtls_rsa_context *rsa_ctx = (mbedtls_rsa_context *)ctx; - padding = rsa_ctx->MBEDTLS_PRIVATE(padding); - } - esp_ds_data_t *s_ds_data = esp_ds_get_data_ctx(); - if (s_ds_data == NULL) { - ESP_LOGE(TAG, "Digital signature data context is NULL"); - return -1; - } - const size_t data_len = s_ds_data->rsa_length + 1; - const size_t _sig_len = data_len * FACTOR_KEYLEN_IN_BYTES; - - if (padding == MBEDTLS_PK_RSA_PKCS_V21) { -#ifdef CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 - if ((ret = (rsa_rsassa_pkcs1_v21_encode(mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE ,md_alg, hash_len, hash, _sig_len, sig ))) != 0) { - ESP_LOGE(TAG, "Error in pkcs1_v21 encoding, returned %d", ret); - return -1; - } -#else /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */ - ESP_LOGE(TAG, "RSA PKCS#1 v2.1 padding is not supported. Please enable CONFIG_MBEDTLS_SSL_PROTO_TLS1_3"); - return -1; -#endif /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */ - } else { - if ((ret = (rsa_rsassa_pkcs1_v15_encode(md_alg, hash_len, hash, _sig_len, sig ))) != 0) { - ESP_LOGE(TAG, "Error in pkcs1_v15 encoding, returned %d", ret); - return -1; - } - } - - uint32_t *signature = heap_caps_malloc_prefer(_sig_len, 2, MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); - if (signature == NULL) { - ESP_LOGE(TAG, "Could not allocate memory for internal DS operations"); - return -1; - } - - for (unsigned int i = 0; i < (data_len); i++) { - signature[i] = SWAP_INT32(((uint32_t *)sig)[(data_len) - (i + 1)]); - } - - hmac_key_id_t s_esp_ds_hmac_key_id = esp_ds_get_hmac_key_id(); - - ds_r = esp_ds_start_sign((const void *)signature, - s_ds_data, - s_esp_ds_hmac_key_id, - &esp_ds_ctx); - if (ds_r != ESP_OK) { - ESP_LOGE(TAG, "Error in esp_ds_start_sign, returned %d ", ds_r); - heap_caps_free(signature); - return -1; - } - - ds_r = esp_ds_finish_sign((void *)signature, esp_ds_ctx); - if (ds_r != ESP_OK) { - if (ds_r == ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST) { - ESP_LOGE(TAG, "Invalid digest in DS data reported by esp_ds_finish_sign"); - } else { - ESP_LOGE(TAG, "Error in esp_ds_finish_sign, returned %d ", ds_r); - } - heap_caps_free(signature); - return -1; - } - - for (unsigned int i = 0; i < (data_len); i++) { - ((uint32_t *)sig)[i] = SWAP_INT32(((uint32_t *)signature)[(data_len) - (i + 1)]); - } - heap_caps_free(signature); - *sig_len = _sig_len; - return 0; -} diff --git a/components/mbedtls/port/include/esp_ds/esp_ds_rsa.h b/components/mbedtls/port/include/esp_ds/esp_ds_rsa.h deleted file mode 100644 index d33875bd62..0000000000 --- a/components/mbedtls/port/include/esp_ds/esp_ds_rsa.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include "esp_ds.h" -#include "mbedtls/md.h" -#include "mbedtls/pk.h" -/** - * @brief ESP-DS data context - * - * @note This structure includes encrypted private key parameters such as ciphertext_c, initialization vector, efuse_key_id, RSA key length, which are obtained when DS peripheral is configured. - */ - -/* Context for encrypted private key data required for DS */ -typedef struct esp_ds_data_ctx { - esp_ds_data_t *esp_ds_data; - uint8_t efuse_key_id; /* efuse block id in which DS_KEY is stored e.g. 0,1*/ - uint16_t rsa_length_bits; /* length of RSA private key in bits e.g. 2048 */ -} esp_ds_data_ctx_t; - -/** - * @brief Initializes internal DS data context - * - * This function allocates and initializes internal ds data context which is used for Digital Signature operation. - * - * @in ds_data ds_data context containing encrypted private key parameters - * @return - * - ESP_OK In case of success - * - ESP_ERR_NO_MEM In case internal context could not be allocated. - * - ESP_ERR_INVALID_ARG in case input parametrers are NULL - * - */ -esp_err_t esp_ds_init_data_ctx(esp_ds_data_ctx_t *ds_data); - -/** - * @brief Deinitializes internal DS data context - * - * This function deinitializes internal ds data context which is used for Digital Signature operation. - * - * @return esp_err_t - * - ESP_OK In case of success - * - ESP_ERR_INVALID_STATE In case internal context is not initialized - */ -esp_err_t esp_ds_deinit_data_ctx(void); - -/** - * - * @brief Release the ds lock acquired for the DS operation (then the DS peripheral can be used for other TLS connection) - * - */ -void esp_ds_release_ds_lock(void); - -/** - * - * @brief Alternate implementation for mbedtls_rsa_rsassa_pkcs1_v15_sign, Internally makes use - * of DS module to perform hardware accelerated RSA sign operation - */ -int esp_ds_rsa_sign( void *ctx, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_md_type_t md_alg, unsigned int hashlen, - const unsigned char *hash, unsigned char *sig ); - -/** - * @brief Alternate implementation for mbedtls_pk_sign, uses DS module for hardware accelerated RSA sign operation - * - * This function is an alternate implementation compatible with mbedtls_pk_sign interface. - * It internally makes use of the DS (Digital Signature) peripheral to perform hardware - * accelerated RSA signature operations. - * - * @param pk Pointer to the mbedtls_pk_context structure containing the public key context - * @param md_alg Message digest algorithm type used for hashing (e.g., MBEDTLS_MD_SHA256) - * @param hash Pointer to the hash value to be signed - * @param hash_len Length of the hash value in bytes - * @param sig Buffer to hold the generated signature - * @param sig_size Maximum size of the signature buffer in bytes - * @param sig_len Pointer to store the actual length of the generated signature in bytes - * - * @return - * - 0 on success - * - MBEDTLS_ERR_PK_BAD_INPUT_DATA if input parameters are invalid - * - MBEDTLS_ERR_PK_ALLOC_FAILED if memory allocation fails - * - Other mbedtls error codes on failure - */ -int esp_ds_rsa_sign_alt(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, size_t *sig_len); -/* - * @brief Get RSA key length in bytes from internal DS context - * - * @return RSA key length in bytes - */ -size_t esp_ds_get_keylen(void *ctx); - -/** - * @brief Get RSA key length in bytes from mbedtls_pk_context - * - * This function retrieves the RSA key length from an mbedtls_pk_context structure. - * It is an alternate implementation compatible with mbedtls PK interface. - * - * @param ctx Pointer to the mbedtls_pk_context structure - * - * @return RSA key length in bytes, or 0 if the context is invalid - */ -size_t esp_ds_get_keylen_alt(mbedtls_pk_context *ctx); - -/* - * @brief Set timeout (equal to TLS session timeout), so that DS module usage can be synchronized in case of multiple TLS connections using DS module, - */ -void esp_ds_set_session_timeout(int timeout); - -/** - * @brief Alternate implementation for mbedtls_rsa_decrypt, Internally makes use - * of DS module to perform hardware accelerated RSA decrypt operation - * - * @param ctx Context for the RSA operation. It should be a pointer to an mbedtls_rsa_context structure. - * The RSA context should have the correct padding type set (either MBEDTLS_RSA_PKCS_V15 or MBEDTLS_RSA_PKCS_V21). - * If ctx is NULL, the default padding type (MBEDTLS_RSA_PKCS_V15) will be used. - * @param olen Pointer to the output length variable, which will be set to the length of the decrypted data. - * @param input The input data to be decrypted. It should be a pointer to an array of unsigned char. - * @param output The buffer to hold the decrypted output. It should be a pointer to an array of unsigned char. - * @param output_max_len The maximum length of the output buffer. It should be greater than or equal to the expected length of the decrypted data. - * @return int - * - 0 on success - * - -1 on failure - */ -int esp_ds_rsa_decrypt(void *ctx, size_t *olen, - const unsigned char *input, unsigned char *output, - size_t output_max_len); - -#ifdef __cplusplus -} -#endif diff --git a/components/mbedtls/port/include/esp_ds/esp_rsa_sign_alt.h b/components/mbedtls/port/include/esp_ds/esp_rsa_sign_alt.h deleted file mode 100644 index 529a2dc3e4..0000000000 --- a/components/mbedtls/port/include/esp_ds/esp_rsa_sign_alt.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#ifndef _ESP_RSA_SIGN_ALT_H_ -#define _ESP_RSA_SIGN_ALT_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "esp_ds.h" -#include "mbedtls/md.h" - -/** - * @brief ESP-DS data context - * - * @note This structure includes encrypted private key parameters such as ciphertext_c, initialization vector, efuse_key_id, RSA key length, which are obtained when DS peripheral is configured. - */ - -/* Context for encrypted private key data required for DS */ -typedef struct esp_ds_data_ctx { - esp_ds_data_t *esp_ds_data; - uint8_t efuse_key_id; /* efuse block id in which DS_KEY is stored e.g. 0,1*/ - uint16_t rsa_length_bits; /* length of RSA private key in bits e.g. 2048 */ -} esp_ds_data_ctx_t; - -/** - * @brief Initializes internal DS data context - * - * This function allocates and initializes internal ds data context which is used for Digital Signature operation. - * - * @in ds_data ds_data context containing encrypted private key parameters - * @return - * - ESP_OK In case of success - * - ESP_ERR_NO_MEM In case internal context could not be allocated. - * - ESP_ERR_INVALID_ARG in case input parametrers are NULL - * - */ -esp_err_t esp_ds_init_data_ctx(esp_ds_data_ctx_t *ds_data); - -/** - * - * @brief Release the ds lock acquired for the DS operation (then the DS peripheral can be used for other TLS connection) - * - */ -void esp_ds_release_ds_lock(void); - -/** - * - * @brief Alternate implementation for mbedtls_rsa_rsassa_pkcs1_v15_sign, Internally makes use - * of DS module to perform hardware accelerated RSA sign operation - */ -int esp_ds_rsa_sign(void *ctx, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_md_type_t md_alg, unsigned int hashlen, - const unsigned char *hash, unsigned char *sig); - -/* - * @brief Get RSA key length in bytes from internal DS context - * - * @return RSA key length in bytes - */ -size_t esp_ds_get_keylen(void *ctx); - -/* - * @brief Set timeout (equal to TLS session timeout), so that DS module usage can be synchronized in case of multiple TLS connections using DS module, - */ -void esp_ds_set_session_timeout(int timeout); -#ifdef __cplusplus -} -#endif - -#endif /* _ESP_RSA_SIGN_ALT_H_ */ diff --git a/components/mbedtls/port/include/rsa_dec_alt.h b/components/mbedtls/port/include/rsa_dec_alt.h deleted file mode 100644 index 6c6f29b0b4..0000000000 --- a/components/mbedtls/port/include/rsa_dec_alt.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#ifdef __cpluscplus -extern "C" { -#endif - -#include "sdkconfig.h" - -#if defined(CONFIG_SOC_DIG_SIGN_SUPPORTED) -#include "esp_ds/esp_ds_rsa.h" -#endif - -#ifdef __cpluscplus -} -#endif diff --git a/components/mbedtls/port/include/rsa_sign_alt.h b/components/mbedtls/port/include/rsa_sign_alt.h deleted file mode 100644 index 23911adb58..0000000000 --- a/components/mbedtls/port/include/rsa_sign_alt.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#ifdef __cpluscplus -extern "C" { -#endif - -#include "sdkconfig.h" - -#if defined(CONFIG_SOC_DIG_SIGN_SUPPORTED) -#include "esp_ds/esp_ds_rsa.h" -#endif - -#ifdef __cpluscplus -} -#endif diff --git a/components/mbedtls/port/psa_driver/esp_ds/include/psa_crypto_driver_esp_ds_utilities.h b/components/mbedtls/port/psa_driver/esp_ds/include/psa_crypto_driver_esp_ds_utilities.h new file mode 100644 index 0000000000..41330cb32e --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_ds/include/psa_crypto_driver_esp_ds_utilities.h @@ -0,0 +1,98 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "psa/crypto.h" + +#define FACTOR_KEYLEN_IN_BYTES 4 +#define SWAP_INT32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | ((x) << 24)) +#define MIN_V15_PADDING_LEN 11 + +/** + * @brief Encodes the hash using PKCS#1 v1.5 padding scheme + * + * @param alg Algorithm identifier + * @param hashlen Length of the hash + * @param hash Pointer to the hash data + * @param dst_len Length of the destination buffer + * @param dst Pointer to the destination buffer + * @return psa_status_t + * PSA_ERROR_INVALID_ARGUMENT if arguments are invalid + * PSA_SUCCESS on success + */ +psa_status_t esp_ds_pad_v15_encode(psa_algorithm_t alg, unsigned int hashlen, + const unsigned char *hash, + size_t dst_len, + unsigned char *dst); + +/** + * @brief Unpads the input data using PKCS#1 v1.5 padding scheme + * + * @param input Pointer to the input data + * @param ilen Length of the input data + * @param output Pointer to the output buffer + * @param output_max_len Maximum length of the output buffer + * @param olen Pointer to the length of the output data + * @return psa_status_t + * PSA_ERROR_INVALID_ARGUMENT if arguments are invalid + * PSA_SUCCESS on success + */ +psa_status_t esp_ds_pad_v15_unpad(unsigned char *input, + size_t ilen, + unsigned char *output, + size_t output_max_len, + size_t *olen); + +#if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 + +/** + * @brief Encodes the hash using PKCS#1 v2.2 (PSS) padding scheme + * + * @param hash_alg Hash algorithm identifier + * @param hashlen Length of the hash + * @param hash Pointer to the hash data + * @param saltlen Length of the salt + * @param sig Pointer to the signature buffer + * @param dst_len Length of the destination buffer + * @return psa_status_t + * PSA_ERROR_INVALID_ARGUMENT if arguments are invalid + * PSA_SUCCESS on success + */ +psa_status_t esp_ds_pad_v21_encode(psa_algorithm_t hash_alg, + unsigned int hashlen, + const unsigned char *hash, + int saltlen, + unsigned char *sig, + size_t dst_len); + +/** + * @brief Unpads the input data using PKCS#1 v2.2 (OAEP) padding scheme + * + * @param input Pointer to the input data + * @param ilen Length of the input data + * @param output Pointer to the output buffer + * @param output_max_len Maximum length of the output buffer + * @param olen Pointer to the length of the output data + * @param hash_alg Hash algorithm identifier + * @return psa_status_t + * PSA_ERROR_INVALID_ARGUMENT if arguments are invalid + * PSA_SUCCESS on success + */ +psa_status_t esp_ds_pad_oaep_unpad(unsigned char *input, + size_t ilen, + unsigned char *output, + size_t output_max_len, + size_t *olen, + psa_algorithm_t hash_alg); +#endif /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */ +#ifdef __cplusplus +} +#endif diff --git a/components/mbedtls/port/psa_driver/esp_ds/psa_crypto_driver_esp_ds.c b/components/mbedtls/port/psa_driver/esp_ds/psa_crypto_driver_esp_ds.c new file mode 100644 index 0000000000..0572326abd --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_ds/psa_crypto_driver_esp_ds.c @@ -0,0 +1,474 @@ +/* + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" + +#include "psa_crypto_driver_esp_ds.h" +#include "psa_crypto_driver_esp_ds_contexts.h" +#include "include/psa_crypto_driver_esp_ds_utilities.h" + +#include "esp_log.h" +#include "esp_efuse.h" + +static const char *TAG = "PSA_DS_DRIVER"; + +static SemaphoreHandle_t s_ds_lock = NULL; +static int s_timeout_ms = 0; + +void esp_ds_release_ds_lock(void); + +static int esp_ds_pad(esp_ds_padding_t padding, psa_algorithm_t hash_alg, unsigned int hashlen, + const unsigned char *hash, + int saltlen, + unsigned char *sig, size_t dst_len) +{ + if (padding == ESP_DS_PADDING_PKCS_V15) { + (void)saltlen; + return esp_ds_pad_v15_encode(hash_alg, hashlen, hash, dst_len, sig); + } +#if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 + else if (padding == ESP_DS_PADDING_PSS) { + return esp_ds_pad_v21_encode(hash_alg, hashlen, hash, saltlen, sig, dst_len); + } +#endif /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */ + else { + ESP_LOGE(TAG, "Unsupported padding scheme"); + return PSA_ERROR_NOT_SUPPORTED; + } +} + +/* Lock for the DS session, other TLS connections trying to use the DS peripheral will be blocked + * till this DS session is completed (i.e. TLS handshake for this connection is completed) */ +static void __attribute__((constructor)) esp_ds_conn_lock(void) +{ + if ((s_ds_lock = xSemaphoreCreateMutex()) == NULL) { + ESP_EARLY_LOGE(TAG, "mutex for the DS session lock could not be created"); + } +} + +void esp_ds_release_ds_lock(void) +{ + if (s_ds_lock == NULL) { + ESP_LOGE(TAG, "s_ds_lock is NULL, cannot release lock"); + return; + } + if (xSemaphoreGetMutexHolder(s_ds_lock) == xTaskGetCurrentTaskHandle()) { + /* Give back the semaphore (DS lock) */ + xSemaphoreGive(s_ds_lock); + } +} + +static int esp_ds_validate_opaque_key(const esp_ds_data_ctx_t *opaque_key) +{ + if (opaque_key == NULL) { + ESP_LOGE(TAG, "Opaque key is NULL"); + return PSA_ERROR_INVALID_ARGUMENT; + } + if (opaque_key->esp_ds_data == NULL) { + ESP_LOGE(TAG, "esp_ds_data pointer in opaque key is NULL"); + return PSA_ERROR_INVALID_ARGUMENT; + } + + if (EFUSE_BLK_KEY0 + opaque_key->efuse_key_id >= EFUSE_BLK_KEY_MAX) { + ESP_LOGE(TAG, "Invalid efuse_key_id in opaque key"); + return PSA_ERROR_INVALID_ARGUMENT; + } + + if (opaque_key->rsa_length_bits % 32 != 0) { + ESP_LOGE(TAG, "RSA key length must be a multiple of 32 bits"); + return PSA_ERROR_INVALID_ARGUMENT; + } + + if (opaque_key->rsa_length_bits < 1024 || opaque_key->rsa_length_bits > 4096) { + ESP_LOGE(TAG, "RSA key length must be between 1024 and 4096 bits"); + return PSA_ERROR_INVALID_ARGUMENT; + } + + esp_efuse_purpose_t purpose = esp_efuse_get_key_purpose(EFUSE_BLK_KEY0 + opaque_key->efuse_key_id); + if (purpose != ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE) { + ESP_LOGE(TAG, "Efuse key id purpose is not HMAC_DOWN_DIGITAL_SIGNATURE"); + return PSA_ERROR_NOT_PERMITTED; + } + return PSA_SUCCESS; +} + +psa_status_t esp_ds_opaque_sign_hash_start( + esp_ds_opaque_sign_hash_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *hash, + size_t hash_length) +{ + if (!attributes || !key_buffer || !hash) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + if (key_buffer_size < sizeof(esp_ds_data_ctx_t)) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + if (!PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) && !PSA_ALG_IS_RSA_PSS(alg)) { + return PSA_ERROR_NOT_SUPPORTED; + } + + operation->alg = alg; + + const esp_ds_data_ctx_t *opaque_key = (const esp_ds_data_ctx_t *)key_buffer; + operation->esp_ds_opaque_key = opaque_key; + + if (esp_ds_validate_opaque_key(opaque_key) != PSA_SUCCESS) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + if ((xSemaphoreTake(s_ds_lock, s_timeout_ms / portTICK_PERIOD_MS) != pdTRUE)) { + ESP_LOGE(TAG, "ds_lock could not be obtained in specified time"); + return PSA_ERROR_GENERIC_ERROR; + } + + int padding = ESP_DS_PADDING_PKCS_V15; + if (PSA_ALG_IS_RSA_PSS(operation->alg)) { + padding = ESP_DS_PADDING_PSS; + } + + psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(operation->alg); + + const size_t words_len = (opaque_key->rsa_length_bits / 32); + const size_t rsa_len_bytes = words_len * 4; + operation->sig_buffer_size = rsa_len_bytes; + + unsigned char *em = heap_caps_malloc_prefer(rsa_len_bytes, 1, MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + if (em == NULL) { + ESP_LOGE(TAG, "Could not allocate memory for internal DS operations"); + esp_ds_release_ds_lock(); + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + + psa_status_t status = esp_ds_pad( + padding, hash_alg, hash_length, hash, -1, em, rsa_len_bytes); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Error in esp_ds_pad, returned %d ", status); + heap_caps_free(em); + esp_ds_release_ds_lock(); + return status; + } + + operation->sig_buffer = heap_caps_malloc_prefer(rsa_len_bytes, 2, MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + if (operation->sig_buffer == NULL) { + ESP_LOGE(TAG, "Could not allocate memory for internal DS operations"); + heap_caps_free(em); + esp_ds_release_ds_lock(); + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + + { + uint32_t *sig_words = (uint32_t *)operation->sig_buffer; + const uint32_t *em_words = (const uint32_t *)em; + for (unsigned int i = 0; i < words_len; i++) { + sig_words[i] = SWAP_INT32(em_words[words_len - (i + 1)]); + } + } + + heap_caps_free(em); + + memcpy(&operation->esp_ds_data, opaque_key->esp_ds_data, sizeof(esp_ds_data_t)); + operation->esp_ds_data.rsa_length = (opaque_key->rsa_length_bits / 32) - 1; + + esp_err_t err = esp_ds_start_sign((const void *)operation->sig_buffer, + &operation->esp_ds_data, + (hmac_key_id_t) opaque_key->efuse_key_id, + &operation->esp_ds_ctx); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Error in esp_ds_start_sign, returned %X ", err); + heap_caps_free(operation->sig_buffer); + esp_ds_release_ds_lock(); + return PSA_ERROR_GENERIC_ERROR; + } + + return PSA_SUCCESS; +} + +psa_status_t esp_ds_opaque_sign_hash_complete( + esp_ds_opaque_sign_hash_operation_t *operation, + uint8_t *signature, size_t signature_size, + size_t *signature_length) +{ + if (!signature || !signature_length || !operation) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + int expected_signature_size = operation->esp_ds_opaque_key->rsa_length_bits / 8; + if (signature_size < expected_signature_size) { + return PSA_ERROR_BUFFER_TOO_SMALL; + } + + esp_err_t err = esp_ds_finish_sign((void *)operation->sig_buffer, operation->esp_ds_ctx); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Error in esp_ds_finish_sign, returned %X ", err); + memset(operation->sig_buffer, 0, operation->sig_buffer_size); + heap_caps_free(operation->sig_buffer); + esp_ds_release_ds_lock(); + return PSA_ERROR_GENERIC_ERROR; + } + + unsigned int words_len = expected_signature_size / 4; + uint32_t *out_words = (uint32_t *)signature; + const uint32_t *ds_words = (const uint32_t *)operation->sig_buffer; + for (unsigned int i = 0; i < words_len; i++) { + out_words[i] = SWAP_INT32(ds_words[words_len - (i + 1)]); + } + + *signature_length = expected_signature_size; + memset(operation->sig_buffer, 0, operation->sig_buffer_size); + heap_caps_free(operation->sig_buffer); + esp_ds_release_ds_lock(); + return PSA_SUCCESS; +} + +psa_status_t esp_ds_opaque_sign_hash_abort( + esp_ds_opaque_sign_hash_operation_t *operation) +{ + if (!operation) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + // Free allocated memory if exists + if (operation->sig_buffer) { + heap_caps_free(operation->sig_buffer); + operation->sig_buffer = NULL; + } + + // Release the DS lock if held + esp_ds_release_ds_lock(); + + // Clear the operation structure + memset(operation, 0, sizeof(esp_ds_opaque_sign_hash_operation_t)); + + return PSA_SUCCESS; +} + +psa_status_t esp_ds_opaque_signature_sign_hash( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *hash, + size_t hash_length, + uint8_t *signature, + size_t signature_size, + size_t *signature_length +) +{ + esp_ds_opaque_sign_hash_operation_t operation = {0}; + psa_status_t status = esp_ds_opaque_sign_hash_start( + &operation, + attributes, + key_buffer, + key_buffer_size, + alg, + hash, + hash_length + ); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Error in esp_ds_opaque_sign_hash_start, returned %d ", status); + esp_ds_opaque_sign_hash_abort(&operation); + return status; + } + + status = esp_ds_opaque_sign_hash_complete( + &operation, + signature, + signature_size, + signature_length + ); + if (status != PSA_SUCCESS) { + esp_ds_opaque_sign_hash_abort(&operation); + return status; + } + return PSA_SUCCESS; +} + +psa_status_t esp_ds_opaque_import_key( + const psa_key_attributes_t *attributes, + const uint8_t *data, + size_t data_length, + uint8_t *key_buffer, + size_t key_buffer_size, + size_t *key_buffer_length, + size_t *bits) +{ + if (!attributes || !data || data_length < 1 || !key_buffer || !key_buffer_length || !bits) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + if (key_buffer_size < sizeof(esp_ds_data_ctx_t)) { + return PSA_ERROR_BUFFER_TOO_SMALL; + } + + const esp_ds_data_ctx_t *opaque_key = (const esp_ds_data_ctx_t *)data; + int ret = esp_ds_validate_opaque_key(opaque_key); + if (ret != PSA_SUCCESS) { + return ret; + } + memcpy(key_buffer, opaque_key, sizeof(esp_ds_data_ctx_t)); + *key_buffer_length = sizeof(esp_ds_data_ctx_t); + *bits = opaque_key->rsa_length_bits; + return PSA_SUCCESS; +} + +size_t esp_ds_opaque_size_function( + psa_key_type_t key_type, + size_t key_bits) +{ + (void)key_type; + (void)key_bits; + + // Opaque keys always use the same size structure + return sizeof(esp_ds_data_ctx_t); +} + +void esp_ds_opaque_set_session_timeout(int timeout_ms) +{ + if (timeout_ms > s_timeout_ms) { + s_timeout_ms = timeout_ms; + } +} + +psa_status_t esp_ds_opaque_asymmetric_decrypt( + const psa_key_attributes_t *attributes, const uint8_t *key, + size_t key_length, psa_algorithm_t alg, const uint8_t *input, + size_t input_length, const uint8_t *salt, size_t salt_length, + uint8_t *output, size_t output_size, size_t *output_length) +{ + (void)salt; + (void)salt_length; + if (!attributes || !key || key_length < sizeof(esp_ds_data_ctx_t) || + !input || input_length < 1 || !output || !output_length) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + if (!PSA_ALG_IS_RSA_OAEP(alg) && alg != PSA_ALG_RSA_PKCS1V15_CRYPT) { + return PSA_ERROR_NOT_SUPPORTED; + } + + const esp_ds_data_ctx_t *opaque_key = (const esp_ds_data_ctx_t *)key; + + if (esp_ds_validate_opaque_key(opaque_key) != PSA_SUCCESS) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + size_t key_bits = opaque_key->rsa_length_bits; + if (input_length != (key_bits / 8)) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + esp_ds_padding_t padding = ESP_DS_PADDING_PKCS_V15; + if (PSA_ALG_IS_RSA_OAEP(alg)) { + padding = ESP_DS_PADDING_OAEP; + } else if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) { + padding = ESP_DS_PADDING_PKCS_V15; + } else { + ESP_LOGE(TAG, "Unsupported algorithm for decryption"); + return PSA_ERROR_NOT_SUPPORTED; + } + + if (xSemaphoreTake(s_ds_lock, s_timeout_ms / portTICK_PERIOD_MS) != pdTRUE) { + ESP_LOGE(TAG, "ds_lock could not be obtained in specified time"); + return PSA_ERROR_GENERIC_ERROR; + } + + size_t ilen = key_bits / 8; + size_t data_len = ilen / 4; + uint32_t *em_words = heap_caps_malloc_prefer(sizeof(uint32_t) * data_len, 1, MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + if (em_words == NULL) { + ESP_LOGE(TAG, "Could not allocate memory for internal DS operations"); + esp_ds_release_ds_lock(); + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + + for (unsigned int i = 0; i < (data_len); i++) { + em_words[i] = SWAP_INT32(((uint32_t *)input)[(data_len) - (i + 1)]); + } + + esp_ds_opaque_sign_hash_operation_t operation = {0}; + operation.alg = alg; + operation.esp_ds_opaque_key = opaque_key; + operation.sig_buffer = em_words; + + esp_err_t err = esp_ds_start_sign((const void *)em_words, + opaque_key->esp_ds_data, + (hmac_key_id_t) opaque_key->efuse_key_id, + &operation.esp_ds_ctx); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Error in esp_ds_start_sign for decryption, returned %X ", err); + heap_caps_free(em_words); + esp_ds_release_ds_lock(); + return PSA_ERROR_GENERIC_ERROR; + } + + err = esp_ds_finish_sign((void *)em_words, operation.esp_ds_ctx); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Error in esp_ds_finish_sign for decryption, returned %X ", err); + heap_caps_free(em_words); + esp_ds_release_ds_lock(); + return PSA_ERROR_GENERIC_ERROR; + } + + esp_ds_release_ds_lock(); + + // Remove padding + uint32_t *out_tmp = heap_caps_malloc_prefer(sizeof(uint32_t) * data_len, 1, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + if (out_tmp == NULL) { + ESP_LOGE(TAG, "Could not allocate memory for internal DS operations"); + heap_caps_free(em_words); + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + + for (unsigned int i = 0; i < (data_len); i++) { + ((uint32_t *)out_tmp)[i] = SWAP_INT32(em_words[(data_len) - (i + 1)]); + } + + size_t unpadded_len = 0; + psa_status_t ret = 0; + if (padding == ESP_DS_PADDING_PKCS_V15) { + ret = esp_ds_pad_v15_unpad((unsigned char *)out_tmp, ilen, (unsigned char *)out_tmp, ilen, &unpadded_len); + } +#if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 + else if (padding == ESP_DS_PADDING_OAEP) { + ret = esp_ds_pad_oaep_unpad((unsigned char *)out_tmp, ilen, (unsigned char *)out_tmp, ilen, &unpadded_len, PSA_ALG_RSA_OAEP_GET_HASH(alg)); + } +#endif /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */ + else { + ESP_LOGE(TAG, "Unsupported padding scheme for decryption"); + heap_caps_free(em_words); + heap_caps_free(out_tmp); + return PSA_ERROR_NOT_SUPPORTED; + } + + if (ret != PSA_SUCCESS) { + ESP_LOGE(TAG, "Error in unpadding, returned %d", ret); + heap_caps_free(em_words); + heap_caps_free(out_tmp); + return PSA_ERROR_INVALID_PADDING; + } + + if (output_size < unpadded_len) { + ESP_LOGE(TAG, "Output buffer too small for decrypted data, required size: %zu", unpadded_len); + heap_caps_free(em_words); + heap_caps_free(out_tmp); + return PSA_ERROR_BUFFER_TOO_SMALL; + } + + memcpy(output, out_tmp, unpadded_len); + *output_length = unpadded_len; + heap_caps_free(em_words); + heap_caps_free(out_tmp); + return PSA_SUCCESS; +} diff --git a/components/mbedtls/port/psa_driver/esp_ds/psa_crypto_driver_esp_ds_utilities.c b/components/mbedtls/port/psa_driver/esp_ds/psa_crypto_driver_esp_ds_utilities.c new file mode 100644 index 0000000000..bf1a7390b4 --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_ds/psa_crypto_driver_esp_ds_utilities.c @@ -0,0 +1,497 @@ +/* + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "include/psa_crypto_driver_esp_ds_utilities.h" +#include "mbedtls/asn1.h" +#include "mbedtls/psa_util.h" +#include "esp_log.h" + +typedef struct { + psa_algorithm_t md_alg; + const char *oid; + size_t oid_len; +} oid_md_mapping_t; + +static const oid_md_mapping_t oid_md_table[] = { +#if defined(PSA_WANT_ALG_MD5) + { PSA_ALG_MD5, "\x2a\x86\x48\x86\xf7\x0d\x02\x05", 8 }, +#endif +#if defined(PSA_WANT_ALG_SHA_1) + { PSA_ALG_SHA_1, "\x2b\x0e\x03\x02\x1a", 5 }, +#endif +#if defined(PSA_WANT_ALG_SHA_224) + { PSA_ALG_SHA_224, "\x60\x86\x48\x01\x65\x03\x04\x02\x04", 9 }, +#endif +#if defined(PSA_WANT_ALG_SHA_256) + { PSA_ALG_SHA_256, "\x60\x86\x48\x01\x65\x03\x04\x02\x01", 9 }, +#endif +#if defined(PSA_WANT_ALG_SHA_384) + { PSA_ALG_SHA_384, "\x60\x86\x48\x01\x65\x03\x04\x02\x02", 9 }, +#endif +#if defined(PSA_WANT_ALG_SHA_512) + { PSA_ALG_SHA_512, "\x60\x86\x48\x01\x65\x03\x04\x02\x03", 9 }, +#endif +#if defined(PSA_WANT_ALG_RIPEMD160) + { PSA_ALG_RIPEMD160, "\x2b\x24\x03\x02\x01", 5 }, +#endif + { PSA_ALG_NONE, NULL, 0 } +}; + +static int esp_ds_get_oid_by_psa_alg(psa_algorithm_t md_alg, const char **oid, size_t *olen) +{ + for (size_t i = 0; oid_md_table[i].md_alg != PSA_ALG_NONE; i++) { + if (oid_md_table[i].md_alg == md_alg) { + *oid = oid_md_table[i].oid; + *olen = oid_md_table[i].oid_len; + return 0; + } + } + return PSA_ERROR_NOT_SUPPORTED; +} + +psa_status_t esp_ds_pad_v15_encode(psa_algorithm_t alg, unsigned int hashlen, + const unsigned char *hash, + size_t dst_len, + unsigned char *dst) +{ + size_t oid_size = 0; + size_t nb_pad = dst_len; + unsigned char *p = dst; + const char *oid = NULL; + + /* Are we signing hashed or raw data? */ + if (alg != PSA_ALG_NONE) { + if (esp_ds_get_oid_by_psa_alg(alg, &oid, &oid_size) != PSA_SUCCESS) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + hashlen = PSA_HASH_LENGTH(alg); + + /* Double-check that 8 + hashlen + oid_size can be used as a + * 1-byte ASN.1 length encoding and that there's no overflow. */ + if ( 8 + hashlen + oid_size >= 0x80 || + 10 + hashlen < hashlen || + 10 + hashlen + oid_size < 10 + hashlen ) { + return ( PSA_ERROR_INVALID_ARGUMENT ); + } + + /* + * Static bounds check: + * - Need 10 bytes for five tag-length pairs. + * (Insist on 1-byte length encodings to protect against variants of + * Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification) + * - Need hashlen bytes for hash + * - Need oid_size bytes for hash alg OID. + */ + if ( nb_pad < 10 + hashlen + oid_size ) { + return ( PSA_ERROR_INVALID_ARGUMENT ); + } + nb_pad -= 10 + hashlen + oid_size; + } else { + if ( nb_pad < hashlen ) { + return ( PSA_ERROR_INVALID_ARGUMENT ); + } + + nb_pad -= hashlen; + } + + /* Need space for signature header and padding delimiter (3 bytes), + * and 8 bytes for the minimal padding */ + if ( nb_pad < 3 + 8 ) { + return ( PSA_ERROR_INVALID_ARGUMENT ); + } + nb_pad -= 3; + + /* Now nb_pad is the amount of memory to be filled + * with padding, and at least 8 bytes long. */ + + /* Write signature header and padding */ + *p++ = 0; + *p++ = 1; //MBEDTLS_RSA_SIGN; + memset( p, 0xFF, nb_pad ); + p += nb_pad; + *p++ = 0; + + /* Are we signing raw data? */ + if ( alg == PSA_ALG_NONE ) { + memcpy( p, hash, hashlen ); + return ( PSA_SUCCESS ); + } + + /* Signing hashed data, add corresponding ASN.1 structure + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm DigestAlgorithmIdentifier, + * digest Digest } + * DigestAlgorithmIdentifier ::= AlgorithmIdentifier + * Digest ::= OCTET STRING + * + * Schematic: + * TAG-SEQ + LEN [ TAG-SEQ + LEN [ TAG-OID + LEN [ OID ] + * TAG-NULL + LEN [ NULL ] ] + * TAG-OCTET + LEN [ HASH ] ] + */ + + *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; + *p++ = (unsigned char)( 0x08 + oid_size + hashlen ); + *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; + *p++ = (unsigned char)( 0x04 + oid_size ); + *p++ = MBEDTLS_ASN1_OID; + *p++ = (unsigned char) oid_size; + memcpy( p, oid, oid_size ); + p += oid_size; + *p++ = MBEDTLS_ASN1_NULL; + *p++ = 0x00; + *p++ = MBEDTLS_ASN1_OCTET_STRING; + *p++ = (unsigned char) hashlen; + memcpy( p, hash, hashlen ); + p += hashlen; + + /* Just a sanity-check, should be automatic + * after the initial bounds check. */ + if ( p != dst + dst_len ) { + mbedtls_platform_zeroize( dst, dst_len ); + return ( PSA_ERROR_INVALID_ARGUMENT ); + } + + return PSA_SUCCESS; +} + +psa_status_t esp_ds_pad_v15_unpad(unsigned char *input, + size_t ilen, + unsigned char *output, + size_t output_max_len, + size_t *olen) +{ + if (ilen < MIN_V15_PADDING_LEN) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + unsigned char bad = 0; + size_t msg_len = 0; + size_t msg_max_len = 0; + unsigned char pad_done = 0; + size_t pad_count = 0; + + msg_max_len = (output_max_len > ilen - MIN_V15_PADDING_LEN) ? ilen - MIN_V15_PADDING_LEN : output_max_len; + + /* Check the first byte (0x00) */ + bad |= input[0]; + + /* Check the padding type */ + bad |= input[1] ^ 2; // MBEDTLS_RSA_CRYPT; + + /* Scan for separator (0x00) and count padding bytes in constant time */ + for (size_t i = 2; i < ilen; i++) { + unsigned char found = (input[i] == 0x00); + pad_done = pad_done | found; + pad_count += (pad_done == 0) ? 1 : 0; + } + + /* Check if we found a separator and padding is long enough */ + bad |= (pad_done == 0); /* No separator found */ + bad |= (pad_count < 8); /* Padding too short (need at least 8 non-zero bytes) */ + + /* Calculate message length */ + msg_len = ilen - pad_count - 3; + + /* Check if separator is not at the very end */ + bad |= (msg_len > output_max_len); + if (bad) { + msg_len = msg_max_len; + } + + /* Verify padding bytes are non-zero in constant time */ +#if defined(__clang__) && defined(__xtensa__) + #pragma clang loop vectorize(disable) +#endif + for (size_t i = 2; i < ilen; i++) { + unsigned char in_padding = (i < pad_count + 2); + unsigned char is_zero = (input[i] == 0x00); + bad |= in_padding & is_zero; + } + + if (bad) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + *olen = msg_len; + if (*olen > 0) { + memcpy(output, input + ilen - msg_len, msg_len); + } + return PSA_SUCCESS; +} + +#if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 +static psa_status_t esp_ds_mgf_mask(unsigned char *dst, size_t dlen, unsigned char *src, + size_t slen, psa_algorithm_t hash_alg) +{ + unsigned char counter[4]; + unsigned char *p; + unsigned int hlen; + size_t i, use_len; + unsigned char mask[PSA_HASH_MAX_SIZE]; + psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT; + psa_status_t status; + + hlen = PSA_HASH_LENGTH(hash_alg); + + memset(mask, 0, sizeof(mask)); + memset(counter, 0, 4); + + /* Generate and apply dbMask */ + p = dst; + + while (dlen > 0) { + use_len = hlen; + if (dlen < hlen) { + use_len = dlen; + } + + status = psa_hash_setup(&hash_op, hash_alg); + if (status != PSA_SUCCESS) { + goto exit; + } + status = psa_hash_update(&hash_op, src, slen); + if (status != PSA_SUCCESS) { + goto exit; + } + status = psa_hash_update(&hash_op, counter, 4); + if (status != PSA_SUCCESS) { + goto exit; + } + size_t out_len = 0; + status = psa_hash_finish(&hash_op, mask, PSA_HASH_LENGTH(hash_alg), &out_len); + if (status != PSA_SUCCESS) { + goto exit; + } + + for (i = 0; i < use_len; ++i) { + *p++ ^= mask[i]; + } + + counter[3]++; + + dlen -= use_len; + } + +exit: + psa_hash_abort(&hash_op); + mbedtls_platform_zeroize(mask, sizeof(mask)); + + return status; +} + +static psa_status_t esp_ds_hash_mprime(const unsigned char *hash, size_t hlen, + const unsigned char *salt, size_t slen, + unsigned char *out, psa_algorithm_t hash_alg) +{ + const unsigned char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + + psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT; + psa_status_t status = psa_hash_setup(&hash_op, hash_alg); + if (status != PSA_SUCCESS) { + goto exit; + } + status = psa_hash_update(&hash_op, zeros, sizeof(zeros)); + if (status != PSA_SUCCESS) { + goto exit; + } + status = psa_hash_update(&hash_op, hash, hlen); + if (status != PSA_SUCCESS) { + goto exit; + } + status = psa_hash_update(&hash_op, salt, slen); + if (status != PSA_SUCCESS) { + goto exit; + } + size_t out_len = 0; + status = psa_hash_finish(&hash_op, out, PSA_HASH_LENGTH(hash_alg), &out_len); + if (status != PSA_SUCCESS) { + goto exit; + } +exit: + psa_hash_abort(&hash_op); + return status; +} + +psa_status_t esp_ds_pad_v21_encode(psa_algorithm_t hash_alg, + unsigned int hashlen, + const unsigned char *hash, + int saltlen, + unsigned char *sig, + size_t dst_len) +{ + size_t olen; + unsigned char *p = sig; + unsigned char *salt = NULL; + size_t slen, min_slen, hlen, offset = 0; + psa_status_t ret = PSA_ERROR_INVALID_ARGUMENT; + size_t msb; + + if ((hash_alg != PSA_ALG_NONE || hashlen != 0) && hash == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + olen = dst_len; + + if (hash_alg != PSA_ALG_NONE) { + /* Gather length of hash to sign */ + size_t exp_hashlen = PSA_HASH_LENGTH(hash_alg); + if (exp_hashlen != hashlen) { + return PSA_ERROR_INVALID_ARGUMENT; + } + } + + hlen = PSA_HASH_LENGTH(hash_alg); + + if (saltlen == -1) { + /* Calculate the largest possible salt length, up to the hash size. + * Normally this is the hash length, which is the maximum salt length + * according to FIPS 185-4 �5.5 (e) and common practice. If there is not + * enough room, use the maximum salt length that fits. The constraint is + * that the hash length plus the salt length plus 2 bytes must be at most + * the key length. This complies with FIPS 186-4 �5.5 (e) and RFC 8017 + * (PKCS#1 v2.2) �9.1.1 step 3. */ + min_slen = hlen - 2; + if (olen < hlen + min_slen + 2) { + return PSA_ERROR_INVALID_ARGUMENT; + } else if (olen >= hlen + hlen + 2) { + slen = hlen; + } else { + slen = olen - hlen - 2; + } + } else if ((saltlen < 0) || (saltlen + hlen + 2 > olen)) { + return PSA_ERROR_INVALID_ARGUMENT; + } else { + slen = (size_t) saltlen; + } + + memset(sig, 0, olen); + + /* Note: EMSA-PSS encoding is over the length of N - 1 bits */ + msb = dst_len * 8 - 1; + p += olen - hlen - slen - 2; + *p++ = 0x01; + + /* Generate salt of length slen in place in the encoded message */ + salt = p; + if ((ret = mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, salt, slen)) != 0) { + return PSA_ERROR_INSUFFICIENT_ENTROPY; + } + p += slen; + + /* Generate H = Hash( M' ) */ + ret = esp_ds_hash_mprime(hash, hashlen, salt, slen, p, hash_alg); + if (ret != 0) { + return ret; + } + + /* Compensate for boundary condition when applying mask */ + if (msb % 8 == 0) { + offset = 1; + } + + /* maskedDB: Apply dbMask to DB */ + ret = esp_ds_mgf_mask(sig + offset, olen - hlen - 1 - offset, p, hlen, hash_alg); + if (ret != 0) { + return ret; + } + + msb = dst_len * 8 - 1; + sig[0] &= 0xFF >> (olen * 8 - msb); + + p += hlen; + *p++ = 0xBC; + return ret; +} + +psa_status_t esp_ds_pad_oaep_unpad(unsigned char *input, + size_t ilen, + unsigned char *output, + size_t output_max_len, + size_t *olen, + psa_algorithm_t hash_alg) +{ + unsigned int hlen = PSA_HASH_LENGTH(hash_alg); + unsigned char bad = 0; + size_t msg_len = 0; + + /* Validate input length */ + bad |= (ilen < 2 * hlen + 2); + + /* Apply MGF masks */ + bad |= esp_ds_mgf_mask(input + 1, hlen, input + hlen + 1, ilen - hlen - 1, hash_alg) != PSA_SUCCESS; + + bad |= esp_ds_mgf_mask(input + hlen + 1, ilen - hlen - 1, input + 1, hlen, hash_alg) != PSA_SUCCESS; + + /* Check first byte (should be 0x00) */ + bad |= input[0]; + + /* Skip the first byte and maskSeed */ + unsigned char *db = input + 1 + hlen; + size_t db_len = ilen - hlen - 1; + + /* Compute hash, label is NULL and label_len is 0 */ + unsigned char lhash[PSA_HASH_MAX_SIZE]; + memset(lhash, 0, sizeof(lhash)); + size_t lhen = 0; + bad |= psa_hash_compute(hash_alg, NULL, 0, lhash, sizeof(lhash), &lhen) != PSA_SUCCESS; + + bad |= (lhen != hlen); + + /* Verify hash portion of db against lhash */ + for (size_t i = 0; i < hlen && i < db_len; i++) { + bad |= db[i] ^ lhash[i]; + } + + /* Skip past lhash in DB */ + unsigned char *p = db + hlen; + size_t remaining = db_len - hlen; + + /* + * Scan PS || 0x01 || M + */ + unsigned char seen_one = 0; + size_t msg_index = 0; + + for (size_t i = 0; i < remaining; i++) { + unsigned char is_zero = (p[i] == 0); + unsigned char is_one = (p[i] == 1); + + /* Before delimiter, only 0x00 allowed */ + bad |= (seen_one == 0) & !(is_zero | is_one); + + /* Record first 0x01 */ + msg_index |= (seen_one == 0 && is_one) * i; + seen_one |= is_one; + } + + /* Must see exactly one delimiter */ + bad |= (seen_one == 0); + + /* Calculate message length */ + msg_len = remaining - msg_index - 1; + bad |= (msg_len == 0); + + /* Check output buffer size */ + bad |= (output_max_len < msg_len); + + if (bad) { + *olen = 0; + return PSA_ERROR_INVALID_ARGUMENT; + } + + /* Copy message in constant time */ + *olen = msg_len; + if (*olen > 0) { + memcpy(output, p + msg_index + 1, msg_len); + } + + return PSA_SUCCESS; +} +#endif /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */ diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ds.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ds.h new file mode 100644 index 0000000000..7b05181f9c --- /dev/null +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ds.h @@ -0,0 +1,82 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "psa/crypto.h" +#include "psa_crypto_driver_esp_ds_contexts.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(ESP_DS_DRIVER_ENABLED) +#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT +#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ +#endif /* ESP_DS_DRIVER_ENABLED */ + +#define PSA_CRYPTO_ESP_DS_DRIVER_LOCATION ((psa_key_location_t) 0x800002) + + +#define PSA_KEY_LIFETIME_ESP_DS \ + PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( \ + PSA_KEY_PERSISTENCE_VOLATILE, \ + PSA_CRYPTO_ESP_DS_DRIVER_LOCATION) + +#ifdef SOC_DIG_SIGN_SUPPORTED +psa_status_t esp_ds_opaque_sign_hash_start( + esp_ds_opaque_sign_hash_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *hash, + size_t hash_length); + +psa_status_t esp_ds_opaque_sign_hash_complete( + esp_ds_opaque_sign_hash_operation_t *operation, + uint8_t *signature, size_t signature_size, + size_t *signature_length); + +psa_status_t esp_ds_opaque_sign_hash_abort( + esp_ds_opaque_sign_hash_operation_t *operation); + +psa_status_t esp_ds_opaque_signature_sign_hash( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *hash, + size_t hash_length, + uint8_t *signature, + size_t signature_size, + size_t *signature_length +); + +psa_status_t esp_ds_opaque_import_key( + const psa_key_attributes_t *attributes, + const uint8_t *data, + size_t data_length, + uint8_t *key_buffer, + size_t key_buffer_size, + size_t *key_buffer_length, + size_t *bits); + +size_t esp_ds_opaque_size_function( + psa_key_type_t key_type, + size_t key_bits); + +void esp_ds_opaque_set_session_timeout(int timeout_ms); + +psa_status_t esp_ds_opaque_asymmetric_decrypt( + const psa_key_attributes_t *attributes, const uint8_t *key, + size_t key_length, psa_algorithm_t alg, const uint8_t *input, + size_t input_length, const uint8_t *salt, size_t salt_length, + uint8_t *output, size_t output_size, size_t *output_length); +#endif /* SOC_DIG_SIGN_SUPPORTED */ +#ifdef __cplusplus +} +#endif diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ds_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ds_contexts.h new file mode 100644 index 0000000000..99f0eec1c2 --- /dev/null +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ds_contexts.h @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "psa/crypto.h" +#ifdef SOC_DIG_SIGN_SUPPORTED +#include "esp_ds.h" +#endif /* SOC_DIG_SIGN_SUPPORTED */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + ESP_DS_PADDING_PKCS_V15, + ESP_DS_PADDING_PSS, + ESP_DS_PADDING_OAEP, +} esp_ds_padding_t; + +#ifdef SOC_DIG_SIGN_SUPPORTED +typedef struct { + esp_ds_data_t *esp_ds_data; + uint8_t efuse_key_id; /* efuse block id in which DS_KEY is stored e.g. 0,1*/ + uint16_t rsa_length_bits; /* length of RSA private key in bits e.g. 2048 */ +} esp_ds_data_ctx_t; + +typedef struct { + const esp_ds_data_ctx_t *esp_ds_opaque_key; /*!< Pointer to the esp ds opaque key */ + psa_algorithm_t alg; /*!< Algorithm used in the sign operation */ + uint32_t *sig_buffer; /*!< Buffer to hold the signature */ + size_t sig_buffer_size; /*!< Size of the signature buffer */ + esp_ds_context_t *esp_ds_ctx; /*!< Pointer to the esp ds context */ + esp_ds_data_t esp_ds_data; +} esp_ds_opaque_sign_hash_operation_t; +#endif /* SOC_DIG_SIGN_SUPPORTED */ + +#ifdef __cplusplus +} +#endif diff --git a/components/mbedtls/test_apps/main/CMakeLists.txt b/components/mbedtls/test_apps/main/CMakeLists.txt index 09a6322059..ac099767a0 100644 --- a/components/mbedtls/test_apps/main/CMakeLists.txt +++ b/components/mbedtls/test_apps/main/CMakeLists.txt @@ -20,5 +20,7 @@ target_compile_definitions(${mbedtls} INTERFACE "-DMBEDTLS_DEPRECATED_WARNING") target_compile_definitions(mbedtls PUBLIC "-DMBEDTLS_DEPRECATED_WARNING") target_compile_definitions(mbedx509 PUBLIC "-DMBEDTLS_DEPRECATED_WARNING") -# Add linker wrap option to override esp_ds_finish_sign -target_link_options(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=esp_ds_finish_sign,--wrap=esp_ds_start_sign") +target_link_options( + ${COMPONENT_LIB} INTERFACE + "-Wl,--wrap=esp_ds_finish_sign,--wrap=esp_ds_start_sign,--wrap=esp_efuse_get_key_purpose" + ) diff --git a/components/mbedtls/test_apps/main/test_ds_sign_and_decrypt.c b/components/mbedtls/test_apps/main/test_ds_sign_and_decrypt.c index 116515c530..38583f2381 100644 --- a/components/mbedtls/test_apps/main/test_ds_sign_and_decrypt.c +++ b/components/mbedtls/test_apps/main/test_ds_sign_and_decrypt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,117 +9,187 @@ #include "mbedtls/private/rsa.h" #include "esp_random.h" #include "sdkconfig.h" +#include "soc/soc_caps.h" +#include "esp_efuse.h" +#include "hal/hmac_types.h" -#ifdef CONFIG_HEAP_TRACING -#include -#define NUM_RECORDS 100 -static heap_trace_record_t trace_record[NUM_RECORDS]; // This buffer must be in internal RAM +#ifndef ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE +#define ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE 0 #endif #ifdef SOC_DIG_SIGN_SUPPORTED -#include "soc/soc_caps.h" #include "esp_ds.h" -#include "esp_ds/esp_ds_rsa.h" +#include "psa_crypto_driver_esp_ds.h" -static int mbedtls_esp_random(void *ctx, unsigned char *output, size_t len) +esp_ds_data_ctx_t *esp_secure_cert_get_ds_ctx(void) { - if (len == 0 || output == NULL) { - return -1; + // In real implementation, this function retrieves the DS key context from secure storage + // For testing purposes, we will create a mock DS key context + + esp_ds_data_ctx_t *ds_key = calloc(1, sizeof(esp_ds_data_ctx_t)); + if (ds_key == NULL) { + return NULL; } - esp_fill_random(output, len); - return 0; + + // Mock RSA key parameters + ds_key->rsa_length_bits = 2048; + ds_key->efuse_key_id = 0; + ds_key->esp_ds_data = calloc(1, sizeof(esp_ds_data_t)); + // Fill in other necessary fields as per esp_ds_data_ctx_t definition + // For simplicity, we will leave them zeroed out + + return ds_key; } -TEST_CASE("ds sign test pkcs1_v15", "[ds_rsa]") +void esp_secure_cert_free_ds_ctx(esp_ds_data_ctx_t *ds_key) { - mbedtls_rsa_context rsa_ctx; - rsa_ctx.MBEDTLS_PRIVATE(padding) = MBEDTLS_RSA_PKCS_V15; - unsigned char hash[32] = {0}; - mbedtls_esp_random(NULL, hash, sizeof(hash)); // Fill hash with random data - unsigned int hashlen = sizeof(hash); - unsigned char signature[256] = {0}; - mbedtls_pk_context pk; - mbedtls_pk_init(&pk); - pk.MBEDTLS_PRIVATE(pk_ctx) = &rsa_ctx; - - // esp_ds is not initialized, so we expect an error - int err = esp_ds_rsa_sign(&pk, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature); - TEST_ASSERT_EQUAL(-1, err); - - // Initialize the esp_ds context - esp_ds_data_ctx_t ctx; - esp_ds_data_t ds_data; - ds_data.rsa_length = ESP_DS_RSA_2048; // Example length - ctx.esp_ds_data = &ds_data; - ctx.efuse_key_id = 1; // Example efuse key ID - ctx.rsa_length_bits = 2048; // Example RSA length in bits - - err = esp_ds_init_data_ctx(&ctx); - TEST_ASSERT_EQUAL(ESP_OK, err); - - // Now we can call esp_ds_rsa_sign again - err = esp_ds_rsa_sign(&pk, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature); - TEST_ASSERT_EQUAL(0, err); - TEST_ASSERT_NOT_NULL(signature); - - err = esp_ds_deinit_data_ctx(); - TEST_ASSERT_EQUAL(ESP_OK, err); - - // Because we have wrapped around the ds_start_sign and ds_finish_sign functions, - // we are not actually performing the real signing operation. That test is done in the - // crypto test_apps, so here we just check that the surrounding code works as expected. - // In this test, we have used v15 padding, so we expect the signature to be non-null - // and the hash to be part of the signature. - TEST_ASSERT_EQUAL(0, memcmp(hash, signature + (256 - hashlen), hashlen)); - - // Let's also ensure that signature has correct encoding - // Just before the hash start, it should have size of hash - TEST_ASSERT_EQUAL(hashlen, signature[256 - hashlen - 1]); - - // One byte before should be MBEDTLS_ASN1_OCTET_STRING - TEST_ASSERT_EQUAL(0x04, signature[256 - hashlen - 2]); - - // And the first byte should be 0x00, indicating that this is a valid PKCS#1 v1.5 signature - TEST_ASSERT_EQUAL(0x00, signature[0]); + if (ds_key != NULL) { + if (ds_key->esp_ds_data != NULL) { + free(ds_key->esp_ds_data); + } + free(ds_key); + } } +TEST_CASE("ds sign test pkcs1_v15 PSA validation", "[ds_rsa_psa]") +{ + psa_key_id_t keyt_id; + psa_status_t status; + psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256); + + esp_ds_data_ctx_t *ds_key = esp_secure_cert_get_ds_ctx(); + TEST_ASSERT_NOT_NULL(ds_key); + + ds_key->efuse_key_id = EFUSE_BLK_MAX; // Invalid efuse key id to trigger validation failure + + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR); + psa_set_key_bits(&attributes, ds_key->rsa_length_bits); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_DS); + status = psa_import_key(&attributes, + (const uint8_t *)ds_key, + sizeof(*ds_key), + &keyt_id); + TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, status); + + ds_key->efuse_key_id = EFUSE_BLK0 + 0; // Reset to valid efuse key id + ds_key->rsa_length_bits = 1000; // Invalid RSA length to trigger validation failure + status = psa_import_key(&attributes, + (const uint8_t *)ds_key, + sizeof(*ds_key), + &keyt_id); + TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, status); + + ds_key->rsa_length_bits = 2048; // Reset to valid RSA length + esp_ds_data_t *ds_data_backup = ds_key->esp_ds_data; + ds_key->esp_ds_data = NULL; // NULL esp_ds_data to trigger validation failure + status = psa_import_key(&attributes, + (const uint8_t *)ds_key, + sizeof(*ds_key), + &keyt_id); + TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, status); + + ds_key->esp_ds_data = ds_data_backup; // Restore esp_ds_data + + esp_secure_cert_free_ds_ctx(ds_key); +} + +TEST_CASE("ds sign test pkcs1_v15 PSA", "[ds_rsa_psa]") +{ + psa_key_id_t keyt_id; + psa_status_t status; + psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256); + + esp_ds_data_ctx_t *ds_key = esp_secure_cert_get_ds_ctx(); + TEST_ASSERT_NOT_NULL(ds_key); + + printf("DS key efuse_key_id: %d\n", ds_key->efuse_key_id); + + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR); + psa_set_key_bits(&attributes, ds_key->rsa_length_bits); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_DS); + status = psa_import_key(&attributes, + (const uint8_t *)ds_key, + sizeof(*ds_key), + &keyt_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + unsigned char hash[32] = {0}; + size_t hash_length = 0; + uint8_t input[7] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; + status = psa_hash_compute(PSA_ALG_SHA_256, input, 7, hash, sizeof(hash), &hash_length); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + TEST_ASSERT_EQUAL(32, hash_length); + + unsigned char signature[256] = {0}; + size_t signature_length = 0; + status = psa_sign_hash(keyt_id, alg, hash, hash_length, signature, sizeof(signature), &signature_length); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + TEST_ASSERT_EQUAL(256, signature_length); + + status = psa_destroy_key(keyt_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + psa_reset_key_attributes(&attributes); + + // Free the DS context to prevent memory leak + esp_secure_cert_free_ds_ctx(ds_key); +} + +const unsigned char message[] = { + 0x62, 0x1c, 0xaa, 0x4a, 0xae, 0xf8, 0x1f, 0x4b, 0x59, 0x70, 0xee, 0xcb, 0x0c, 0x91, 0x35, 0xc9, + 0x4a, 0xe2, 0x85, 0xf4, 0xfc, 0x21, 0x18, 0x3e, 0xa6, 0xed, 0xa6, 0x71, 0xdb, 0xfe, 0x2b, 0x95, + 0x67, 0x45, 0xb7, +}; +const size_t message_len = 35; + #ifdef CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 -TEST_CASE("ds sign test pkcs1_v21", "[ds_rsa]") +TEST_CASE("ds sign test pkcs1_v21 PSA", "[ds_rsa_psa]") { - mbedtls_rsa_context rsa_ctx; - rsa_ctx.MBEDTLS_PRIVATE(padding) = MBEDTLS_RSA_PKCS_V21; + psa_key_id_t keyt_id; + psa_status_t status; + psa_algorithm_t alg = PSA_ALG_RSA_PSS(PSA_ALG_SHA_256); + esp_ds_data_ctx_t *ds_key = esp_secure_cert_get_ds_ctx(); + TEST_ASSERT_NOT_NULL(ds_key); + + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR); + psa_set_key_bits(&attributes, ds_key->rsa_length_bits); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_DS); + status = psa_import_key(&attributes, + (const uint8_t *)ds_key, + sizeof(*ds_key), + &keyt_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + unsigned char hash[32] = {0}; - mbedtls_esp_random(NULL, hash, sizeof(hash)); // Fill hash with random data - unsigned int hashlen = sizeof(hash); + size_t hash_length = 0; + uint8_t input[7] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; + status = psa_hash_compute(PSA_ALG_SHA_256, input, 7, hash, sizeof(hash), &hash_length); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + TEST_ASSERT_EQUAL(32, hash_length); + unsigned char signature[256] = {0}; - mbedtls_pk_context pk; - mbedtls_pk_init(&pk); - pk.MBEDTLS_PRIVATE(pk_ctx) = &rsa_ctx; + size_t signature_length = 0; + status = psa_sign_hash(keyt_id, alg, hash, hash_length, signature, sizeof(signature), &signature_length); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + TEST_ASSERT_EQUAL(256, signature_length); - // esp_ds is not initialized, so we expect an error - int err = esp_ds_rsa_sign(&pk, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature); - TEST_ASSERT_EQUAL(-1, err); + status = psa_destroy_key(keyt_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); - // Initialize the esp_ds context - esp_ds_data_ctx_t ctx; - esp_ds_data_t ds_data; - ds_data.rsa_length = ESP_DS_RSA_2048; // Example length - ctx.esp_ds_data = &ds_data; - ctx.efuse_key_id = 1; // Example efuse key ID - ctx.rsa_length_bits = 2048; // Example RSA length in bits + psa_reset_key_attributes(&attributes); - err = esp_ds_init_data_ctx(&ctx); - TEST_ASSERT_EQUAL(ESP_OK, err); - - // Now we can call esp_ds_rsa_sign again - err = esp_ds_rsa_sign(&pk, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature); - TEST_ASSERT_EQUAL(0, err); - TEST_ASSERT_NOT_NULL(signature); - - err = esp_ds_deinit_data_ctx(); - TEST_ASSERT_EQUAL(ESP_OK, err); + // Free the DS context to prevent memory leak + esp_secure_cert_free_ds_ctx(ds_key); } -#endif // CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 /* Generated external data for OAEP padding */ const unsigned char oaep_padded_v21[] = { @@ -141,53 +211,48 @@ const unsigned char oaep_padded_v21[] = { 0x3a, 0x1c, 0xf5, 0xe8, 0x9f, 0x17, 0x22, 0x66, 0x3d, 0xc5, 0xab, 0xf6, 0x51, 0xe9, 0x84, 0x73, }; -const unsigned char message[] = { - 0x62, 0x1c, 0xaa, 0x4a, 0xae, 0xf8, 0x1f, 0x4b, 0x59, 0x70, 0xee, 0xcb, 0x0c, 0x91, 0x35, 0xc9, - 0x4a, 0xe2, 0x85, 0xf4, 0xfc, 0x21, 0x18, 0x3e, 0xa6, 0xed, 0xa6, 0x71, 0xdb, 0xfe, 0x2b, 0x95, - 0x67, 0x45, 0xb7, -}; -const size_t message_len = 35; - -TEST_CASE("ds decrypt test pkcs1_v21", "[ds_rsa]") +TEST_CASE("ds decrypt test pkcs1_v21 PSA", "[ds_rsa]") { -#ifdef CONFIG_HEAP_TRACING - heap_trace_init_standalone(trace_record, NUM_RECORDS); - heap_trace_start(HEAP_TRACE_LEAKS); -#endif - mbedtls_rsa_context rsa_ctx; - rsa_ctx.MBEDTLS_PRIVATE(padding) = MBEDTLS_RSA_PKCS_V21; - // Initialize the esp_ds context - esp_ds_data_ctx_t ctx; - esp_ds_data_t ds_data; - ds_data.rsa_length = ESP_DS_RSA_2048; // Example length - ctx.esp_ds_data = &ds_data; - ctx.efuse_key_id = 1; // Example efuse key ID - ctx.rsa_length_bits = 2048; // Example RSA length in bits + psa_key_id_t keyt_id; + psa_status_t status; + psa_algorithm_t alg = PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256); + + esp_ds_data_ctx_t *ds_key = esp_secure_cert_get_ds_ctx(); + TEST_ASSERT_NOT_NULL(ds_key); + + printf("DS Key RSA Length Bits: %d\n", ds_key->rsa_length_bits); + + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR); + psa_set_key_bits(&attributes, ds_key->rsa_length_bits); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_DS); + status = psa_import_key(&attributes, + (const uint8_t *)ds_key, + sizeof(*ds_key), + &keyt_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); unsigned char decrypted[256] = {0}; size_t decrypted_len = 0; - // esp_ds is not initialized, so we expect an error - int err = esp_ds_rsa_decrypt(&rsa_ctx, &decrypted_len, oaep_padded_v21, decrypted, sizeof(decrypted)); - TEST_ASSERT_EQUAL(-1, err); - - err = esp_ds_init_data_ctx(&ctx); - TEST_ASSERT_EQUAL(ESP_OK, err); - - err = esp_ds_rsa_decrypt(&rsa_ctx, &decrypted_len, oaep_padded_v21, decrypted, sizeof(decrypted)); - TEST_ASSERT_EQUAL(0, err); - TEST_ASSERT_NOT_NULL(decrypted); - - err = esp_ds_deinit_data_ctx(); - TEST_ASSERT_EQUAL(ESP_OK, err); - - TEST_ASSERT_EQUAL(decrypted_len, message_len); + status = psa_asymmetric_decrypt(keyt_id, alg, oaep_padded_v21, sizeof(oaep_padded_v21), + NULL, 0, + decrypted, sizeof(decrypted), + &decrypted_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + TEST_ASSERT_EQUAL(message_len, decrypted_len); TEST_ASSERT_EQUAL_MEMORY(decrypted, message, message_len); -#ifdef CONFIG_HEAP_TRACING - heap_trace_stop(); - heap_trace_dump(); -#endif + + status = psa_destroy_key(keyt_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + psa_reset_key_attributes(&attributes); + // Free the DS context to prevent memory leak + esp_secure_cert_free_ds_ctx(ds_key); } +#endif /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */ const unsigned char v15_padded[] = { 0x00, 0x02, 0xdf, 0x36, 0xfc, 0x41, 0x57, 0x40, 0x87, 0x3f, 0x88, 0xa7, 0x7f, 0x7a, 0x33, 0xbe, @@ -208,32 +273,46 @@ const unsigned char v15_padded[] = { 0xf4, 0xfc, 0x21, 0x18, 0x3e, 0xa6, 0xed, 0xa6, 0x71, 0xdb, 0xfe, 0x2b, 0x95, 0x67, 0x45, 0xb7, }; -TEST_CASE("ds decrypt test pkcs1_v15", "[ds_rsa]") +TEST_CASE("ds decrypt test pkcs1_v15 PSA", "[ds_rsa]") { - mbedtls_rsa_context rsa_ctx; - rsa_ctx.MBEDTLS_PRIVATE(padding) = MBEDTLS_RSA_PKCS_V15; - // Initialize the esp_ds context - esp_ds_data_ctx_t ctx; - esp_ds_data_t ds_data; - ds_data.rsa_length = ESP_DS_RSA_2048; // Example length - ctx.esp_ds_data = &ds_data; - ctx.efuse_key_id = 1; // Example efuse key ID - ctx.rsa_length_bits = 2048; // Example RSA length in bits + psa_key_id_t keyt_id; + psa_status_t status; + psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_CRYPT; - int err = esp_ds_init_data_ctx(&ctx); - TEST_ASSERT_EQUAL(ESP_OK, err); + esp_ds_data_ctx_t *ds_key = esp_secure_cert_get_ds_ctx(); + TEST_ASSERT_NOT_NULL(ds_key); + + printf("DS Key RSA Length Bits: %d\n", ds_key->rsa_length_bits); + + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR); + psa_set_key_bits(&attributes, ds_key->rsa_length_bits); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_DS); + status = psa_import_key(&attributes, + (const uint8_t *)ds_key, + sizeof(*ds_key), + &keyt_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); unsigned char decrypted[256] = {0}; size_t decrypted_len = 0; - err = esp_ds_rsa_decrypt(&rsa_ctx, &decrypted_len, v15_padded, decrypted, sizeof(decrypted)); - TEST_ASSERT_EQUAL(0, err); - TEST_ASSERT_NOT_NULL(decrypted); - err = esp_ds_deinit_data_ctx(); - TEST_ASSERT_EQUAL(ESP_OK, err); - - TEST_ASSERT_EQUAL(decrypted_len, message_len); + status = psa_asymmetric_decrypt(keyt_id, alg, v15_padded, sizeof(v15_padded), + NULL, 0, + decrypted, sizeof(decrypted), + &decrypted_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + TEST_ASSERT_EQUAL(message_len, decrypted_len); TEST_ASSERT_EQUAL_MEMORY(decrypted, message, message_len); + + status = psa_destroy_key(keyt_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + psa_reset_key_attributes(&attributes); + // Free the DS context to prevent memory leak + esp_secure_cert_free_ds_ctx(ds_key); } int __wrap_esp_ds_start_sign(const void *message, const esp_ds_data_t *data, hmac_key_id_t key_id, esp_ds_context_t **esp_ds_ctx) @@ -262,4 +341,19 @@ int __wrap_esp_ds_finish_sign(void *sig, esp_ds_context_t *ctx) // Or we can call the real implementation if needed: // return __real_esp_ds_finish_sign(sig, ctx); } + #endif /* SOC_DIG_SIGN_SUPPORTED */ + +// Forward declaration for linker-wrapped function +extern esp_efuse_purpose_t __real_esp_efuse_get_key_purpose(esp_efuse_block_t block); + +esp_efuse_purpose_t __wrap_esp_efuse_get_key_purpose(esp_efuse_block_t block) +{ + if (block == EFUSE_BLK_KEY0 + 0) { + printf("Mocked esp_efuse_get_key_purpose called for block %d\n", block); + return ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE; + } else { + printf("Mocked esp_efuse_get_key_purpose forwarding to real for block %d\n", block); + return __real_esp_efuse_get_key_purpose(block); + } +} diff --git a/components/mbedtls/test_apps/partitions.csv b/components/mbedtls/test_apps/partitions.csv new file mode 100644 index 0000000000..31ab742852 --- /dev/null +++ b/components/mbedtls/test_apps/partitions.csv @@ -0,0 +1,4 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild +esp_secure_cert, 0x3F, , 0xD000, 0x2000, +factory, app, factory, 0x20000, 1M, From e06a7dd79151bbd7d4bd04c7e78be0583410a662 Mon Sep 17 00:00:00 2001 From: Ashish Sharma Date: Mon, 19 Jan 2026 14:57:29 +0800 Subject: [PATCH 2/3] feat: adds new Kconfig variable for DS peripheral --- components/esp-tls/Kconfig | 1 + components/esp-tls/esp_tls_mbedtls.c | 16 +- .../test_apps/crypto/main/ds/test_ds.c | 6 +- components/mbedtls/CMakeLists.txt | 10 +- components/mbedtls/Kconfig | 7 + .../psa_crypto_driver_esp_rsa_ds_utilities.h} | 8 +- .../psa_crypto_driver_esp_rsa_ds.c} | 250 +++++++++--------- .../psa_crypto_driver_esp_rsa_ds_utilities.c} | 26 +- .../include/psa_crypto_driver_esp_ds.h | 82 ------ .../psa_crypto_driver_esp_ds_contexts.h | 42 --- .../include/psa_crypto_driver_esp_rsa_ds.h | 180 +++++++++++++ .../psa_crypto_driver_esp_rsa_ds_contexts.h | 55 ++++ .../psa_crypto_driver_esp_sha_contexts.h | 81 +++--- .../test_apps/main/test_ds_sign_and_decrypt.c | 56 ++-- .../mbedtls/test_apps/sdkconfig.ci.ds_rsa | 1 + docs/doxygen/Doxyfile | 3 + 16 files changed, 486 insertions(+), 338 deletions(-) rename components/mbedtls/port/psa_driver/{esp_ds/include/psa_crypto_driver_esp_ds_utilities.h => esp_rsa_ds/include/psa_crypto_driver_esp_rsa_ds_utilities.h} (91%) rename components/mbedtls/port/psa_driver/{esp_ds/psa_crypto_driver_esp_ds.c => esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c} (59%) rename components/mbedtls/port/psa_driver/{esp_ds/psa_crypto_driver_esp_ds_utilities.c => esp_rsa_ds/psa_crypto_driver_esp_rsa_ds_utilities.c} (92%) delete mode 100644 components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ds.h delete mode 100644 components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ds_contexts.h create mode 100644 components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_rsa_ds.h create mode 100644 components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_rsa_ds_contexts.h diff --git a/components/esp-tls/Kconfig b/components/esp-tls/Kconfig index 427607ca4d..6f70f8440e 100644 --- a/components/esp-tls/Kconfig +++ b/components/esp-tls/Kconfig @@ -27,6 +27,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 + select MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL default y help Enable use of the Digital Signature Peripheral for ESP-TLS.The DS peripheral diff --git a/components/esp-tls/esp_tls_mbedtls.c b/components/esp-tls/esp_tls_mbedtls.c index c020262a7a..38f56153d3 100644 --- a/components/esp-tls/esp_tls_mbedtls.c +++ b/components/esp-tls/esp_tls_mbedtls.c @@ -45,7 +45,7 @@ static esp_err_t esp_set_atecc608a_pki_context(esp_tls_t *tls, const void *pki); #if defined(CONFIG_ESP_TLS_USE_DS_PERIPHERAL) #include #include "psa/crypto.h" -#include "psa_crypto_driver_esp_ds.h" +#include "psa_crypto_driver_esp_rsa_ds.h" static esp_err_t esp_mbedtls_init_pk_ctx_for_ds(const void *pki); #endif /* CONFIG_ESP_TLS_USE_DS_PERIPHERAL */ @@ -118,7 +118,7 @@ typedef struct esp_tls_pki_t { const unsigned char *privkey_password; unsigned int privkey_password_len; #ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL - void *esp_ds_data; + void *esp_rsa_ds_data; #endif } esp_tls_pki_t; @@ -601,10 +601,10 @@ static esp_err_t set_pki_context(esp_tls_t *tls, const esp_tls_pki_t *pki) } #ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL - if (pki->esp_ds_data != NULL) { + if (pki->esp_rsa_ds_data != NULL) { ret = esp_mbedtls_init_pk_ctx_for_ds(pki); if (ret != ESP_OK) { - ESP_LOGE(TAG, "Failed to initialize pk context for esp_ds"); + ESP_LOGE(TAG, "Failed to initialize pk context for esp_rsa_ds"); return ret; } } else @@ -1063,7 +1063,7 @@ esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t ESP_LOGE(TAG, "Client certificate is also required with the DS parameters"); return ESP_ERR_INVALID_STATE; } - esp_ds_opaque_set_session_timeout(cfg->timeout_ms); + esp_rsa_ds_opaque_set_session_timeout(cfg->timeout_ms); /* set private key pointer to NULL since the DS peripheral with its own configuration data is used */ esp_tls_pki_t pki = { .public_cert = &tls->clientcert, @@ -1074,7 +1074,7 @@ esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t .privkey_pem_bytes = 0, .privkey_password = NULL, .privkey_password_len = 0, - .esp_ds_data = cfg->ds_data, + .esp_rsa_ds_data = cfg->ds_data, }; esp_err_t esp_ret = set_pki_context(tls, &pki); @@ -1406,7 +1406,7 @@ static esp_err_t esp_set_atecc608a_pki_context(esp_tls_t *tls, const void *pki) #ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL static esp_err_t esp_mbedtls_init_pk_ctx_for_ds(const void *pki) { - esp_ds_data_ctx_t *ds_data = ((const esp_tls_pki_t*)pki)->esp_ds_data; + esp_ds_data_ctx_t *ds_data = ((const esp_tls_pki_t*)pki)->esp_rsa_ds_data; if (ds_data == NULL) { ESP_LOGE(TAG, "DS data context is NULL"); return ESP_ERR_INVALID_ARG; @@ -1430,7 +1430,7 @@ static esp_err_t esp_mbedtls_init_pk_ctx_for_ds(const void *pki) psa_set_key_bits(&ds_key_attributes, ds_data->rsa_length_bits); psa_set_key_usage_flags(&ds_key_attributes, PSA_KEY_USAGE_SIGN_HASH); psa_set_key_algorithm(&ds_key_attributes, alg); - psa_set_key_lifetime(&ds_key_attributes, PSA_KEY_LIFETIME_ESP_DS); + psa_set_key_lifetime(&ds_key_attributes, PSA_KEY_LIFETIME_ESP_RSA_DS); status = psa_import_key(&ds_key_attributes, (const uint8_t *)ds_data, sizeof(esp_ds_data_ctx_t), diff --git a/components/esp_hal_security/test_apps/crypto/main/ds/test_ds.c b/components/esp_hal_security/test_apps/crypto/main/ds/test_ds.c index ddf5858eb1..b982707cce 100644 --- a/components/esp_hal_security/test_apps/crypto/main/ds/test_ds.c +++ b/components/esp_hal_security/test_apps/crypto/main/ds/test_ds.c @@ -150,9 +150,9 @@ static esp_err_t esp_ds_finish_sign(void *signature, const esp_ds_data_t *data) } static esp_err_t esp_ds_sign(const void *message, - const esp_ds_data_t *data, - uint32_t key_id, - void *signature) + const esp_ds_data_t *data, + uint32_t key_id, + void *signature) { esp_err_t result = esp_ds_start_sign(message, data, key_id); if (result != ESP_OK) { diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index dc54525fa0..367210753e 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -382,18 +382,14 @@ if(CONFIG_SOC_HMAC_SUPPORTED) target_link_libraries(tfpsacrypto PRIVATE idf::efuse) endif() -if(CONFIG_SOC_DIG_SIGN_SUPPORTED) +if(CONFIG_SOC_DIG_SIGN_SUPPORTED AND CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL) target_compile_definitions(tfpsacrypto PRIVATE ESP_DS_DRIVER_ENABLED) target_sources(tfpsacrypto PRIVATE - "${COMPONENT_DIR}/port/psa_driver/esp_ds/psa_crypto_driver_esp_ds.c" - "${COMPONENT_DIR}/port/psa_driver/esp_ds/psa_crypto_driver_esp_ds_utilities.c" + "${COMPONENT_DIR}/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c" + "${COMPONENT_DIR}/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds_utilities.c" ) target_link_libraries(tfpsacrypto PRIVATE idf::efuse) endif() -# # CONFIG_ESP_TLS_USE_DS_PERIPHERAL can be enabled only for the supported targets. -if(CONFIG_ESP_TLS_USE_DS_PERIPHERAL) - # target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/esp_ds/esp_rsa_sign_alt.c") -endif() if(CONFIG_SOC_HMAC_SUPPORTED) target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/esp_hmac_pbkdf2.c") diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index d4be891dbb..be66b17454 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -1543,6 +1543,13 @@ menu "mbedTLS" help This option enables hardware acceleration for ECDSA sign function, only when using ATECC608A cryptoauth chip. + + config MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL + bool "Enable hardware RSA digital signature peripheral acceleration" + default n + depends on SOC_DIG_SIGN_SUPPORTED + help + Enable hardware accelerated digital signature peripheral for RSA digital signature generation. endmenu menu "Entropy and Random Number Generation" diff --git a/components/mbedtls/port/psa_driver/esp_ds/include/psa_crypto_driver_esp_ds_utilities.h b/components/mbedtls/port/psa_driver/esp_rsa_ds/include/psa_crypto_driver_esp_rsa_ds_utilities.h similarity index 91% rename from components/mbedtls/port/psa_driver/esp_ds/include/psa_crypto_driver_esp_ds_utilities.h rename to components/mbedtls/port/psa_driver/esp_rsa_ds/include/psa_crypto_driver_esp_rsa_ds_utilities.h index 41330cb32e..e1462d5a4c 100644 --- a/components/mbedtls/port/psa_driver/esp_ds/include/psa_crypto_driver_esp_ds_utilities.h +++ b/components/mbedtls/port/psa_driver/esp_rsa_ds/include/psa_crypto_driver_esp_rsa_ds_utilities.h @@ -28,7 +28,7 @@ extern "C" { * PSA_ERROR_INVALID_ARGUMENT if arguments are invalid * PSA_SUCCESS on success */ -psa_status_t esp_ds_pad_v15_encode(psa_algorithm_t alg, unsigned int hashlen, +psa_status_t esp_rsa_ds_pad_v15_encode(psa_algorithm_t alg, unsigned int hashlen, const unsigned char *hash, size_t dst_len, unsigned char *dst); @@ -45,7 +45,7 @@ psa_status_t esp_ds_pad_v15_encode(psa_algorithm_t alg, unsigned int hashlen, * PSA_ERROR_INVALID_ARGUMENT if arguments are invalid * PSA_SUCCESS on success */ -psa_status_t esp_ds_pad_v15_unpad(unsigned char *input, +psa_status_t esp_rsa_ds_pad_v15_unpad(unsigned char *input, size_t ilen, unsigned char *output, size_t output_max_len, @@ -66,7 +66,7 @@ psa_status_t esp_ds_pad_v15_unpad(unsigned char *input, * PSA_ERROR_INVALID_ARGUMENT if arguments are invalid * PSA_SUCCESS on success */ -psa_status_t esp_ds_pad_v21_encode(psa_algorithm_t hash_alg, +psa_status_t esp_rsa_ds_pad_v21_encode(psa_algorithm_t hash_alg, unsigned int hashlen, const unsigned char *hash, int saltlen, @@ -86,7 +86,7 @@ psa_status_t esp_ds_pad_v21_encode(psa_algorithm_t hash_alg, * PSA_ERROR_INVALID_ARGUMENT if arguments are invalid * PSA_SUCCESS on success */ -psa_status_t esp_ds_pad_oaep_unpad(unsigned char *input, +psa_status_t esp_rsa_ds_pad_oaep_unpad(unsigned char *input, size_t ilen, unsigned char *output, size_t output_max_len, diff --git a/components/mbedtls/port/psa_driver/esp_ds/psa_crypto_driver_esp_ds.c b/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c similarity index 59% rename from components/mbedtls/port/psa_driver/esp_ds/psa_crypto_driver_esp_ds.c rename to components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c index 0572326abd..099b2c36b0 100644 --- a/components/mbedtls/port/psa_driver/esp_ds/psa_crypto_driver_esp_ds.c +++ b/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c @@ -9,53 +9,54 @@ #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" -#include "psa_crypto_driver_esp_ds.h" -#include "psa_crypto_driver_esp_ds_contexts.h" -#include "include/psa_crypto_driver_esp_ds_utilities.h" +#include "psa_crypto_driver_esp_rsa_ds.h" +#include "psa_crypto_driver_esp_rsa_ds_contexts.h" +#include "include/psa_crypto_driver_esp_rsa_ds_utilities.h" #include "esp_log.h" #include "esp_efuse.h" +#include "soc/soc_caps.h" -static const char *TAG = "PSA_DS_DRIVER"; +#define ESP_RSA_DS_TIMEOUT_BUFFER_MS 1000 + +static const char *TAG = "PSA_RSA_DS"; static SemaphoreHandle_t s_ds_lock = NULL; static int s_timeout_ms = 0; -void esp_ds_release_ds_lock(void); +void esp_rsa_ds_release_ds_lock(void); -static int esp_ds_pad(esp_ds_padding_t padding, psa_algorithm_t hash_alg, unsigned int hashlen, +static int esp_rsa_ds_pad(esp_rsa_ds_padding_t padding, psa_algorithm_t hash_alg, unsigned int hashlen, const unsigned char *hash, int saltlen, unsigned char *sig, size_t dst_len) { - if (padding == ESP_DS_PADDING_PKCS_V15) { + if (padding == ESP_RSA_DS_PADDING_PKCS_V15) { (void)saltlen; - return esp_ds_pad_v15_encode(hash_alg, hashlen, hash, dst_len, sig); + return esp_rsa_ds_pad_v15_encode(hash_alg, hashlen, hash, dst_len, sig); } #if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 - else if (padding == ESP_DS_PADDING_PSS) { - return esp_ds_pad_v21_encode(hash_alg, hashlen, hash, saltlen, sig, dst_len); + else if (padding == ESP_RSA_DS_PADDING_PSS) { + return esp_rsa_ds_pad_v21_encode(hash_alg, hashlen, hash, saltlen, sig, dst_len); } #endif /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */ else { - ESP_LOGE(TAG, "Unsupported padding scheme"); return PSA_ERROR_NOT_SUPPORTED; } } /* Lock for the DS session, other TLS connections trying to use the DS peripheral will be blocked * till this DS session is completed (i.e. TLS handshake for this connection is completed) */ -static void __attribute__((constructor)) esp_ds_conn_lock(void) +static void __attribute__((constructor)) esp_rsa_ds_conn_lock(void) { if ((s_ds_lock = xSemaphoreCreateMutex()) == NULL) { - ESP_EARLY_LOGE(TAG, "mutex for the DS session lock could not be created"); + ESP_EARLY_LOGE(TAG, "Failed to create DS lock"); } } -void esp_ds_release_ds_lock(void) +void esp_rsa_ds_release_ds_lock(void) { if (s_ds_lock == NULL) { - ESP_LOGE(TAG, "s_ds_lock is NULL, cannot release lock"); return; } if (xSemaphoreGetMutexHolder(s_ds_lock) == xTaskGetCurrentTaskHandle()) { @@ -64,42 +65,36 @@ void esp_ds_release_ds_lock(void) } } -static int esp_ds_validate_opaque_key(const esp_ds_data_ctx_t *opaque_key) +static int esp_rsa_ds_validate_opaque_key(const esp_ds_data_ctx_t *opaque_key) { if (opaque_key == NULL) { - ESP_LOGE(TAG, "Opaque key is NULL"); return PSA_ERROR_INVALID_ARGUMENT; } - if (opaque_key->esp_ds_data == NULL) { - ESP_LOGE(TAG, "esp_ds_data pointer in opaque key is NULL"); + if (opaque_key->esp_rsa_ds_data == NULL) { return PSA_ERROR_INVALID_ARGUMENT; } if (EFUSE_BLK_KEY0 + opaque_key->efuse_key_id >= EFUSE_BLK_KEY_MAX) { - ESP_LOGE(TAG, "Invalid efuse_key_id in opaque key"); return PSA_ERROR_INVALID_ARGUMENT; } if (opaque_key->rsa_length_bits % 32 != 0) { - ESP_LOGE(TAG, "RSA key length must be a multiple of 32 bits"); return PSA_ERROR_INVALID_ARGUMENT; } - if (opaque_key->rsa_length_bits < 1024 || opaque_key->rsa_length_bits > 4096) { - ESP_LOGE(TAG, "RSA key length must be between 1024 and 4096 bits"); + if (opaque_key->rsa_length_bits < 1024 || opaque_key->rsa_length_bits > SOC_DS_SIGNATURE_MAX_BIT_LEN) { return PSA_ERROR_INVALID_ARGUMENT; } esp_efuse_purpose_t purpose = esp_efuse_get_key_purpose(EFUSE_BLK_KEY0 + opaque_key->efuse_key_id); if (purpose != ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE) { - ESP_LOGE(TAG, "Efuse key id purpose is not HMAC_DOWN_DIGITAL_SIGNATURE"); return PSA_ERROR_NOT_PERMITTED; } return PSA_SUCCESS; } -psa_status_t esp_ds_opaque_sign_hash_start( - esp_ds_opaque_sign_hash_operation_t *operation, +psa_status_t esp_rsa_ds_opaque_sign_hash_start( + esp_rsa_ds_opaque_sign_hash_operation_t *operation, const psa_key_attributes_t *attributes, const uint8_t *key_buffer, size_t key_buffer_size, @@ -107,7 +102,7 @@ psa_status_t esp_ds_opaque_sign_hash_start( const uint8_t *hash, size_t hash_length) { - if (!attributes || !key_buffer || !hash) { + if (!attributes || !key_buffer || !hash || !operation) { return PSA_ERROR_INVALID_ARGUMENT; } @@ -122,20 +117,21 @@ psa_status_t esp_ds_opaque_sign_hash_start( operation->alg = alg; const esp_ds_data_ctx_t *opaque_key = (const esp_ds_data_ctx_t *)key_buffer; - operation->esp_ds_opaque_key = opaque_key; + operation->esp_rsa_ds_opaque_key = opaque_key; - if (esp_ds_validate_opaque_key(opaque_key) != PSA_SUCCESS) { + if (esp_rsa_ds_validate_opaque_key(opaque_key) != PSA_SUCCESS) { return PSA_ERROR_INVALID_ARGUMENT; } if ((xSemaphoreTake(s_ds_lock, s_timeout_ms / portTICK_PERIOD_MS) != pdTRUE)) { - ESP_LOGE(TAG, "ds_lock could not be obtained in specified time"); return PSA_ERROR_GENERIC_ERROR; } - int padding = ESP_DS_PADDING_PKCS_V15; + esp_rsa_ds_padding_t padding = ESP_RSA_DS_PADDING_INVALID; if (PSA_ALG_IS_RSA_PSS(operation->alg)) { - padding = ESP_DS_PADDING_PSS; + padding = ESP_RSA_DS_PADDING_PSS; + } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(operation->alg)) { + padding = ESP_RSA_DS_PADDING_PKCS_V15; } psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(operation->alg); @@ -143,60 +139,61 @@ psa_status_t esp_ds_opaque_sign_hash_start( const size_t words_len = (opaque_key->rsa_length_bits / 32); const size_t rsa_len_bytes = words_len * 4; operation->sig_buffer_size = rsa_len_bytes; + operation->sig_buffer = NULL; unsigned char *em = heap_caps_malloc_prefer(rsa_len_bytes, 1, MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); if (em == NULL) { - ESP_LOGE(TAG, "Could not allocate memory for internal DS operations"); - esp_ds_release_ds_lock(); + esp_rsa_ds_release_ds_lock(); return PSA_ERROR_INSUFFICIENT_MEMORY; } - psa_status_t status = esp_ds_pad( + psa_status_t status = esp_rsa_ds_pad( padding, hash_alg, hash_length, hash, -1, em, rsa_len_bytes); if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "Error in esp_ds_pad, returned %d ", status); - heap_caps_free(em); - esp_ds_release_ds_lock(); - return status; + goto error; } operation->sig_buffer = heap_caps_malloc_prefer(rsa_len_bytes, 2, MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); if (operation->sig_buffer == NULL) { - ESP_LOGE(TAG, "Could not allocate memory for internal DS operations"); - heap_caps_free(em); - esp_ds_release_ds_lock(); - return PSA_ERROR_INSUFFICIENT_MEMORY; + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto error; } - { - uint32_t *sig_words = (uint32_t *)operation->sig_buffer; - const uint32_t *em_words = (const uint32_t *)em; - for (unsigned int i = 0; i < words_len; i++) { - sig_words[i] = SWAP_INT32(em_words[words_len - (i + 1)]); - } + uint32_t *sig_words = (uint32_t *)operation->sig_buffer; + const uint32_t *em_words = (const uint32_t *)em; + for (unsigned int i = 0; i < words_len; i++) { + sig_words[i] = SWAP_INT32(em_words[words_len - (i + 1)]); } - heap_caps_free(em); - - memcpy(&operation->esp_ds_data, opaque_key->esp_ds_data, sizeof(esp_ds_data_t)); - operation->esp_ds_data.rsa_length = (opaque_key->rsa_length_bits / 32) - 1; + memcpy(&operation->esp_rsa_ds_data, opaque_key->esp_rsa_ds_data, sizeof(esp_ds_data_t)); + operation->esp_rsa_ds_data.rsa_length = (opaque_key->rsa_length_bits / 32) - 1; esp_err_t err = esp_ds_start_sign((const void *)operation->sig_buffer, - &operation->esp_ds_data, + &operation->esp_rsa_ds_data, (hmac_key_id_t) opaque_key->efuse_key_id, - &operation->esp_ds_ctx); + &operation->esp_rsa_ds_ctx); if (err != ESP_OK) { - ESP_LOGE(TAG, "Error in esp_ds_start_sign, returned %X ", err); - heap_caps_free(operation->sig_buffer); - esp_ds_release_ds_lock(); - return PSA_ERROR_GENERIC_ERROR; + status = PSA_ERROR_GENERIC_ERROR; + goto error; } - return PSA_SUCCESS; +error: + if (em) { + heap_caps_free(em); + em = NULL; + } + if (status != PSA_SUCCESS) { + if (operation->sig_buffer) { + heap_caps_free(operation->sig_buffer); + operation->sig_buffer = NULL; + } + esp_rsa_ds_release_ds_lock(); + } + return status; } -psa_status_t esp_ds_opaque_sign_hash_complete( - esp_ds_opaque_sign_hash_operation_t *operation, +psa_status_t esp_rsa_ds_opaque_sign_hash_complete( + esp_rsa_ds_opaque_sign_hash_operation_t *operation, uint8_t *signature, size_t signature_size, size_t *signature_length) { @@ -204,17 +201,20 @@ psa_status_t esp_ds_opaque_sign_hash_complete( return PSA_ERROR_INVALID_ARGUMENT; } - int expected_signature_size = operation->esp_ds_opaque_key->rsa_length_bits / 8; + if ((operation->esp_rsa_ds_ctx == NULL) || (operation->sig_buffer == NULL)) { + return PSA_ERROR_BAD_STATE; + } + + int expected_signature_size = operation->esp_rsa_ds_opaque_key->rsa_length_bits / 8; if (signature_size < expected_signature_size) { return PSA_ERROR_BUFFER_TOO_SMALL; } - esp_err_t err = esp_ds_finish_sign((void *)operation->sig_buffer, operation->esp_ds_ctx); + esp_err_t err = esp_ds_finish_sign((void *)operation->sig_buffer, operation->esp_rsa_ds_ctx); if (err != ESP_OK) { - ESP_LOGE(TAG, "Error in esp_ds_finish_sign, returned %X ", err); memset(operation->sig_buffer, 0, operation->sig_buffer_size); heap_caps_free(operation->sig_buffer); - esp_ds_release_ds_lock(); + esp_rsa_ds_release_ds_lock(); return PSA_ERROR_GENERIC_ERROR; } @@ -228,12 +228,12 @@ psa_status_t esp_ds_opaque_sign_hash_complete( *signature_length = expected_signature_size; memset(operation->sig_buffer, 0, operation->sig_buffer_size); heap_caps_free(operation->sig_buffer); - esp_ds_release_ds_lock(); + esp_rsa_ds_release_ds_lock(); return PSA_SUCCESS; } -psa_status_t esp_ds_opaque_sign_hash_abort( - esp_ds_opaque_sign_hash_operation_t *operation) +psa_status_t esp_rsa_ds_opaque_sign_hash_abort( + esp_rsa_ds_opaque_sign_hash_operation_t *operation) { if (!operation) { return PSA_ERROR_INVALID_ARGUMENT; @@ -241,20 +241,21 @@ psa_status_t esp_ds_opaque_sign_hash_abort( // Free allocated memory if exists if (operation->sig_buffer) { + memset(operation->sig_buffer, 0, operation->sig_buffer_size); heap_caps_free(operation->sig_buffer); operation->sig_buffer = NULL; } // Release the DS lock if held - esp_ds_release_ds_lock(); + esp_rsa_ds_release_ds_lock(); // Clear the operation structure - memset(operation, 0, sizeof(esp_ds_opaque_sign_hash_operation_t)); + memset(operation, 0, sizeof(esp_rsa_ds_opaque_sign_hash_operation_t)); return PSA_SUCCESS; } -psa_status_t esp_ds_opaque_signature_sign_hash( +psa_status_t esp_rsa_ds_opaque_signature_sign_hash( const psa_key_attributes_t *attributes, const uint8_t *key_buffer, size_t key_buffer_size, @@ -266,8 +267,8 @@ psa_status_t esp_ds_opaque_signature_sign_hash( size_t *signature_length ) { - esp_ds_opaque_sign_hash_operation_t operation = {0}; - psa_status_t status = esp_ds_opaque_sign_hash_start( + esp_rsa_ds_opaque_sign_hash_operation_t operation = {0}; + psa_status_t status = esp_rsa_ds_opaque_sign_hash_start( &operation, attributes, key_buffer, @@ -277,25 +278,22 @@ psa_status_t esp_ds_opaque_signature_sign_hash( hash_length ); if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "Error in esp_ds_opaque_sign_hash_start, returned %d ", status); - esp_ds_opaque_sign_hash_abort(&operation); + esp_rsa_ds_opaque_sign_hash_abort(&operation); return status; } - status = esp_ds_opaque_sign_hash_complete( + status = esp_rsa_ds_opaque_sign_hash_complete( &operation, signature, signature_size, signature_length ); - if (status != PSA_SUCCESS) { - esp_ds_opaque_sign_hash_abort(&operation); - return status; - } - return PSA_SUCCESS; + + esp_rsa_ds_opaque_sign_hash_abort(&operation); + return status; } -psa_status_t esp_ds_opaque_import_key( +psa_status_t esp_rsa_ds_opaque_import_key( const psa_key_attributes_t *attributes, const uint8_t *data, size_t data_length, @@ -313,7 +311,7 @@ psa_status_t esp_ds_opaque_import_key( } const esp_ds_data_ctx_t *opaque_key = (const esp_ds_data_ctx_t *)data; - int ret = esp_ds_validate_opaque_key(opaque_key); + int ret = esp_rsa_ds_validate_opaque_key(opaque_key); if (ret != PSA_SUCCESS) { return ret; } @@ -323,7 +321,7 @@ psa_status_t esp_ds_opaque_import_key( return PSA_SUCCESS; } -size_t esp_ds_opaque_size_function( +size_t esp_rsa_ds_opaque_size_function( psa_key_type_t key_type, size_t key_bits) { @@ -334,14 +332,21 @@ size_t esp_ds_opaque_size_function( return sizeof(esp_ds_data_ctx_t); } -void esp_ds_opaque_set_session_timeout(int timeout_ms) +void esp_rsa_ds_opaque_set_session_timeout(int timeout_ms) { + /* add additional offset of ESP_RSA_DS_TIMEOUT_BUFFER_MS ms to have enough time for deleting the TLS connection + * and free the previous ds context after exceeding timeout value + * (this offset also helps when timeout is set to 0) + */ + if (timeout_ms < 0) { + return; + } if (timeout_ms > s_timeout_ms) { - s_timeout_ms = timeout_ms; + s_timeout_ms = timeout_ms + ESP_RSA_DS_TIMEOUT_BUFFER_MS; } } -psa_status_t esp_ds_opaque_asymmetric_decrypt( +psa_status_t esp_rsa_ds_opaque_asymmetric_decrypt( const psa_key_attributes_t *attributes, const uint8_t *key, size_t key_length, psa_algorithm_t alg, const uint8_t *input, size_t input_length, const uint8_t *salt, size_t salt_length, @@ -360,7 +365,7 @@ psa_status_t esp_ds_opaque_asymmetric_decrypt( const esp_ds_data_ctx_t *opaque_key = (const esp_ds_data_ctx_t *)key; - if (esp_ds_validate_opaque_key(opaque_key) != PSA_SUCCESS) { + if (esp_rsa_ds_validate_opaque_key(opaque_key) != PSA_SUCCESS) { return PSA_ERROR_INVALID_ARGUMENT; } @@ -369,18 +374,14 @@ psa_status_t esp_ds_opaque_asymmetric_decrypt( return PSA_ERROR_INVALID_ARGUMENT; } - esp_ds_padding_t padding = ESP_DS_PADDING_PKCS_V15; + esp_rsa_ds_padding_t padding = ESP_RSA_DS_PADDING_INVALID; if (PSA_ALG_IS_RSA_OAEP(alg)) { - padding = ESP_DS_PADDING_OAEP; + padding = ESP_RSA_DS_PADDING_OAEP; } else if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) { - padding = ESP_DS_PADDING_PKCS_V15; - } else { - ESP_LOGE(TAG, "Unsupported algorithm for decryption"); - return PSA_ERROR_NOT_SUPPORTED; + padding = ESP_RSA_DS_PADDING_PKCS_V15; } if (xSemaphoreTake(s_ds_lock, s_timeout_ms / portTICK_PERIOD_MS) != pdTRUE) { - ESP_LOGE(TAG, "ds_lock could not be obtained in specified time"); return PSA_ERROR_GENERIC_ERROR; } @@ -388,8 +389,7 @@ psa_status_t esp_ds_opaque_asymmetric_decrypt( size_t data_len = ilen / 4; uint32_t *em_words = heap_caps_malloc_prefer(sizeof(uint32_t) * data_len, 1, MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); if (em_words == NULL) { - ESP_LOGE(TAG, "Could not allocate memory for internal DS operations"); - esp_ds_release_ds_lock(); + esp_rsa_ds_release_ds_lock(); return PSA_ERROR_INSUFFICIENT_MEMORY; } @@ -397,36 +397,33 @@ psa_status_t esp_ds_opaque_asymmetric_decrypt( em_words[i] = SWAP_INT32(((uint32_t *)input)[(data_len) - (i + 1)]); } - esp_ds_opaque_sign_hash_operation_t operation = {0}; + esp_rsa_ds_opaque_sign_hash_operation_t operation = {0}; operation.alg = alg; - operation.esp_ds_opaque_key = opaque_key; + operation.esp_rsa_ds_opaque_key = opaque_key; operation.sig_buffer = em_words; esp_err_t err = esp_ds_start_sign((const void *)em_words, - opaque_key->esp_ds_data, + opaque_key->esp_rsa_ds_data, (hmac_key_id_t) opaque_key->efuse_key_id, - &operation.esp_ds_ctx); + &operation.esp_rsa_ds_ctx); if (err != ESP_OK) { - ESP_LOGE(TAG, "Error in esp_ds_start_sign for decryption, returned %X ", err); heap_caps_free(em_words); - esp_ds_release_ds_lock(); + esp_rsa_ds_release_ds_lock(); return PSA_ERROR_GENERIC_ERROR; } - err = esp_ds_finish_sign((void *)em_words, operation.esp_ds_ctx); + err = esp_ds_finish_sign((void *)em_words, operation.esp_rsa_ds_ctx); if (err != ESP_OK) { - ESP_LOGE(TAG, "Error in esp_ds_finish_sign for decryption, returned %X ", err); heap_caps_free(em_words); - esp_ds_release_ds_lock(); + esp_rsa_ds_release_ds_lock(); return PSA_ERROR_GENERIC_ERROR; } - esp_ds_release_ds_lock(); + esp_rsa_ds_release_ds_lock(); // Remove padding uint32_t *out_tmp = heap_caps_malloc_prefer(sizeof(uint32_t) * data_len, 1, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); if (out_tmp == NULL) { - ESP_LOGE(TAG, "Could not allocate memory for internal DS operations"); heap_caps_free(em_words); return PSA_ERROR_INSUFFICIENT_MEMORY; } @@ -436,39 +433,38 @@ psa_status_t esp_ds_opaque_asymmetric_decrypt( } size_t unpadded_len = 0; - psa_status_t ret = 0; - if (padding == ESP_DS_PADDING_PKCS_V15) { - ret = esp_ds_pad_v15_unpad((unsigned char *)out_tmp, ilen, (unsigned char *)out_tmp, ilen, &unpadded_len); + psa_status_t ret = PSA_ERROR_NOT_SUPPORTED; + if (padding == ESP_RSA_DS_PADDING_PKCS_V15) { + ret = esp_rsa_ds_pad_v15_unpad((unsigned char *)out_tmp, ilen, (unsigned char *)out_tmp, ilen, &unpadded_len); } #if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 - else if (padding == ESP_DS_PADDING_OAEP) { - ret = esp_ds_pad_oaep_unpad((unsigned char *)out_tmp, ilen, (unsigned char *)out_tmp, ilen, &unpadded_len, PSA_ALG_RSA_OAEP_GET_HASH(alg)); + else if (padding == ESP_RSA_DS_PADDING_OAEP) { + ret = esp_rsa_ds_pad_oaep_unpad((unsigned char *)out_tmp, ilen, (unsigned char *)out_tmp, ilen, &unpadded_len, PSA_ALG_RSA_OAEP_GET_HASH(alg)); } #endif /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */ else { - ESP_LOGE(TAG, "Unsupported padding scheme for decryption"); - heap_caps_free(em_words); - heap_caps_free(out_tmp); - return PSA_ERROR_NOT_SUPPORTED; + ret = PSA_ERROR_NOT_SUPPORTED; + goto exit; } if (ret != PSA_SUCCESS) { - ESP_LOGE(TAG, "Error in unpadding, returned %d", ret); - heap_caps_free(em_words); - heap_caps_free(out_tmp); - return PSA_ERROR_INVALID_PADDING; + ret = PSA_ERROR_INVALID_PADDING; + goto exit; } if (output_size < unpadded_len) { - ESP_LOGE(TAG, "Output buffer too small for decrypted data, required size: %zu", unpadded_len); - heap_caps_free(em_words); - heap_caps_free(out_tmp); - return PSA_ERROR_BUFFER_TOO_SMALL; + ret = PSA_ERROR_BUFFER_TOO_SMALL; + goto exit; } memcpy(output, out_tmp, unpadded_len); *output_length = unpadded_len; + ret = PSA_SUCCESS; + +exit: + memset(em_words, 0, sizeof(uint32_t) * data_len); + memset(out_tmp, 0, sizeof(uint32_t) * data_len); heap_caps_free(em_words); heap_caps_free(out_tmp); - return PSA_SUCCESS; + return ret; } diff --git a/components/mbedtls/port/psa_driver/esp_ds/psa_crypto_driver_esp_ds_utilities.c b/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds_utilities.c similarity index 92% rename from components/mbedtls/port/psa_driver/esp_ds/psa_crypto_driver_esp_ds_utilities.c rename to components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds_utilities.c index bf1a7390b4..ac16315d1d 100644 --- a/components/mbedtls/port/psa_driver/esp_ds/psa_crypto_driver_esp_ds_utilities.c +++ b/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds_utilities.c @@ -5,7 +5,7 @@ */ #include -#include "include/psa_crypto_driver_esp_ds_utilities.h" +#include "include/psa_crypto_driver_esp_rsa_ds_utilities.h" #include "mbedtls/asn1.h" #include "mbedtls/psa_util.h" #include "esp_log.h" @@ -41,7 +41,7 @@ static const oid_md_mapping_t oid_md_table[] = { { PSA_ALG_NONE, NULL, 0 } }; -static int esp_ds_get_oid_by_psa_alg(psa_algorithm_t md_alg, const char **oid, size_t *olen) +static int esp_rsa_ds_get_oid_by_psa_alg(psa_algorithm_t md_alg, const char **oid, size_t *olen) { for (size_t i = 0; oid_md_table[i].md_alg != PSA_ALG_NONE; i++) { if (oid_md_table[i].md_alg == md_alg) { @@ -53,7 +53,7 @@ static int esp_ds_get_oid_by_psa_alg(psa_algorithm_t md_alg, const char **oid, s return PSA_ERROR_NOT_SUPPORTED; } -psa_status_t esp_ds_pad_v15_encode(psa_algorithm_t alg, unsigned int hashlen, +psa_status_t esp_rsa_ds_pad_v15_encode(psa_algorithm_t alg, unsigned int hashlen, const unsigned char *hash, size_t dst_len, unsigned char *dst) @@ -65,7 +65,7 @@ psa_status_t esp_ds_pad_v15_encode(psa_algorithm_t alg, unsigned int hashlen, /* Are we signing hashed or raw data? */ if (alg != PSA_ALG_NONE) { - if (esp_ds_get_oid_by_psa_alg(alg, &oid, &oid_size) != PSA_SUCCESS) { + if (esp_rsa_ds_get_oid_by_psa_alg(alg, &oid, &oid_size) != PSA_SUCCESS) { return PSA_ERROR_INVALID_ARGUMENT; } @@ -161,7 +161,7 @@ psa_status_t esp_ds_pad_v15_encode(psa_algorithm_t alg, unsigned int hashlen, return PSA_SUCCESS; } -psa_status_t esp_ds_pad_v15_unpad(unsigned char *input, +psa_status_t esp_rsa_ds_pad_v15_unpad(unsigned char *input, size_t ilen, unsigned char *output, size_t output_max_len, @@ -227,7 +227,7 @@ psa_status_t esp_ds_pad_v15_unpad(unsigned char *input, } #if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 -static psa_status_t esp_ds_mgf_mask(unsigned char *dst, size_t dlen, unsigned char *src, +static psa_status_t esp_rsa_ds_mgf_mask(unsigned char *dst, size_t dlen, unsigned char *src, size_t slen, psa_algorithm_t hash_alg) { unsigned char counter[4]; @@ -286,7 +286,7 @@ exit: return status; } -static psa_status_t esp_ds_hash_mprime(const unsigned char *hash, size_t hlen, +static psa_status_t esp_rsa_ds_hash_mprime(const unsigned char *hash, size_t hlen, const unsigned char *salt, size_t slen, unsigned char *out, psa_algorithm_t hash_alg) { @@ -319,7 +319,7 @@ exit: return status; } -psa_status_t esp_ds_pad_v21_encode(psa_algorithm_t hash_alg, +psa_status_t esp_rsa_ds_pad_v21_encode(psa_algorithm_t hash_alg, unsigned int hashlen, const unsigned char *hash, int saltlen, @@ -386,7 +386,7 @@ psa_status_t esp_ds_pad_v21_encode(psa_algorithm_t hash_alg, p += slen; /* Generate H = Hash( M' ) */ - ret = esp_ds_hash_mprime(hash, hashlen, salt, slen, p, hash_alg); + ret = esp_rsa_ds_hash_mprime(hash, hashlen, salt, slen, p, hash_alg); if (ret != 0) { return ret; } @@ -397,7 +397,7 @@ psa_status_t esp_ds_pad_v21_encode(psa_algorithm_t hash_alg, } /* maskedDB: Apply dbMask to DB */ - ret = esp_ds_mgf_mask(sig + offset, olen - hlen - 1 - offset, p, hlen, hash_alg); + ret = esp_rsa_ds_mgf_mask(sig + offset, olen - hlen - 1 - offset, p, hlen, hash_alg); if (ret != 0) { return ret; } @@ -410,7 +410,7 @@ psa_status_t esp_ds_pad_v21_encode(psa_algorithm_t hash_alg, return ret; } -psa_status_t esp_ds_pad_oaep_unpad(unsigned char *input, +psa_status_t esp_rsa_ds_pad_oaep_unpad(unsigned char *input, size_t ilen, unsigned char *output, size_t output_max_len, @@ -425,9 +425,9 @@ psa_status_t esp_ds_pad_oaep_unpad(unsigned char *input, bad |= (ilen < 2 * hlen + 2); /* Apply MGF masks */ - bad |= esp_ds_mgf_mask(input + 1, hlen, input + hlen + 1, ilen - hlen - 1, hash_alg) != PSA_SUCCESS; + bad |= esp_rsa_ds_mgf_mask(input + 1, hlen, input + hlen + 1, ilen - hlen - 1, hash_alg) != PSA_SUCCESS; - bad |= esp_ds_mgf_mask(input + hlen + 1, ilen - hlen - 1, input + 1, hlen, hash_alg) != PSA_SUCCESS; + bad |= esp_rsa_ds_mgf_mask(input + hlen + 1, ilen - hlen - 1, input + 1, hlen, hash_alg) != PSA_SUCCESS; /* Check first byte (should be 0x00) */ bad |= input[0]; diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ds.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ds.h deleted file mode 100644 index 7b05181f9c..0000000000 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ds.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#pragma once - -#include "psa/crypto.h" -#include "psa_crypto_driver_esp_ds_contexts.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(ESP_DS_DRIVER_ENABLED) -#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT -#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ -#endif /* ESP_DS_DRIVER_ENABLED */ - -#define PSA_CRYPTO_ESP_DS_DRIVER_LOCATION ((psa_key_location_t) 0x800002) - - -#define PSA_KEY_LIFETIME_ESP_DS \ - PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( \ - PSA_KEY_PERSISTENCE_VOLATILE, \ - PSA_CRYPTO_ESP_DS_DRIVER_LOCATION) - -#ifdef SOC_DIG_SIGN_SUPPORTED -psa_status_t esp_ds_opaque_sign_hash_start( - esp_ds_opaque_sign_hash_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *hash, - size_t hash_length); - -psa_status_t esp_ds_opaque_sign_hash_complete( - esp_ds_opaque_sign_hash_operation_t *operation, - uint8_t *signature, size_t signature_size, - size_t *signature_length); - -psa_status_t esp_ds_opaque_sign_hash_abort( - esp_ds_opaque_sign_hash_operation_t *operation); - -psa_status_t esp_ds_opaque_signature_sign_hash( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *hash, - size_t hash_length, - uint8_t *signature, - size_t signature_size, - size_t *signature_length -); - -psa_status_t esp_ds_opaque_import_key( - const psa_key_attributes_t *attributes, - const uint8_t *data, - size_t data_length, - uint8_t *key_buffer, - size_t key_buffer_size, - size_t *key_buffer_length, - size_t *bits); - -size_t esp_ds_opaque_size_function( - psa_key_type_t key_type, - size_t key_bits); - -void esp_ds_opaque_set_session_timeout(int timeout_ms); - -psa_status_t esp_ds_opaque_asymmetric_decrypt( - const psa_key_attributes_t *attributes, const uint8_t *key, - size_t key_length, psa_algorithm_t alg, const uint8_t *input, - size_t input_length, const uint8_t *salt, size_t salt_length, - uint8_t *output, size_t output_size, size_t *output_length); -#endif /* SOC_DIG_SIGN_SUPPORTED */ -#ifdef __cplusplus -} -#endif diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ds_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ds_contexts.h deleted file mode 100644 index 99f0eec1c2..0000000000 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ds_contexts.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#pragma once - -#include "psa/crypto.h" -#ifdef SOC_DIG_SIGN_SUPPORTED -#include "esp_ds.h" -#endif /* SOC_DIG_SIGN_SUPPORTED */ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - ESP_DS_PADDING_PKCS_V15, - ESP_DS_PADDING_PSS, - ESP_DS_PADDING_OAEP, -} esp_ds_padding_t; - -#ifdef SOC_DIG_SIGN_SUPPORTED -typedef struct { - esp_ds_data_t *esp_ds_data; - uint8_t efuse_key_id; /* efuse block id in which DS_KEY is stored e.g. 0,1*/ - uint16_t rsa_length_bits; /* length of RSA private key in bits e.g. 2048 */ -} esp_ds_data_ctx_t; - -typedef struct { - const esp_ds_data_ctx_t *esp_ds_opaque_key; /*!< Pointer to the esp ds opaque key */ - psa_algorithm_t alg; /*!< Algorithm used in the sign operation */ - uint32_t *sig_buffer; /*!< Buffer to hold the signature */ - size_t sig_buffer_size; /*!< Size of the signature buffer */ - esp_ds_context_t *esp_ds_ctx; /*!< Pointer to the esp ds context */ - esp_ds_data_t esp_ds_data; -} esp_ds_opaque_sign_hash_operation_t; -#endif /* SOC_DIG_SIGN_SUPPORTED */ - -#ifdef __cplusplus -} -#endif diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_rsa_ds.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_rsa_ds.h new file mode 100644 index 0000000000..74d27d3210 --- /dev/null +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_rsa_ds.h @@ -0,0 +1,180 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "sdkconfig.h" +#include "psa/crypto.h" +#if defined(SOC_DIG_SIGN_SUPPORTED) && defined(CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL) +#include "psa_crypto_driver_esp_rsa_ds_contexts.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(ESP_RSA_DS_DRIVER_ENABLED) +#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT +#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ +#endif /* ESP_RSA_DS_DRIVER_ENABLED */ + +#define PSA_CRYPTO_ESP_RSA_DS_DRIVER_LOCATION ((psa_key_location_t) 0x800002) + + +#define PSA_KEY_LIFETIME_ESP_RSA_DS \ + PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( \ + PSA_KEY_PERSISTENCE_VOLATILE, \ + PSA_CRYPTO_ESP_RSA_DS_DRIVER_LOCATION) + +/** + * @brief Start the RSA DS opaque sign hash operation + * + * @param operation Operation context + * @param attributes Key attributes + * @param key_buffer Key buffer + * @param key_buffer_size Key buffer size + * @param alg Algorithm used in the sign operation + * @param hash Hash to sign + * @param hash_length Length of the hash + * @return Status of the start operation + * PSA_SUCCESS if the operation was started successfully + * Error code if the operation was not started successfully, check psa_status_t documentation for more details. + */ +psa_status_t esp_rsa_ds_opaque_sign_hash_start( + esp_rsa_ds_opaque_sign_hash_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *hash, + size_t hash_length); + +/** + * @brief Complete the RSA DS opaque sign hash operation. + * The signature buffer should be pre-allocated with the size of the RSA key. + * The operation context should be initialised with the start operation. + * @param operation Operation context + * @param signature Signature buffer + * @param signature_size Size of the signature buffer + * @param signature_length Actual length of the signature + * @return Status of the complete operation + * PSA_SUCCESS if the operation was completed successfully + * Error code if the operation was not completed successfully, check psa_status_t documentation for more details. + */ +psa_status_t esp_rsa_ds_opaque_sign_hash_complete( + esp_rsa_ds_opaque_sign_hash_operation_t *operation, + uint8_t *signature, size_t signature_size, + size_t *signature_length); + +/** + * @brief Abort the RSA DS opaque sign hash operation. + * The operation context should be initialised with the start operation. + * @param operation Operation context + * @return Status of the abort operation + * PSA_SUCCESS if the operation was aborted successfully + * Error code if the operation was not aborted successfully, check psa_status_t documentation for more details. + */ +psa_status_t esp_rsa_ds_opaque_sign_hash_abort( + esp_rsa_ds_opaque_sign_hash_operation_t *operation); + +/** + * @brief Sign the hash using the RSA DS opaque key. + * This is one-shot function that combines the start and complete operations. + * + * @param attributes Key attributes + * @param key_buffer Key buffer + * @param key_buffer_size Key buffer size + * @param alg Algorithm used in the sign operation + * @param hash Hash to sign + * @param hash_length Length of the hash + * @param signature Signature buffer + * @param signature_size Size of the signature buffer + * @param signature_length Actual length of the signature + * @return Status of the sign operation + * PSA_SUCCESS if the operation was completed successfully + * Error code if the operation was not completed successfully, check psa_status_t documentation for more details. + */ +psa_status_t esp_rsa_ds_opaque_signature_sign_hash( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *hash, + size_t hash_length, + uint8_t *signature, + size_t signature_size, + size_t *signature_length +); + +/** + * @brief Import the RSA DS opaque key + * The data should be of type esp_ds_data_ctx_t and should be + * already initialised with DS data and efuse key id. + * + * @param attributes Key attributes + * @param data Key data + * @param data_length Key data length + * @param key_buffer Key buffer + * @param key_buffer_size Key buffer size + * @param key_buffer_length Key buffer length + * @param bits Key bits + * @return Status of the import operation + * PSA_SUCCESS if the key was imported successfully + * Error code if the key was not imported successfully, check psa_status_t documentation for more details + */ +psa_status_t esp_rsa_ds_opaque_import_key( + const psa_key_attributes_t *attributes, + const uint8_t *data, + size_t data_length, + uint8_t *key_buffer, + size_t key_buffer_size, + size_t *key_buffer_length, + size_t *bits); + +/** + * @brief Return the size of the RSA DS opaque key in bytes + * + * @param key_type Key type + * @param key_bits Key bits + * @return Size of the RSA DS opaque key in bytes + */ +size_t esp_rsa_ds_opaque_size_function( + psa_key_type_t key_type, + size_t key_bits); + +/** + * @brief Set the timeout for the RSA DS session + * + * @param timeout_ms Timeout in milliseconds + */ +void esp_rsa_ds_opaque_set_session_timeout(int timeout_ms); + +/** + * @brief Decrypt the input using the RSA DS opaque key. + * + * @param attributes Key attributes + * @param key Key buffer + * @param key_length Key buffer size + * @param alg Algorithm used in the decrypt operation + * @param input Input buffer + * @param input_length Length of the input buffer + * @param salt Salt buffer + * @param salt_length Length of the salt buffer + * @param output Output buffer + * @param output_size Size of the output buffer + * @param output_length Actual length of the output + * @return Status of the decrypt operation + * PSA_SUCCESS if the operation was completed successfully + * Error code if the operation was not completed successfully, check psa_status_t documentation for more details. + */ +psa_status_t esp_rsa_ds_opaque_asymmetric_decrypt( + const psa_key_attributes_t *attributes, const uint8_t *key, + size_t key_length, psa_algorithm_t alg, const uint8_t *input, + size_t input_length, const uint8_t *salt, size_t salt_length, + uint8_t *output, size_t output_size, size_t *output_length); +#endif /* SOC_DIG_SIGN_SUPPORTED && CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL */ +#ifdef __cplusplus +} +#endif diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_rsa_ds_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_rsa_ds_contexts.h new file mode 100644 index 0000000000..321d3831ad --- /dev/null +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_rsa_ds_contexts.h @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "sdkconfig.h" +#include "soc/soc_caps.h" + +#if defined(SOC_DIG_SIGN_SUPPORTED) && defined(CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL) +#include "psa/crypto.h" +#include "esp_ds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief RSA-DS padding options + */ +typedef enum { + ESP_RSA_DS_PADDING_PKCS_V15, + ESP_RSA_DS_PADDING_PSS, + ESP_RSA_DS_PADDING_OAEP, + ESP_RSA_DS_PADDING_INVALID = -1 +} esp_rsa_ds_padding_t; + +/** + * @brief ESP DS data context + * This context is used to store the ESP DS data. + */ +typedef struct { + esp_ds_data_t *esp_rsa_ds_data; /**< Pointer to the esp ds data */ + uint8_t efuse_key_id; /**< efuse block id in which DS_KEY is stored e.g. 0,1*/ + uint16_t rsa_length_bits; /**< length of RSA private key in bits e.g. 2048 */ +} esp_ds_data_ctx_t; + +#if !(__DOXYGEN__) // No need to document these structures, these are internal to the driver +/* The buffers are stored in the little-endian format */ +typedef struct { + const esp_ds_data_ctx_t *esp_rsa_ds_opaque_key; /**< Pointer to the esp ds opaque key */ + psa_algorithm_t alg; /**< Algorithm used in the sign operation */ + uint32_t *sig_buffer; /**< Buffer to hold the signature */ + size_t sig_buffer_size; /**< Size of the signature buffer */ + esp_ds_context_t *esp_rsa_ds_ctx; /**< Pointer to the esp ds context */ + esp_ds_data_t esp_rsa_ds_data; /**< RSA DS data */ +} esp_rsa_ds_opaque_sign_hash_operation_t; +#endif /* !(__DOXYGEN__) */ + +#ifdef __cplusplus +} +#endif + +#endif /* SOC_DIG_SIGN_SUPPORTED && CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL */ diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha_contexts.h index 19c63c20ff..1635e0aff7 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha_contexts.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha_contexts.h @@ -10,6 +10,7 @@ #include "esp_types.h" #include #include "soc/soc_caps.h" +#include "sdkconfig.h" #ifdef __cplusplus extern "C" { @@ -28,6 +29,9 @@ extern "C" { * crypto_driver_contexts_primitives.h. */ +/** + * @brief ESP SHA operation type + */ typedef enum { ESP_SHA_OPERATION_TYPE_SHA1, ESP_SHA_OPERATION_TYPE_SHA256, @@ -37,24 +41,33 @@ typedef enum { } esp_sha_operation_type_t; /** - * \brief ESP SHA1 state enumeration + * @brief ESP SHA1 state enumeration */ typedef enum { ESP_SHA1_STATE_INIT, ESP_SHA1_STATE_IN_PROCESS } esp_sha1_state; +/** + * @brief ESP SHA256 state enumeration + */ typedef enum { ESP_SHA256_STATE_INIT, ESP_SHA256_STATE_IN_PROCESS } esp_sha256_state; +/** + * @brief ESP SHA512 state enumeration + */ typedef enum { ESP_SHA512_STATE_INIT, ESP_SHA512_STATE_IN_PROCESS } esp_sha512_state; -#if SOC_SHA_SUPPORT_PARALLEL_ENG +#if CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG +/** + * @brief ESP SHA mode enumeration + */ typedef enum { ESP_SHA_MODE_UNUSED, ESP_SHA_MODE_HARDWARE, @@ -63,61 +76,65 @@ typedef enum { #endif /* SOC_SHA_SUPPORT_PARALLEL_ENG */ /** - * \brief ESP SHA1 context structure + * @brief ESP SHA1 context structure */ typedef struct { - uint32_t total[2]; /*!< The number of Bytes processed. */ - uint32_t state[5]; /*!< The intermediate digest state. */ - unsigned char buffer[64]; /*!< The data block being processed. */ - bool first_block; /*!< First block flag for hardware initialization */ - int sha_state; /*!< SHA operation state */ -#if SOC_SHA_SUPPORT_PARALLEL_ENG + uint32_t total[2]; /**< The number of Bytes processed. */ + uint32_t state[5]; /**< The intermediate digest state. */ + unsigned char buffer[64]; /**< The data block being processed. */ + bool first_block; /**< First block flag for hardware initialization */ + int sha_state; /**< SHA operation state */ +#if CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG esp_sha_mode_t operation_mode; /*!< Hardware or Software mode */ #endif /* SOC_SHA_SUPPORT_PARALLEL_ENG */ } esp_sha1_context; /** - * \brief ESP SHA256 context structure + * @brief ESP SHA256 context structure */ typedef struct { - unsigned char buffer[64]; /*!< The data block being processed. */ - uint32_t total[2]; /*!< The number of Bytes processed. */ - uint32_t state[8]; /*!< The intermediate digest state. */ - bool first_block; /*!< First block flag for hardware initialization */ - int sha_state; /*!< SHA operation state */ - int mode; /*!< SHA2_224 or SHA2_256 */ -#if SOC_SHA_SUPPORT_PARALLEL_ENG + unsigned char buffer[64]; /**< The data block being processed. */ + uint32_t total[2]; /**< The number of Bytes processed. */ + uint32_t state[8]; /**< The intermediate digest state. */ + bool first_block; /**< First block flag for hardware initialization */ + int sha_state; /**< SHA operation state */ + int mode; /**< SHA2_224 or SHA2_256 */ +#if CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG esp_sha_mode_t operation_mode; /*!< Hardware or Software mode */ #endif /* SOC_SHA_SUPPORT_PARALLEL_ENG */ } esp_sha256_context; /** - * \brief ESP SHA512 context structure - * + * @brief ESP SHA512 context structure */ typedef struct { - uint64_t total[2]; /*!< The number of Bytes processed. */ - uint64_t state[8]; /*!< The intermediate digest state. */ - unsigned char buffer[128]; /*!< The data block being processed. */ - bool first_block; - int sha_state; - int mode; - uint32_t t_val; /*!< t_val for 512/t mode */ -#if SOC_SHA_SUPPORT_PARALLEL_ENG - esp_sha_mode_t operation_mode; /*!< Hardware or Software mode */ -#endif /* SOC_SHA_SUPPORT_PARALLEL_ENG */ + uint64_t total[2]; /**< The number of Bytes processed. */ + uint64_t state[8]; /**< The intermediate digest state. */ + unsigned char buffer[128]; /**< The data block being processed. */ + bool first_block; /**< First block flag for hardware initialization */ + int sha_state; /**< SHA operation state */ + int mode; /**< SHA2_224 or SHA2_256 */ + uint32_t t_val; /**< t_val for 512/t mode */ +#if CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG + esp_sha_mode_t operation_mode; /**< Hardware or Software mode */ +#endif /* CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG */ } esp_sha512_context; +/** + * @brief ESP SHA context type + * This is void pointer to remove any dependency on the actual SHA context structure + * and allows the driver to be used with different SHA context structures. + */ typedef void *esp_sha_context_t; /** - * \brief ESP SHA driver operation context + * @brief ESP SHA driver operation context * * This structure contains the contexts for different SHA algorithms * supported by the ESP hardware accelerator. */ typedef struct { - esp_sha_context_t sha_ctx; - esp_sha_operation_type_t sha_type; + esp_sha_context_t sha_ctx; /**< Pointer to the SHA context */ + esp_sha_operation_type_t sha_type; /**< SHA operation type */ } esp_sha_hash_operation_t; #ifdef __cplusplus diff --git a/components/mbedtls/test_apps/main/test_ds_sign_and_decrypt.c b/components/mbedtls/test_apps/main/test_ds_sign_and_decrypt.c index 38583f2381..f3e83d9811 100644 --- a/components/mbedtls/test_apps/main/test_ds_sign_and_decrypt.c +++ b/components/mbedtls/test_apps/main/test_ds_sign_and_decrypt.c @@ -10,16 +10,12 @@ #include "esp_random.h" #include "sdkconfig.h" #include "soc/soc_caps.h" -#include "esp_efuse.h" #include "hal/hmac_types.h" +#include "esp_efuse.h" -#ifndef ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE -#define ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE 0 -#endif - -#ifdef SOC_DIG_SIGN_SUPPORTED +#ifdef CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL #include "esp_ds.h" -#include "psa_crypto_driver_esp_ds.h" +#include "psa_crypto_driver_esp_rsa_ds.h" esp_ds_data_ctx_t *esp_secure_cert_get_ds_ctx(void) { @@ -34,7 +30,7 @@ esp_ds_data_ctx_t *esp_secure_cert_get_ds_ctx(void) // Mock RSA key parameters ds_key->rsa_length_bits = 2048; ds_key->efuse_key_id = 0; - ds_key->esp_ds_data = calloc(1, sizeof(esp_ds_data_t)); + ds_key->esp_rsa_ds_data = calloc(1, sizeof(esp_ds_data_t)); // Fill in other necessary fields as per esp_ds_data_ctx_t definition // For simplicity, we will leave them zeroed out @@ -44,8 +40,8 @@ esp_ds_data_ctx_t *esp_secure_cert_get_ds_ctx(void) void esp_secure_cert_free_ds_ctx(esp_ds_data_ctx_t *ds_key) { if (ds_key != NULL) { - if (ds_key->esp_ds_data != NULL) { - free(ds_key->esp_ds_data); + if (ds_key->esp_rsa_ds_data != NULL) { + free(ds_key->esp_rsa_ds_data); } free(ds_key); } @@ -67,7 +63,7 @@ TEST_CASE("ds sign test pkcs1_v15 PSA validation", "[ds_rsa_psa]") psa_set_key_bits(&attributes, ds_key->rsa_length_bits); psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); psa_set_key_algorithm(&attributes, alg); - psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_DS); + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_RSA_DS); status = psa_import_key(&attributes, (const uint8_t *)ds_key, sizeof(*ds_key), @@ -83,15 +79,15 @@ TEST_CASE("ds sign test pkcs1_v15 PSA validation", "[ds_rsa_psa]") TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, status); ds_key->rsa_length_bits = 2048; // Reset to valid RSA length - esp_ds_data_t *ds_data_backup = ds_key->esp_ds_data; - ds_key->esp_ds_data = NULL; // NULL esp_ds_data to trigger validation failure + esp_ds_data_t *ds_data_backup = ds_key->esp_rsa_ds_data; + ds_key->esp_rsa_ds_data = NULL; // NULL esp_rsa_ds_data to trigger validation failure status = psa_import_key(&attributes, (const uint8_t *)ds_key, sizeof(*ds_key), &keyt_id); TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, status); - ds_key->esp_ds_data = ds_data_backup; // Restore esp_ds_data + ds_key->esp_rsa_ds_data = ds_data_backup; // Restore esp_rsa_ds_data esp_secure_cert_free_ds_ctx(ds_key); } @@ -112,7 +108,7 @@ TEST_CASE("ds sign test pkcs1_v15 PSA", "[ds_rsa_psa]") psa_set_key_bits(&attributes, ds_key->rsa_length_bits); psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); psa_set_key_algorithm(&attributes, alg); - psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_DS); + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_RSA_DS); status = psa_import_key(&attributes, (const uint8_t *)ds_key, sizeof(*ds_key), @@ -139,6 +135,23 @@ TEST_CASE("ds sign test pkcs1_v15 PSA", "[ds_rsa_psa]") // Free the DS context to prevent memory leak esp_secure_cert_free_ds_ctx(ds_key); + + // Because we have wrapped around the ds_start_sign and ds_finish_sign functions, + // we are not actually performing the real signing operation. That test is done in the + // crypto test_apps, so here we just check that the surrounding code works as expected. + // In this test, we have used v15 padding, so we expect the signature to be non-null + // and the hash to be part of the signature. + TEST_ASSERT_EQUAL(0, memcmp(hash, signature + (256 - hash_length), hash_length)); + + // Let's also ensure that signature has correct encoding + // Just before the hash start, it should have size of hash + TEST_ASSERT_EQUAL(hash_length, signature[256 - hash_length - 1]); + + // One byte before should be MBEDTLS_ASN1_OCTET_STRING + TEST_ASSERT_EQUAL(0x04, signature[256 - hash_length - 2]); + + // And the first byte should be 0x00, indicating that this is a valid PKCS#1 v1.5 signature + TEST_ASSERT_EQUAL(0x00, signature[0]); } const unsigned char message[] = { @@ -162,7 +175,7 @@ TEST_CASE("ds sign test pkcs1_v21 PSA", "[ds_rsa_psa]") psa_set_key_bits(&attributes, ds_key->rsa_length_bits); psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); psa_set_key_algorithm(&attributes, alg); - psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_DS); + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_RSA_DS); status = psa_import_key(&attributes, (const uint8_t *)ds_key, sizeof(*ds_key), @@ -227,7 +240,7 @@ TEST_CASE("ds decrypt test pkcs1_v21 PSA", "[ds_rsa]") psa_set_key_bits(&attributes, ds_key->rsa_length_bits); psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); psa_set_key_algorithm(&attributes, alg); - psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_DS); + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_RSA_DS); status = psa_import_key(&attributes, (const uint8_t *)ds_key, sizeof(*ds_key), @@ -289,7 +302,7 @@ TEST_CASE("ds decrypt test pkcs1_v15 PSA", "[ds_rsa]") psa_set_key_bits(&attributes, ds_key->rsa_length_bits); psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); psa_set_key_algorithm(&attributes, alg); - psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_DS); + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_RSA_DS); status = psa_import_key(&attributes, (const uint8_t *)ds_key, sizeof(*ds_key), @@ -342,17 +355,20 @@ int __wrap_esp_ds_finish_sign(void *sig, esp_ds_context_t *ctx) // return __real_esp_ds_finish_sign(sig, ctx); } -#endif /* SOC_DIG_SIGN_SUPPORTED */ +#endif /* CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL */ // Forward declaration for linker-wrapped function extern esp_efuse_purpose_t __real_esp_efuse_get_key_purpose(esp_efuse_block_t block); esp_efuse_purpose_t __wrap_esp_efuse_get_key_purpose(esp_efuse_block_t block) { +#if CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL if (block == EFUSE_BLK_KEY0 + 0) { printf("Mocked esp_efuse_get_key_purpose called for block %d\n", block); return ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE; - } else { + } else +#endif /* CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL */ + { printf("Mocked esp_efuse_get_key_purpose forwarding to real for block %d\n", block); return __real_esp_efuse_get_key_purpose(block); } diff --git a/components/mbedtls/test_apps/sdkconfig.ci.ds_rsa b/components/mbedtls/test_apps/sdkconfig.ci.ds_rsa index 48159ab38d..c6c856da27 100644 --- a/components/mbedtls/test_apps/sdkconfig.ci.ds_rsa +++ b/components/mbedtls/test_apps/sdkconfig.ci.ds_rsa @@ -1 +1,2 @@ CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y +CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL=y diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index a2602bfb10..512e5f6185 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -298,6 +298,9 @@ INPUT = \ $(PROJECT_PATH)/components/mbedtls/esp_crt_bundle/include/esp_crt_bundle.h \ $(PROJECT_PATH)/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ecdsa_contexts.h \ $(PROJECT_PATH)/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque_contexts.h \ + $(PROJECT_PATH)/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_rsa_ds_contexts.h \ + $(PROJECT_PATH)/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha_contexts.h \ + $(PROJECT_PATH)/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h \ $(PROJECT_PATH)/components/nvs_flash/include/nvs_flash.h \ $(PROJECT_PATH)/components/nvs_flash/include/nvs.h \ $(PROJECT_PATH)/components/nvs_flash/include/nvs_bootloader.h \ From 6f5b078ed65cb57ec24efe711d140d262a88597d Mon Sep 17 00:00:00 2001 From: Ashish Sharma Date: Wed, 28 Jan 2026 16:56:16 +0800 Subject: [PATCH 3/3] feat: adds DS Sign capabilities for ESP32S2 --- components/esp-tls/esp_tls_mbedtls.c | 3 ++- components/mbedtls/CMakeLists.txt | 4 ++-- .../mbedtls/port/include/mbedtls/esp_config.h | 7 +++++++ .../esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c | 16 ++++++++++----- .../psa_crypto_driver_esp_rsa_ds_utilities.c | 2 +- .../psa_crypto_driver_esp_aes_contexts.h | 20 ++++--------------- .../include/psa_crypto_driver_esp_rsa_ds.h | 6 +++--- .../psa_crypto_driver_esp_rsa_ds_contexts.h | 12 ++++++----- .../test_apps/main/test_ds_sign_and_decrypt.c | 6 ++++-- .../esp32s2/include/soc/Kconfig.soc_caps.in | 12 +++++++++++ components/soc/esp32s2/include/soc/soc_caps.h | 11 ++++++++++ 11 files changed, 64 insertions(+), 35 deletions(-) diff --git a/components/esp-tls/esp_tls_mbedtls.c b/components/esp-tls/esp_tls_mbedtls.c index 38f56153d3..05fe189e18 100644 --- a/components/esp-tls/esp_tls_mbedtls.c +++ b/components/esp-tls/esp_tls_mbedtls.c @@ -1443,7 +1443,8 @@ static esp_err_t esp_mbedtls_init_pk_ctx_for_ds(const void *pki) int ret = mbedtls_pk_wrap_psa(pki_l->pk_key, ds_key_id); if (ret != 0) { ESP_LOGE(TAG, "mbedtls_pk_wrap_psa failed with -0x%04X", -ret); - return ret; + psa_destroy_key(ds_key_id); + return ESP_FAIL; } ESP_LOGD(TAG, "DS peripheral pk context initialized."); return ESP_OK; diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index 367210753e..111fd3de5a 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -278,8 +278,9 @@ endif() target_sources(mbedtls PRIVATE ${mbedtls_target_sources}) if(NOT ${IDF_TARGET} STREQUAL "linux") - target_link_libraries(tfpsacrypto PRIVATE idf::esp_security) + target_link_libraries(tfpsacrypto PUBLIC idf::esp_security) target_link_libraries(builtin PRIVATE idf::esp_security) + target_link_libraries(p256m PRIVATE idf::esp_security) endif() # Choose peripheral type @@ -383,7 +384,6 @@ if(CONFIG_SOC_HMAC_SUPPORTED) endif() if(CONFIG_SOC_DIG_SIGN_SUPPORTED AND CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL) -target_compile_definitions(tfpsacrypto PRIVATE ESP_DS_DRIVER_ENABLED) target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c" "${COMPONENT_DIR}/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds_utilities.c" diff --git a/components/mbedtls/port/include/mbedtls/esp_config.h b/components/mbedtls/port/include/mbedtls/esp_config.h index 8fd8408ec0..ef905ccfd6 100644 --- a/components/mbedtls/port/include/mbedtls/esp_config.h +++ b/components/mbedtls/port/include/mbedtls/esp_config.h @@ -1743,6 +1743,13 @@ #undef PSA_WANT_KEY_TYPE_AES #endif +/* PSA Crypto RSA DS Driver */ +#ifdef CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL +#define ESP_RSA_DS_DRIVER_ENABLED +#else +#undef ESP_RSA_DS_DRIVER_ENABLED +#endif + /* The following units have ESP32 hardware support, uncommenting each _ALT macro will use the hardware-accelerated implementation. */ diff --git a/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c b/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c index 099b2c36b0..67ea0ddb1c 100644 --- a/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c +++ b/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c @@ -86,6 +86,11 @@ static int esp_rsa_ds_validate_opaque_key(const esp_ds_data_ctx_t *opaque_key) return PSA_ERROR_INVALID_ARGUMENT; } + /* DS data rsa_length must match rsa_length_bits so we can use the key's data directly in sign operations */ + if (opaque_key->esp_rsa_ds_data->rsa_length != (opaque_key->rsa_length_bits / 32) - 1) { + return PSA_ERROR_INVALID_ARGUMENT; + } + esp_efuse_purpose_t purpose = esp_efuse_get_key_purpose(EFUSE_BLK_KEY0 + opaque_key->efuse_key_id); if (purpose != ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE) { return PSA_ERROR_NOT_PERMITTED; @@ -165,11 +170,8 @@ psa_status_t esp_rsa_ds_opaque_sign_hash_start( sig_words[i] = SWAP_INT32(em_words[words_len - (i + 1)]); } - memcpy(&operation->esp_rsa_ds_data, opaque_key->esp_rsa_ds_data, sizeof(esp_ds_data_t)); - operation->esp_rsa_ds_data.rsa_length = (opaque_key->rsa_length_bits / 32) - 1; - esp_err_t err = esp_ds_start_sign((const void *)operation->sig_buffer, - &operation->esp_rsa_ds_data, + opaque_key->esp_rsa_ds_data, (hmac_key_id_t) opaque_key->efuse_key_id, &operation->esp_rsa_ds_ctx); if (err != ESP_OK) { @@ -228,6 +230,7 @@ psa_status_t esp_rsa_ds_opaque_sign_hash_complete( *signature_length = expected_signature_size; memset(operation->sig_buffer, 0, operation->sig_buffer_size); heap_caps_free(operation->sig_buffer); + operation->sig_buffer = NULL; esp_rsa_ds_release_ds_lock(); return PSA_SUCCESS; } @@ -315,6 +318,10 @@ psa_status_t esp_rsa_ds_opaque_import_key( if (ret != PSA_SUCCESS) { return ret; } + + /* Shallow copy: key buffer holds the context; esp_rsa_ds_data points to the caller's data. + * The key material (esp_ds_data_ctx_t and the esp_ds_data_t it points to) must remain + * valid until psa_destroy_key() is called on this key. */ memcpy(key_buffer, opaque_key, sizeof(esp_ds_data_ctx_t)); *key_buffer_length = sizeof(esp_ds_data_ctx_t); *bits = opaque_key->rsa_length_bits; @@ -328,7 +335,6 @@ size_t esp_rsa_ds_opaque_size_function( (void)key_type; (void)key_bits; - // Opaque keys always use the same size structure return sizeof(esp_ds_data_ctx_t); } diff --git a/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds_utilities.c b/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds_utilities.c index ac16315d1d..270a3fda12 100644 --- a/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds_utilities.c +++ b/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds_utilities.c @@ -236,7 +236,7 @@ static psa_status_t esp_rsa_ds_mgf_mask(unsigned char *dst, size_t dlen, unsigne size_t i, use_len; unsigned char mask[PSA_HASH_MAX_SIZE]; psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT; - psa_status_t status; + psa_status_t status = PSA_SUCCESS; hlen = PSA_HASH_LENGTH(hash_alg); diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h index cbe889c41c..bf72b60647 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h @@ -6,26 +6,14 @@ #pragma once -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \file psa_crypto_driver_esp_sha_contexts.h - * - * \brief Context structure definitions for ESP SHA hardware driver. - * - * This file contains the context structures used by the ESP SHA driver - * for PSA Crypto API. These definitions are completely standalone and - * do not include any PSA Crypto headers to avoid circular dependencies. - * - * \note This file may not be included directly. It is included by - * crypto_driver_contexts_primitives.h. - */ #include "esp_types.h" #include "psa/crypto_driver_common.h" +#ifdef __cplusplus +extern "C" { +#endif + #if defined(ESP_AES_DRIVER_ENABLED) #define ESP_MBEDTLS_AES_MAX_BLOCK_LENGTH 16 #define ESP_MBEDTLS_AES_MAX_IV_LENGTH 16 diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_rsa_ds.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_rsa_ds.h index 74d27d3210..862282dc42 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_rsa_ds.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_rsa_ds.h @@ -20,13 +20,13 @@ extern "C" { #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ #endif /* ESP_RSA_DS_DRIVER_ENABLED */ -#define PSA_CRYPTO_ESP_RSA_DS_DRIVER_LOCATION ((psa_key_location_t) 0x800002) +#define PSA_KEY_LOCATION_ESP_RSA_DS ((psa_key_location_t) 0x800003) #define PSA_KEY_LIFETIME_ESP_RSA_DS \ PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( \ PSA_KEY_PERSISTENCE_VOLATILE, \ - PSA_CRYPTO_ESP_RSA_DS_DRIVER_LOCATION) + PSA_KEY_LOCATION_ESP_RSA_DS) /** * @brief Start the RSA DS opaque sign hash operation @@ -174,7 +174,7 @@ psa_status_t esp_rsa_ds_opaque_asymmetric_decrypt( size_t key_length, psa_algorithm_t alg, const uint8_t *input, size_t input_length, const uint8_t *salt, size_t salt_length, uint8_t *output, size_t output_size, size_t *output_length); -#endif /* SOC_DIG_SIGN_SUPPORTED && CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL */ #ifdef __cplusplus } #endif +#endif /* SOC_DIG_SIGN_SUPPORTED && CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL */ diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_rsa_ds_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_rsa_ds_contexts.h index 321d3831ad..01183feaaa 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_rsa_ds_contexts.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_rsa_ds_contexts.h @@ -6,10 +6,9 @@ #pragma once #include "sdkconfig.h" -#include "soc/soc_caps.h" -#if defined(SOC_DIG_SIGN_SUPPORTED) && defined(CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL) -#include "psa/crypto.h" +#if defined(ESP_RSA_DS_DRIVER_ENABLED) +#include "psa/crypto_driver_common.h" #include "esp_ds.h" #ifdef __cplusplus @@ -29,6 +28,10 @@ typedef enum { /** * @brief ESP DS data context * This context is used to store the ESP DS data. + * + * When passed to psa_import_key() for PSA_KEY_LIFETIME_ESP_RSA_DS, the key material + * (this struct and the esp_ds_data_t pointed to by esp_rsa_ds_data) must remain valid + * until psa_destroy_key() is called on the imported key. */ typedef struct { esp_ds_data_t *esp_rsa_ds_data; /**< Pointer to the esp ds data */ @@ -44,7 +47,6 @@ typedef struct { uint32_t *sig_buffer; /**< Buffer to hold the signature */ size_t sig_buffer_size; /**< Size of the signature buffer */ esp_ds_context_t *esp_rsa_ds_ctx; /**< Pointer to the esp ds context */ - esp_ds_data_t esp_rsa_ds_data; /**< RSA DS data */ } esp_rsa_ds_opaque_sign_hash_operation_t; #endif /* !(__DOXYGEN__) */ @@ -52,4 +54,4 @@ typedef struct { } #endif -#endif /* SOC_DIG_SIGN_SUPPORTED && CONFIG_MBEDTLS_HARDWARE_RSA_DS_PERIPHERAL */ +#endif /* ESP_RSA_DS_DRIVER_ENABLED */ diff --git a/components/mbedtls/test_apps/main/test_ds_sign_and_decrypt.c b/components/mbedtls/test_apps/main/test_ds_sign_and_decrypt.c index f3e83d9811..182951e768 100644 --- a/components/mbedtls/test_apps/main/test_ds_sign_and_decrypt.c +++ b/components/mbedtls/test_apps/main/test_ds_sign_and_decrypt.c @@ -31,6 +31,10 @@ esp_ds_data_ctx_t *esp_secure_cert_get_ds_ctx(void) ds_key->rsa_length_bits = 2048; ds_key->efuse_key_id = 0; ds_key->esp_rsa_ds_data = calloc(1, sizeof(esp_ds_data_t)); + if (ds_key->esp_rsa_ds_data != NULL) { + /* rsa_length must match rsa_length_bits for driver validation */ + ds_key->esp_rsa_ds_data->rsa_length = (ds_key->rsa_length_bits / 32) - 1; + } // Fill in other necessary fields as per esp_ds_data_ctx_t definition // For simplicity, we will leave them zeroed out @@ -101,8 +105,6 @@ TEST_CASE("ds sign test pkcs1_v15 PSA", "[ds_rsa_psa]") esp_ds_data_ctx_t *ds_key = esp_secure_cert_get_ds_ctx(); TEST_ASSERT_NOT_NULL(ds_key); - printf("DS key efuse_key_id: %d\n", ds_key->efuse_key_id); - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR); psa_set_key_bits(&attributes, ds_key->rsa_length_bits); diff --git a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in index 9eb3713ec0..833443dfcd 100644 --- a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in @@ -367,6 +367,18 @@ config SOC_CPU_WATCHPOINT_MAX_REGION_SIZE hex default 0x40 +config SOC_DS_SIGNATURE_MAX_BIT_LEN + int + default 4096 + +config SOC_DS_KEY_PARAM_MD_IV_LENGTH + int + default 16 + +config SOC_DS_KEY_CHECK_MAX_WAIT_US + int + default 1100 + config SOC_DAC_CHAN_NUM int default 2 diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index 0d319761a5..3270e4fe53 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -160,6 +160,17 @@ #define SOC_CPU_WATCHPOINTS_NUM 2 #define SOC_CPU_WATCHPOINT_MAX_REGION_SIZE 0x40 // bytes +/*-------------------------- DIGITAL SIGNATURE CAPS ----------------------------------------*/ +/** The maximum length of a Digital Signature in bits. */ +#define SOC_DS_SIGNATURE_MAX_BIT_LEN (4096) + +/** Initialization vector (IV) length for the RSA key parameter message digest (MD) in bytes. */ +#define SOC_DS_KEY_PARAM_MD_IV_LENGTH (16) + +/** Maximum wait time for DS parameter decryption key. If overdue, then key error. + See TRM DS chapter for more details */ +#define SOC_DS_KEY_CHECK_MAX_WAIT_US (1100) + /*-------------------------- DAC CAPS ----------------------------------------*/ #define SOC_DAC_CHAN_NUM 2 #define SOC_DAC_RESOLUTION 8 // DAC resolution ratio 8 bit