From 30a120c7cb42f6414fd097dcca4f2007643d4966 Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Wed, 18 Feb 2026 10:18:57 +0530 Subject: [PATCH 1/3] feat(mbedtls/esp_ecdsa): Support Key Manager key using the ESP-ECDSA PSA interface --- .../mbedtls/esp_tee/esp_tee_mbedtls.cmake | 3 +- .../esp_ecdsa/psa_crypto_driver_esp_ecdsa.c | 60 +++++++++++-- .../psa_crypto_driver_esp_ecdsa_contexts.h | 10 ++- .../mbedtls/test_apps/main/test_psa_ecdsa.c | 84 +++++++++++-------- 4 files changed, 108 insertions(+), 49 deletions(-) diff --git a/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake b/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake index b312a9efd3..e180a6bfd7 100644 --- a/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake +++ b/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake @@ -60,11 +60,12 @@ foreach(target ${mbedtls_targets}) target_compile_options(${target} PRIVATE "-O2") endif() target_link_libraries(${target} PUBLIC idf::esp_hal_security) + target_link_libraries(${target} PRIVATE idf::esp_security) endforeach() target_link_libraries(${COMPONENT_LIB} INTERFACE ${mbedtls_targets}) -target_link_libraries(tfpsacrypto PRIVATE idf::esp_security) +target_link_libraries(tfpsacrypto PUBLIC idf::esp_security) target_include_directories(tfpsacrypto PRIVATE ${crypto_port_inc_dirs}) diff --git a/components/mbedtls/port/psa_driver/esp_ecdsa/psa_crypto_driver_esp_ecdsa.c b/components/mbedtls/port/psa_driver/esp_ecdsa/psa_crypto_driver_esp_ecdsa.c index ed9be47abe..c981aac0e7 100644 --- a/components/mbedtls/port/psa_driver/esp_ecdsa/psa_crypto_driver_esp_ecdsa.c +++ b/components/mbedtls/port/psa_driver/esp_ecdsa/psa_crypto_driver_esp_ecdsa.c @@ -20,6 +20,10 @@ #include "esp_efuse.h" #include "esp_efuse_chip.h" +#if SOC_KEY_MANAGER_SUPPORTED +#include "esp_key_mgr.h" +#endif /* SOC_KEY_MANAGER_SUPPORTED */ + #if SOC_ECDSA_SUPPORTED #include "hal/ecdsa_types.h" #include "hal/ecdsa_hal.h" @@ -358,8 +362,8 @@ psa_status_t esp_ecdsa_transparent_verify_hash( */ static bool is_efuse_blk_valid(int high_blk, int low_blk) { - return (high_blk >= EFUSE_BLK0 && high_blk < EFUSE_BLK_MAX && - low_blk >= EFUSE_BLK0 && low_blk < EFUSE_BLK_MAX); + return ((high_blk == 0 || (high_blk >= EFUSE_BLK_KEY0 && high_blk < EFUSE_BLK_KEY_MAX)) && + (low_blk >= EFUSE_BLK_KEY0 && low_blk < EFUSE_BLK_KEY_MAX)); } #endif /* SOC_ECDSA_SUPPORT_CURVE_P384 */ @@ -442,15 +446,18 @@ static psa_status_t validate_ecdsa_opaque_key_attributes(const psa_key_attribute { esp_ecdsa_curve_t expected_curve = psa_bits_to_ecdsa_curve(PSA_BITS_TO_BYTES(psa_get_key_bits(attributes))); - if (expected_curve != opaque_key->curve) { + if (expected_curve == ESP_ECDSA_CURVE_MAX || expected_curve != opaque_key->curve) { return PSA_ERROR_INVALID_ARGUMENT; } #if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN - if (!(opaque_key->use_km_key + if (!(0 +#if SOC_KEY_MANAGER_SUPPORTED + || opaque_key->key_recovery_info +#endif /* SOC_KEY_MANAGER_SUPPORTED */ #if CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN || opaque_key->tee_key_id -#endif +#endif /* CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN */ )) { psa_status_t status = esp_ecdsa_validate_efuse_block(opaque_key->curve, opaque_key->efuse_block); if (status != PSA_SUCCESS) { @@ -625,6 +632,17 @@ psa_status_t esp_ecdsa_opaque_sign_hash_complete( uint8_t zeroes[MAX_ECDSA_COMPONENT_LEN] = {0}; +#if SOC_KEY_MANAGER_SUPPORTED + esp_key_mgr_key_recovery_info_t *key_recovery_info = operation->opaque_key->key_recovery_info; + if (key_recovery_info) { + esp_err_t err = esp_key_mgr_activate_key(key_recovery_info); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to activate key: 0x%x", err); + return PSA_ERROR_INVALID_HANDLE; + } + } +#endif /* SOC_KEY_MANAGER_SUPPORTED */ + // Acquire hardware esp_ecdsa_acquire_hardware(); @@ -648,10 +666,13 @@ psa_status_t esp_ecdsa_opaque_sign_hash_complete( } #endif /* CONFIG_MBEDTLS_ECDSA_DETERMINISTIC && !SOC_ECDSA_SUPPORT_HW_DETERMINISTIC_LOOP */ +#if SOC_KEY_MANAGER_SUPPORTED // Set key source (consistent with esp_ecdsa_pk_conf_t) - if (operation->opaque_key->use_km_key) { + if (key_recovery_info) { conf.use_km_key = 1; - } else { + } else +#endif /* SOC_KEY_MANAGER_SUPPORTED */ + { conf.efuse_key_blk = operation->opaque_key->efuse_block; } @@ -683,6 +704,12 @@ psa_status_t esp_ecdsa_opaque_sign_hash_complete( esp_ecdsa_release_hardware(); +#if SOC_KEY_MANAGER_SUPPORTED + if (key_recovery_info) { + esp_key_mgr_deactivate_key(key_recovery_info->key_type); + } +#endif /* SOC_KEY_MANAGER_SUPPORTED */ + // Convert r from little-endian to big-endian and copy to output change_endianess(operation->r, signature, component_len); // Convert s from little-endian to big-endian and copy to output @@ -814,9 +841,18 @@ psa_status_t esp_ecdsa_opaque_export_public_key( .curve = opaque_key->curve, }; - if (opaque_key->use_km_key) { +#if SOC_KEY_MANAGER_SUPPORTED + esp_key_mgr_key_recovery_info_t *key_recovery_info = opaque_key->key_recovery_info; + if (key_recovery_info) { + esp_err_t err = esp_key_mgr_activate_key(key_recovery_info); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to activate key: 0x%x", err); + return PSA_ERROR_INVALID_HANDLE; + } conf.use_km_key = 1; - } else { + } else +#endif /* SOC_KEY_MANAGER_SUPPORTED */ + { conf.efuse_key_blk = opaque_key->efuse_block; } @@ -834,6 +870,12 @@ psa_status_t esp_ecdsa_opaque_export_public_key( esp_ecdsa_release_hardware(); +#if SOC_KEY_MANAGER_SUPPORTED + if (key_recovery_info) { + esp_key_mgr_deactivate_key(key_recovery_info->key_type); + } +#endif /* SOC_KEY_MANAGER_SUPPORTED */ + // Format: uncompressed point (ECDSA_UNCOMPRESSED_POINT_FORMAT byte followed by x and y coordinates) data[0] = ECDSA_UNCOMPRESSED_POINT_FORMAT; diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ecdsa_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ecdsa_contexts.h index 00c141aa99..78fe73a620 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ecdsa_contexts.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ecdsa_contexts.h @@ -11,6 +11,10 @@ #include "psa/crypto_driver_common.h" #include "sdkconfig.h" +#if SOC_KEY_MANAGER_SUPPORTED +#include "esp_key_mgr.h" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -46,8 +50,10 @@ typedef struct { #if CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN const char *tee_key_id; /**< TEE secure storage key id */ #endif - bool use_km_key; /**< Use key deployed in the key manager */ - uint8_t efuse_block; /**< eFuse block id for ECDSA private key */ +#if SOC_KEY_MANAGER_SUPPORTED + esp_key_mgr_key_recovery_info_t *key_recovery_info; /**< Pointer to the key recovery info for ECDSA key */ +#endif + uint8_t efuse_block; /**< eFuse block id for ECDSA private key e.g. EFUSE_BLK_KEY0, EFUSE_BLK_KEY1 */ } esp_ecdsa_opaque_key_t; #if !(__DOXYGEN__) // No need to document these structures, these are internal to the driver diff --git a/components/mbedtls/test_apps/main/test_psa_ecdsa.c b/components/mbedtls/test_apps/main/test_psa_ecdsa.c index d26d5f38ee..e750d739a6 100644 --- a/components/mbedtls/test_apps/main/test_psa_ecdsa.c +++ b/components/mbedtls/test_apps/main/test_psa_ecdsa.c @@ -301,7 +301,7 @@ const uint8_t k1_ecdsa192_encrypt[] = { 0xde, 0xe9, 0x9c, 0x89, 0xf2, 0x3b, 0x29, 0xb7, 0x9e, 0x33, 0xec, 0x76, 0x75, 0x2f, 0x3e, 0xab, 0x61, 0x06, 0x4d, 0xea, 0x05, 0x2c, 0xc3, 0x29, 0x1c, 0x7f, 0xb7, 0x3d, 0xb8, 0x1c, 0xb2, 0x17, }; -void test_ecdsa_sign(esp_ecdsa_curve_t curve, const uint8_t *hash, const uint8_t *pub_x, const uint8_t *pub_y, bool is_deterministic, int efuse_key_block) +void test_ecdsa_sign(esp_ecdsa_curve_t curve, const uint8_t *hash, const uint8_t *pub_x, const uint8_t *pub_y, bool is_deterministic, int efuse_key_block, void *key_recovery_info) { size_t hash_len = HASH_LEN; uint8_t signature[2 * MAX_ECDSA_COMPONENT_LEN]; @@ -331,13 +331,15 @@ void test_ecdsa_sign(esp_ecdsa_curve_t curve, const uint8_t *hash, const uint8_t psa_key_id_t priv_key_id = 0; psa_key_attributes_t priv_attr = PSA_KEY_ATTRIBUTES_INIT; - esp_ecdsa_opaque_key_t opaque_key = { - .curve = curve, - }; + esp_ecdsa_opaque_key_t opaque_key = { 0 }; + opaque_key.curve = curve; - if (efuse_key_block == USE_ECDSA_KEY_FROM_KEY_MANAGER) { - opaque_key.use_km_key = true; - } else { +#if SOC_KEY_MANAGER_SUPPORTED + if (key_recovery_info) { + opaque_key.key_recovery_info = (esp_key_mgr_key_recovery_info_t *) key_recovery_info; + } else +#endif /* SOC_KEY_MANAGER_SUPPORTED */ + { opaque_key.efuse_block = efuse_key_block; } @@ -373,7 +375,7 @@ TEST_CASE("mbedtls ECDSA signature generation on SECP256R1", "[mbedtls][efuse_ke if (!ecdsa_ll_is_supported()) { TEST_IGNORE_MESSAGE("ECDSA is not supported"); } - test_ecdsa_sign(ESP_ECDSA_CURVE_SECP256R1, sha, ecdsa256_pub_x, ecdsa256_pub_y, false, SECP256R1_EFUSE_BLOCK); + test_ecdsa_sign(ESP_ECDSA_CURVE_SECP256R1, sha, ecdsa256_pub_x, ecdsa256_pub_y, false, SECP256R1_EFUSE_BLOCK, NULL); } #ifdef SOC_ECDSA_SUPPORT_CURVE_P384 @@ -383,14 +385,14 @@ TEST_CASE("mbedtls ECDSA signature generation on SECP384R1", "[mbedtls][efuse_ke TEST_IGNORE_MESSAGE("ECDSA is not supported"); } uint8_t efuse_key_block = HAL_ECDSA_COMBINE_KEY_BLOCKS(SECP384R1_EFUSE_BLOCK_HIGH, SECP384R1_EFUSE_BLOCK_LOW); - test_ecdsa_sign(ESP_ECDSA_CURVE_SECP384R1, sha, ecdsa384_pub_x, ecdsa384_pub_y, false, efuse_key_block); + test_ecdsa_sign(ESP_ECDSA_CURVE_SECP384R1, sha, ecdsa384_pub_x, ecdsa384_pub_y, false, efuse_key_block, NULL); } #endif /* SOC_ECDSA_SUPPORT_CURVE_P384 */ #if SOC_KEY_MANAGER_SUPPORTED -static void deploy_key_in_key_manager(const uint8_t *k1_encrypted, esp_key_mgr_key_type_t key_type, esp_key_mgr_key_len_t key_len) { +static void deploy_key_in_key_manager(const uint8_t *k1_encrypted, esp_key_mgr_key_type_t key_type, esp_key_mgr_key_len_t key_len, esp_key_mgr_key_recovery_info_t *key_recovery_info) { esp_key_mgr_aes_key_config_t *key_config = NULL; key_config = heap_caps_calloc(1, sizeof(esp_key_mgr_aes_key_config_t), MALLOC_CAP_INTERNAL); TEST_ASSERT_NOT_NULL(key_config); @@ -402,16 +404,10 @@ static void deploy_key_in_key_manager(const uint8_t *k1_encrypted, esp_key_mgr_k memcpy(key_config->k1_encrypted[0], (uint8_t*) k1_encrypted, KEY_MGR_K1_ENCRYPTED_SIZE); memcpy(key_config->sw_init_key, (uint8_t*) init_key, KEY_MGR_SW_INIT_KEY_SIZE); - esp_key_mgr_key_recovery_info_t *key_info = NULL; - key_info = heap_caps_calloc(1, sizeof(esp_key_mgr_key_recovery_info_t), MALLOC_CAP_INTERNAL); - TEST_ASSERT_NOT_NULL(key_info); - - esp_key_mgr_deploy_key_in_aes_mode(key_config, key_info); + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deploy_key_in_aes_mode(key_config, key_recovery_info)); ESP_LOGI(TAG, "Key deployed successfully"); - esp_key_mgr_activate_key(key_info); - free(key_info); free(key_config); } @@ -424,9 +420,13 @@ TEST_CASE("mbedtls ECDSA signature generation on SECP256R1", "[mbedtls][key_mana TEST_IGNORE_MESSAGE("Key manager is not supported"); } - deploy_key_in_key_manager(k1_ecdsa256_encrypt, ESP_KEY_MGR_ECDSA_KEY, ESP_KEY_MGR_ECDSA_LEN_256); - test_ecdsa_sign(ESP_ECDSA_CURVE_SECP256R1, sha, ecdsa256_pub_x, ecdsa256_pub_y, false, USE_ECDSA_KEY_FROM_KEY_MANAGER); - esp_key_mgr_deactivate_key(ESP_KEY_MGR_ECDSA_KEY); + esp_key_mgr_key_recovery_info_t *key_recovery_info; + key_recovery_info = heap_caps_calloc(1, sizeof(esp_key_mgr_key_recovery_info_t), MALLOC_CAP_INTERNAL); + TEST_ASSERT_NOT_NULL(key_recovery_info); + + deploy_key_in_key_manager(k1_ecdsa256_encrypt, ESP_KEY_MGR_ECDSA_KEY, ESP_KEY_MGR_ECDSA_LEN_256, key_recovery_info); + test_ecdsa_sign(ESP_ECDSA_CURVE_SECP256R1, sha, ecdsa256_pub_x, ecdsa256_pub_y, false, USE_ECDSA_KEY_FROM_KEY_MANAGER, (void *) key_recovery_info); + free(key_recovery_info); } #endif /* SOC_KEY_MANAGER_SUPPORTED */ @@ -440,7 +440,7 @@ TEST_CASE("mbedtls ECDSA deterministic signature generation on SECP256R1", "[mbe if (!ecdsa_ll_is_deterministic_mode_supported()) { ESP_LOGI(TAG, "Skipping test because ECDSA deterministic mode is not supported."); } else { - test_ecdsa_sign(ESP_ECDSA_CURVE_SECP256R1, sha, ecdsa256_pub_x, ecdsa256_pub_y, true, SECP256R1_EFUSE_BLOCK); + test_ecdsa_sign(ESP_ECDSA_CURVE_SECP256R1, sha, ecdsa256_pub_x, ecdsa256_pub_y, true, SECP256R1_EFUSE_BLOCK, NULL); } } @@ -451,7 +451,7 @@ TEST_CASE("mbedtls ECDSA deterministic signature generation on SECP384R1", "[mbe TEST_IGNORE_MESSAGE("ECDSA is not supported"); } uint8_t efuse_key_block = HAL_ECDSA_COMBINE_KEY_BLOCKS(SECP384R1_EFUSE_BLOCK_HIGH, SECP384R1_EFUSE_BLOCK_LOW); - test_ecdsa_sign(ESP_ECDSA_CURVE_SECP384R1, sha, ecdsa384_pub_x, ecdsa384_pub_y, true, efuse_key_block); + test_ecdsa_sign(ESP_ECDSA_CURVE_SECP384R1, sha, ecdsa384_pub_x, ecdsa384_pub_y, true, efuse_key_block, NULL); } #endif /* SOC_ECDSA_SUPPORT_CURVE_P384 */ @@ -469,16 +469,20 @@ TEST_CASE("mbedtls ECDSA deterministic signature generation on SECP256R1", "[mbe if (!ecdsa_ll_is_deterministic_mode_supported()) { ESP_LOGI(TAG, "Skipping test because ECDSA deterministic mode is not supported."); } else { - deploy_key_in_key_manager(k1_ecdsa256_encrypt, ESP_KEY_MGR_ECDSA_KEY, ESP_KEY_MGR_ECDSA_LEN_256); - test_ecdsa_sign(ESP_ECDSA_CURVE_SECP256R1, sha, ecdsa256_pub_x, ecdsa256_pub_y, true, USE_ECDSA_KEY_FROM_KEY_MANAGER); - esp_key_mgr_deactivate_key(ESP_KEY_MGR_ECDSA_KEY); + esp_key_mgr_key_recovery_info_t *key_recovery_info; + key_recovery_info = heap_caps_calloc(1, sizeof(esp_key_mgr_key_recovery_info_t), MALLOC_CAP_INTERNAL); + TEST_ASSERT_NOT_NULL(key_recovery_info); + + deploy_key_in_key_manager(k1_ecdsa256_encrypt, ESP_KEY_MGR_ECDSA_KEY, ESP_KEY_MGR_ECDSA_LEN_256, key_recovery_info); + test_ecdsa_sign(ESP_ECDSA_CURVE_SECP256R1, sha, ecdsa256_pub_x, ecdsa256_pub_y, true, USE_ECDSA_KEY_FROM_KEY_MANAGER, (void *) key_recovery_info); + free(key_recovery_info); } } #endif /* SOC_KEY_MANAGER_SUPPORTED */ #endif /* SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE */ #ifdef SOC_ECDSA_SUPPORT_EXPORT_PUBKEY -void test_ecdsa_export_pubkey(esp_ecdsa_curve_t curve, const uint8_t *pub_x, const uint8_t *pub_y, int efuse_key_block) +void test_ecdsa_export_pubkey(esp_ecdsa_curve_t curve, const uint8_t *pub_x, const uint8_t *pub_y, int efuse_key_block, void *key_recovery_info) { uint8_t export_pub_key[1 + 2 * MAX_ECDSA_COMPONENT_LEN] = {0}; size_t len = 0; @@ -486,9 +490,8 @@ void test_ecdsa_export_pubkey(esp_ecdsa_curve_t curve, const uint8_t *pub_x, con psa_key_id_t priv_key_id = 0; psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; - esp_ecdsa_opaque_key_t opaque_key = { - .curve = curve, - }; + esp_ecdsa_opaque_key_t opaque_key = { 0 }; + opaque_key.curve = curve; size_t plen = 0; psa_algorithm_t sha_alg = 0; @@ -510,9 +513,12 @@ void test_ecdsa_export_pubkey(esp_ecdsa_curve_t curve, const uint8_t *pub_x, con } size_t plen_bytes = plen / 8; - if (efuse_key_block == USE_ECDSA_KEY_FROM_KEY_MANAGER) { - opaque_key.use_km_key = true; - } else { +#if SOC_KEY_MANAGER_SUPPORTED + if (key_recovery_info) { + opaque_key.key_recovery_info = (esp_key_mgr_key_recovery_info_t *) key_recovery_info; + } else +#endif + { opaque_key.efuse_block = efuse_key_block; } // Set attributes for opaque private key @@ -545,7 +551,7 @@ TEST_CASE("mbedtls ECDSA export public key on SECP256R1", "[mbedtls][efuse_key]" if (!ecdsa_ll_is_supported()) { TEST_IGNORE_MESSAGE("ECDSA is not supported"); } - test_ecdsa_export_pubkey(ESP_ECDSA_CURVE_SECP256R1, ecdsa256_pub_x, ecdsa256_pub_y, SECP256R1_EFUSE_BLOCK); + test_ecdsa_export_pubkey(ESP_ECDSA_CURVE_SECP256R1, ecdsa256_pub_x, ecdsa256_pub_y, SECP256R1_EFUSE_BLOCK, NULL); } #ifdef SOC_ECDSA_SUPPORT_CURVE_P384 @@ -555,7 +561,7 @@ TEST_CASE("mbedtls ECDSA export public key on SECP384R1", "[mbedtls][efuse_key]" TEST_IGNORE_MESSAGE("ECDSA is not supported"); } uint8_t efuse_key_block = HAL_ECDSA_COMBINE_KEY_BLOCKS(SECP384R1_EFUSE_BLOCK_HIGH, SECP384R1_EFUSE_BLOCK_LOW); - test_ecdsa_export_pubkey(ESP_ECDSA_CURVE_SECP384R1, ecdsa384_pub_x, ecdsa384_pub_y, efuse_key_block); + test_ecdsa_export_pubkey(ESP_ECDSA_CURVE_SECP384R1, ecdsa384_pub_x, ecdsa384_pub_y, efuse_key_block, NULL); } #endif /* SOC_ECDSA_SUPPORT_CURVE_P384 */ @@ -570,9 +576,13 @@ TEST_CASE("mbedtls ECDSA export public key on SECP256R1", "[mbedtls][key_manager TEST_IGNORE_MESSAGE("Key manager is not supported"); } - deploy_key_in_key_manager(k1_ecdsa256_encrypt, ESP_KEY_MGR_ECDSA_KEY, ESP_KEY_MGR_ECDSA_LEN_256); - test_ecdsa_export_pubkey(ESP_ECDSA_CURVE_SECP256R1, ecdsa256_pub_x, ecdsa256_pub_y, USE_ECDSA_KEY_FROM_KEY_MANAGER); - esp_key_mgr_deactivate_key(ESP_KEY_MGR_ECDSA_KEY); + esp_key_mgr_key_recovery_info_t *key_recovery_info; + key_recovery_info = heap_caps_calloc(1, sizeof(esp_key_mgr_key_recovery_info_t), MALLOC_CAP_INTERNAL); + TEST_ASSERT_NOT_NULL(key_recovery_info); + + deploy_key_in_key_manager(k1_ecdsa256_encrypt, ESP_KEY_MGR_ECDSA_KEY, ESP_KEY_MGR_ECDSA_LEN_256, key_recovery_info); + test_ecdsa_export_pubkey(ESP_ECDSA_CURVE_SECP256R1, ecdsa256_pub_x, ecdsa256_pub_y, USE_ECDSA_KEY_FROM_KEY_MANAGER, (void *) key_recovery_info); + free(key_recovery_info); } #endif From 803601795107bb4300aab341874af8cdd399220f Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Wed, 18 Feb 2026 17:24:08 +0530 Subject: [PATCH 2/3] feat(mbedtls/esp_mac): Support Key Manager key using the ESP-HMAC PSA interface --- .../tee_sec_storage/tee_sec_storage.c | 4 ++- components/mbedtls/port/esp_hmac_pbkdf2.c | 5 ++- .../psa_crypto_driver_esp_hmac_opaque.c | 31 ++++++++++++++++--- ...a_crypto_driver_esp_hmac_opaque_contexts.h | 10 ++++-- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c b/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c index a56a5e64af..f0f3742bf4 100644 --- a/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c +++ b/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c @@ -156,7 +156,9 @@ static esp_err_t compute_nvs_keys_with_hmac(esp_efuse_block_t key_blk, nvs_sec_c // Create opaque key reference esp_hmac_opaque_key_t opaque_key = { - .use_km_key = false, +#if SOC_KEY_MANAGER_SUPPORTED + .key_recovery_info = NULL, +#endif /* SOC_KEY_MANAGER_SUPPORTED */ .efuse_key_id = hmac_key_id, }; diff --git a/components/mbedtls/port/esp_hmac_pbkdf2.c b/components/mbedtls/port/esp_hmac_pbkdf2.c index de8467c9cb..796dbf2c1d 100644 --- a/components/mbedtls/port/esp_hmac_pbkdf2.c +++ b/components/mbedtls/port/esp_hmac_pbkdf2.c @@ -52,7 +52,10 @@ esp_err_t esp_hmac_derive_pbkdf2_key(hmac_key_id_t key_id, const uint8_t *salt, // Create opaque key reference esp_hmac_opaque_key_t opaque_key = { - .use_km_key = false, + // TODO: Support key recovery info for HMAC key in PBKDF2 after PSA migration of this API is done +#if SOC_KEY_MANAGER_SUPPORTED + .key_recovery_info = NULL, +#endif /* SOC_KEY_MANAGER_SUPPORTED */ .efuse_key_id = key_id, }; diff --git a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c index 2a9fb607ec..0c54eb8689 100644 --- a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c +++ b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c @@ -13,9 +13,19 @@ #include "hal/hmac_types.h" #include "esp_hmac.h" +#if SOC_KEY_MANAGER_SUPPORTED +#include "esp_key_mgr.h" +#endif /* SOC_KEY_MANAGER_SUPPORTED */ + static bool validate_hmac_opaque_key_attributes(const esp_hmac_opaque_key_t *opaque_key) { - // efuse_key_id is uint8_t, so it's always >= 0 (EFUSE_BLK0) +#if SOC_KEY_MANAGER_SUPPORTED + if (opaque_key->key_recovery_info) { + return true; + } +#endif /* SOC_KEY_MANAGER_SUPPORTED */ + + // efuse_key_id is uint8_t, so opaque_key->efuse_key_id + EFUSE_BLK_KEY0 >= EFUSE_BLK_KEY0 if (((opaque_key->efuse_key_id + EFUSE_BLK_KEY0) < EFUSE_BLK_KEY_MAX) && (esp_efuse_get_key_purpose(EFUSE_BLK_KEY0 + opaque_key->efuse_key_id) == ESP_EFUSE_KEY_PURPOSE_HMAC_UP)) { return true; @@ -106,13 +116,26 @@ psa_status_t esp_hmac_update_opaque(esp_hmac_opaque_operation_t *esp_hmac_ctx, c hmac_key_id_t hmac_key_id = esp_hmac_ctx->opaque_key->efuse_key_id; -#if SOC_KEY_MANAGER_HMAC_KEY_DEPLOY - if (esp_hmac_ctx->opaque_key->use_km_key) { +#if SOC_KEY_MANAGER_SUPPORTED && !ESP_TEE_BUILD + esp_key_mgr_key_recovery_info_t *key_recovery_info = esp_hmac_ctx->opaque_key->key_recovery_info; + if (key_recovery_info) { + esp_err_t err = esp_key_mgr_activate_key(key_recovery_info); + if (err != ESP_OK) { + ESP_LOGE("ESP_HMAC_OPAQUE", "Failed to activate key: 0x%x", err); + return PSA_ERROR_INVALID_HANDLE; + } hmac_key_id = HMAC_KEY_KM; } -#endif /* SOC_KEY_MANAGER_HMAC_KEY_DEPLOY */ +#endif /* SOC_KEY_MANAGER_SUPPORTED && !ESP_TEE_BUILD */ esp_err_t hmac_ret = esp_hmac_calculate(hmac_key_id, data, data_length, esp_hmac_ctx->hmac); + +#if SOC_KEY_MANAGER_SUPPORTED && !ESP_TEE_BUILD + if (key_recovery_info) { + esp_key_mgr_deactivate_key(key_recovery_info->key_type); + } +#endif /* SOC_KEY_MANAGER_SUPPORTED && !ESP_TEE_BUILD */ + if (hmac_ret == ESP_ERR_INVALID_ARG) { return PSA_ERROR_INVALID_ARGUMENT; } else if (hmac_ret == ESP_FAIL) { diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque_contexts.h index a2a372bbfb..1bad31ff37 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque_contexts.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque_contexts.h @@ -11,6 +11,10 @@ #include "psa/crypto_driver_common.h" #include "hal/hmac_types.h" +#if SOC_KEY_MANAGER_SUPPORTED +#include "esp_key_mgr.h" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -24,8 +28,10 @@ extern "C" { * @brief Structure to store opaque HMAC key. */ typedef struct { - bool use_km_key; /**< Use key deployed in the key manager */ - hmac_key_id_t efuse_key_id; /**< eFuse key block id for HMAC key */ + uint8_t efuse_key_id; /**< eFuse key block id for HMAC key */ +#if SOC_KEY_MANAGER_SUPPORTED + esp_key_mgr_key_recovery_info_t *key_recovery_info; /**< Pointer to the key recovery info for HMAC key */ +#endif /* SOC_KEY_MANAGER_SUPPORTED */ } esp_hmac_opaque_key_t; /** From a1bbab43fe60e94a26ff321b9819565df7a1a9f7 Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Tue, 3 Mar 2026 13:27:22 +0530 Subject: [PATCH 3/3] feat(mbedtls/esp_rsa_ds): Support Key Manager key using the ESP-RSA-DS PSA interface --- .../esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c | 140 ++++++++++++++---- .../psa_crypto_driver_esp_rsa_ds_contexts.h | 11 ++ 2 files changed, 122 insertions(+), 29 deletions(-) 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 1855be1d39..476cd5241c 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 @@ -17,6 +17,10 @@ #include "esp_efuse.h" #include "soc/soc_caps.h" +#if SOC_KEY_MANAGER_SUPPORTED +#include "esp_key_mgr.h" +#endif /* SOC_KEY_MANAGER_SUPPORTED */ + #define ESP_RSA_DS_TIMEOUT_BUFFER_MS 1000 static const char *TAG = "PSA_RSA_DS"; @@ -79,10 +83,6 @@ static int esp_rsa_ds_validate_opaque_key(const esp_rsa_ds_opaque_key_t *opaque_ return PSA_ERROR_INVALID_ARGUMENT; } - if ((opaque_key->ds_data_ctx->efuse_key_id + EFUSE_BLK_KEY0) >= EFUSE_BLK_KEY_MAX) { - return PSA_ERROR_INVALID_ARGUMENT; - } - if (opaque_key->ds_data_ctx->rsa_length_bits % 32 != 0) { return PSA_ERROR_INVALID_ARGUMENT; } @@ -96,10 +96,21 @@ static int esp_rsa_ds_validate_opaque_key(const esp_rsa_ds_opaque_key_t *opaque_ return PSA_ERROR_INVALID_ARGUMENT; } - esp_efuse_purpose_t purpose = esp_efuse_get_key_purpose(EFUSE_BLK_KEY0 + opaque_key->ds_data_ctx->efuse_key_id); - if (purpose != ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE) { - return PSA_ERROR_NOT_PERMITTED; +#if SOC_KEY_MANAGER_SUPPORTED + if (!opaque_key->key_recovery_info) { +#endif /* SOC_KEY_MANAGER_SUPPORTED */ + if ((opaque_key->ds_data_ctx->efuse_key_id + EFUSE_BLK_KEY0) >= EFUSE_BLK_KEY_MAX) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + esp_efuse_purpose_t purpose = esp_efuse_get_key_purpose(EFUSE_BLK_KEY0 + opaque_key->ds_data_ctx->efuse_key_id); + if (purpose != ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE) { + return PSA_ERROR_NOT_PERMITTED; + } +#if SOC_KEY_MANAGER_SUPPORTED } +#endif /* SOC_KEY_MANAGER_SUPPORTED */ + return PSA_SUCCESS; } @@ -112,6 +123,8 @@ psa_status_t esp_rsa_ds_opaque_sign_hash_start( const uint8_t *hash, size_t hash_length) { + esp_err_t err = ESP_FAIL; + if (!attributes || !key_buffer || !hash || !operation) { return PSA_ERROR_INVALID_ARGUMENT; } @@ -175,10 +188,26 @@ psa_status_t esp_rsa_ds_opaque_sign_hash_start( sig_words[i] = SWAP_INT32(em_words[words_len - (i + 1)]); } - esp_err_t err = esp_ds_start_sign((const void *)operation->sig_buffer, - opaque_key->ds_data_ctx->esp_ds_data, - opaque_key->ds_data_ctx->efuse_key_id, - &operation->esp_rsa_ds_ctx); + hmac_key_id_t hmac_key_id = opaque_key->ds_data_ctx->efuse_key_id; + +#if SOC_KEY_MANAGER_SUPPORTED + esp_key_mgr_key_recovery_info_t *km_key_recovery_info = operation->esp_rsa_ds_opaque_key->key_recovery_info; + if (km_key_recovery_info) { + err = esp_key_mgr_activate_key(km_key_recovery_info); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to activate key: 0x%x", err); + status = PSA_ERROR_INVALID_HANDLE; + goto error; + } + hmac_key_id = HMAC_KEY_KM; + operation->is_km_key_active = true; + } +#endif /* SOC_KEY_MANAGER_SUPPORTED */ + + err = esp_ds_start_sign((const void *)operation->sig_buffer, + opaque_key->ds_data_ctx->esp_ds_data, + hmac_key_id, + &operation->esp_rsa_ds_ctx); if (err != ESP_OK) { status = PSA_ERROR_GENERIC_ERROR; goto error; @@ -189,13 +218,7 @@ error: 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; } @@ -204,6 +227,10 @@ psa_status_t esp_rsa_ds_opaque_sign_hash_complete( uint8_t *signature, size_t signature_size, size_t *signature_length) { + if (!operation) { + return PSA_ERROR_INVALID_ARGUMENT; + } + if (!signature || !signature_length || !operation) { return PSA_ERROR_INVALID_ARGUMENT; } @@ -218,10 +245,8 @@ psa_status_t esp_rsa_ds_opaque_sign_hash_complete( } esp_err_t err = esp_ds_finish_sign((void *)operation->sig_buffer, operation->esp_rsa_ds_ctx); + operation->esp_rsa_ds_ctx = NULL; if (err != ESP_OK) { - memset(operation->sig_buffer, 0, operation->sig_buffer_size); - heap_caps_free(operation->sig_buffer); - esp_rsa_ds_release_ds_lock(); return PSA_ERROR_GENERIC_ERROR; } @@ -233,10 +258,15 @@ 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(); + + if (operation->sig_buffer) { + memset(operation->sig_buffer, 0, operation->sig_buffer_size); + heap_caps_free(operation->sig_buffer); + operation->sig_buffer = NULL; + } + return PSA_SUCCESS; } @@ -247,6 +277,24 @@ psa_status_t esp_rsa_ds_opaque_sign_hash_abort( return PSA_ERROR_INVALID_ARGUMENT; } + if (operation->esp_rsa_ds_opaque_key) { +#if SOC_KEY_MANAGER_SUPPORTED + esp_key_mgr_key_recovery_info_t *km_key_recovery_info = operation->esp_rsa_ds_opaque_key->key_recovery_info; + if (km_key_recovery_info && operation->is_km_key_active) { + esp_key_mgr_deactivate_key(km_key_recovery_info->key_type); + operation->is_km_key_active = false; + } +#endif /* SOC_KEY_MANAGER_SUPPORTED */ + operation->esp_rsa_ds_opaque_key = NULL; + } + + if (operation->esp_rsa_ds_ctx) { +#if !ESP_TEE_BUILD + free(operation->esp_rsa_ds_ctx); +#endif + operation->esp_rsa_ds_ctx = NULL; + } + // Free allocated memory if exists if (operation->sig_buffer) { memset(operation->sig_buffer, 0, operation->sig_buffer_size); @@ -310,7 +358,7 @@ psa_status_t esp_rsa_ds_opaque_import_key( size_t *key_buffer_length, size_t *bits) { - if (!attributes || !data || data_length < 1 || !key_buffer || !key_buffer_length || !bits) { + if (!attributes || !data || data_length < sizeof(esp_rsa_ds_opaque_key_t) || !key_buffer || !key_buffer_length || !bits) { return PSA_ERROR_INVALID_ARGUMENT; } @@ -365,6 +413,9 @@ psa_status_t esp_rsa_ds_opaque_asymmetric_decrypt( { (void)salt; (void)salt_length; + + esp_err_t err = ESP_FAIL; + if (!attributes || !key || key_length < sizeof(esp_rsa_ds_opaque_key_t) || !input || input_length < 1 || !output || !output_length) { return PSA_ERROR_INVALID_ARGUMENT; @@ -413,17 +464,47 @@ psa_status_t esp_rsa_ds_opaque_asymmetric_decrypt( 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->ds_data_ctx->esp_ds_data, - opaque_key->ds_data_ctx->efuse_key_id, - &operation.esp_rsa_ds_ctx); + hmac_key_id_t hmac_key_id = opaque_key->ds_data_ctx->efuse_key_id; +#if SOC_KEY_MANAGER_SUPPORTED + esp_key_mgr_key_recovery_info_t *km_key_recovery_info = opaque_key->key_recovery_info; + if (km_key_recovery_info) { + err = esp_key_mgr_activate_key(km_key_recovery_info); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to activate key: 0x%x", err); + heap_caps_free(em_words); + esp_rsa_ds_release_ds_lock(); + return PSA_ERROR_INVALID_HANDLE; + } + hmac_key_id = HMAC_KEY_KM; + operation.is_km_key_active = true; + } +#endif /* SOC_KEY_MANAGER_SUPPORTED */ + + err = esp_ds_start_sign((const void *)em_words, + opaque_key->ds_data_ctx->esp_ds_data, + hmac_key_id, + &operation.esp_rsa_ds_ctx); if (err != ESP_OK) { heap_caps_free(em_words); +#if SOC_KEY_MANAGER_SUPPORTED + if (km_key_recovery_info && operation.is_km_key_active) { + esp_key_mgr_deactivate_key(km_key_recovery_info->key_type); + operation.is_km_key_active = false; + } +#endif /* SOC_KEY_MANAGER_SUPPORTED */ esp_rsa_ds_release_ds_lock(); return PSA_ERROR_GENERIC_ERROR; } err = esp_ds_finish_sign((void *)em_words, operation.esp_rsa_ds_ctx); + +#if SOC_KEY_MANAGER_SUPPORTED + if (km_key_recovery_info && operation.is_km_key_active) { + esp_key_mgr_deactivate_key(km_key_recovery_info->key_type); + operation.is_km_key_active = false; + } +#endif /* SOC_KEY_MANAGER_SUPPORTED */ + if (err != ESP_OK) { heap_caps_free(em_words); esp_rsa_ds_release_ds_lock(); @@ -435,6 +516,7 @@ psa_status_t esp_rsa_ds_opaque_asymmetric_decrypt( // 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) { + memset(em_words, 0, sizeof(uint32_t) * data_len); heap_caps_free(em_words); return PSA_ERROR_INSUFFICIENT_MEMORY; } 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 72184f71b3..0886f4e1f7 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 @@ -12,6 +12,11 @@ #include "esp_ds.h" #include "hal/hmac_types.h" +#include "soc/soc_caps.h" +#if SOC_KEY_MANAGER_SUPPORTED +#include "esp_key_mgr.h" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -42,12 +47,18 @@ typedef struct { typedef struct { esp_ds_data_ctx_t *ds_data_ctx; +#if SOC_KEY_MANAGER_SUPPORTED + esp_key_mgr_key_recovery_info_t *key_recovery_info; /**< Pointer to the key recovery info for DS key */ +#endif /* SOC_KEY_MANAGER_SUPPORTED */ } esp_rsa_ds_opaque_key_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_rsa_ds_opaque_key_t *esp_rsa_ds_opaque_key; /**< Pointer to the esp ds opaque key */ +#if SOC_KEY_MANAGER_SUPPORTED + bool is_km_key_active; /**< Flag indicating if the Key Manager key is active for this operation */ +#endif /* SOC_KEY_MANAGER_SUPPORTED */ 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 */