From 427dc875b92418939c31fe1f4d8f2b7de239d475 Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Fri, 3 Jul 2026 17:19:17 +0530 Subject: [PATCH] change(esp_tee): Force non-deterministic ECDSA signing for TEE secure storage keys --- .../tee_sec_storage/tee_sec_storage.c | 6 +-- .../tee_test_fw/main/test_esp_tee_sec_stg.c | 52 +++++++++++++------ .../mbedtls/esp_tee/esp_tee_mbedtls_config.h | 6 +-- .../esp_ecdsa/psa_crypto_driver_esp_ecdsa.c | 4 ++ 4 files changed, 45 insertions(+), 23 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 db22b85a970..6136b79591a 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 @@ -575,11 +575,9 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign(const esp_tee_sec_storage_key_cfg_t *cf psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_VERIFY_HASH); - psa_algorithm_t ecdsa_alg = PSA_ALG_ECDSA(PSA_ALG_SHA_256); -#if CONFIG_MBEDTLS_ECDSA_DETERMINISTIC - ecdsa_alg = PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256); -#endif + /* ECDSA signatures over TEE secure-storage keys are compulsorily non-deterministic */ + psa_algorithm_t ecdsa_alg = PSA_ALG_ECDSA(PSA_ALG_SHA_256); psa_set_key_algorithm(&key_attributes, ecdsa_alg); diff --git a/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_sec_stg.c b/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_sec_stg.c index 55dd7ff4b7e..b4a0820e635 100644 --- a/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_sec_stg.c +++ b/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_sec_stg.c @@ -145,6 +145,43 @@ TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp256r1)", "[sec_stora } } +TEST_CASE("Test TEE Secure Storage - Signatures are non-deterministic (ecdsa_secp256r1)", "[sec_storage]") +{ + const size_t sig_len = 2 * ECDSA_SECP256R1_KEY_LEN; + + uint8_t msg_digest[SHA256_DIGEST_SZ]; + esp_fill_random(msg_digest, sizeof(msg_digest)); + + esp_tee_sec_storage_key_cfg_t key_cfg = { + .id = "ecdsa_nondet", + .type = ESP_SEC_STG_KEY_ECDSA_SECP256R1 + }; + + esp_err_t err = esp_tee_sec_storage_clear_key(key_cfg.id); + TEST_ASSERT_TRUE(err == ESP_OK || err == ESP_ERR_NOT_FOUND); + TEST_ESP_OK(esp_tee_sec_storage_gen_key(&key_cfg)); + + esp_tee_sec_storage_ecdsa_pubkey_t pubkey = {}; + TEST_ESP_OK(esp_tee_sec_storage_ecdsa_get_pubkey(&key_cfg, &pubkey)); + + uint8_t signatures[MAX_SEC_STG_ITER][2 * ECDSA_SECP256R1_KEY_LEN]; + + for (unsigned int i = 0; i < MAX_SEC_STG_ITER; i++) { + esp_tee_sec_storage_ecdsa_sign_t sign = {}; + TEST_ESP_OK(esp_tee_sec_storage_ecdsa_sign(&key_cfg, msg_digest, sizeof(msg_digest), &sign)); + + TEST_ESP_OK(verify_ecdsa_sign(key_cfg.type, msg_digest, sizeof(msg_digest), &pubkey, &sign)); + + for (unsigned int j = 0; j < i; j++) { + TEST_ASSERT_TRUE_MESSAGE(memcmp(sign.signature, signatures[j], sig_len) != 0, + "ECDSA signature repeated - deterministic signing detected"); + } + memcpy(signatures[i], sign.signature, sig_len); + } + + TEST_ESP_OK(esp_tee_sec_storage_clear_key(key_cfg.id)); +} + #if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp384r1)", "[sec_storage]") { @@ -686,21 +723,6 @@ static void test_ecdsa_sign(esp_ecdsa_curve_t curve) TEST_ASSERT_EQUAL_HEX32(PSA_SUCCESS, status); TEST_ASSERT_EQUAL(signature_len, 2 * key_len); -#if CONFIG_MBEDTLS_ECDSA_DETERMINISTIC - uint8_t signature_det_verify[2 * ECDSA_SECP384R1_KEY_LEN]; - size_t signature_det_verify_len = 0; - - status = psa_sign_hash(priv_key_id, - alg, - sha, sha_len, - signature_det_verify, 2 * key_len, - &signature_det_verify_len); - - TEST_ASSERT_EQUAL_HEX32(PSA_SUCCESS, status); - TEST_ASSERT_EQUAL(signature_det_verify_len, signature_len); - TEST_ASSERT_EQUAL_HEX8_ARRAY(signature, signature_det_verify, signature_len); -#endif - psa_set_key_type(&pub_key_attr, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)); psa_set_key_bits(&pub_key_attr, key_len * 8); psa_set_key_usage_flags(&pub_key_attr, PSA_KEY_USAGE_VERIFY_HASH); diff --git a/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h b/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h index 2dc04dbd550..3ba1e1c44e6 100644 --- a/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h +++ b/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h @@ -61,12 +61,10 @@ #endif #define PSA_WANT_ECC_SECP_R1_256 1 -#ifdef CONFIG_MBEDTLS_ECDSA_DETERMINISTIC -#define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1 -#else +/* ECDSA signatures over TEE secure-storage keys are compulsorily + * non-deterministic (randomized nonce) */ #undef PSA_WANT_ALG_DETERMINISTIC_ECDSA #undef MBEDTLS_HMAC_DRBG_C -#endif #if SOC_SHA_SUPPORTED #define ESP_SHA_DRIVER_ENABLED 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 44ab52e60bf..f7900c277c9 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 @@ -1003,6 +1003,10 @@ psa_status_t esp_ecdsa_opaque_sign_hash_complete( #if CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN if (key_source == ESP_ECDSA_KEY_SOURCE_TEE) { /* TEE key path */ + if (PSA_ALG_ECDSA_IS_DETERMINISTIC(operation->alg)) { + ESP_LOGW(TAG, "Deterministic ECDSA unsupported for TEE keys; using randomized nonce"); + } + const char *tee_key_id = NULL; uint8_t stored_curve;