From 6f5b078ed65cb57ec24efe711d140d262a88597d Mon Sep 17 00:00:00 2001 From: Ashish Sharma Date: Wed, 28 Jan 2026 16:56:16 +0800 Subject: [PATCH] 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