From 8ce8d8919bb2c58e805ff6b3b0b813b0d033de34 Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Thu, 23 Apr 2026 09:53:44 +0530 Subject: [PATCH] fix(esp_security): Enable ECC clock while using the Key Manager's ECDH key deployment mode --- .../test_apps/crypto/main/CMakeLists.txt | 1 + .../crypto/main/key_manager/km_ecdh0_verify.c | 180 ++++++++++++++++++ .../crypto/main/key_manager/km_ecdh0_verify.h | 63 ++++++ .../main/key_manager/test_key_manager.c | 126 ++++++++++-- components/esp_security/src/esp_key_mgr.c | 9 + 5 files changed, 363 insertions(+), 16 deletions(-) create mode 100644 components/esp_hal_security/test_apps/crypto/main/key_manager/km_ecdh0_verify.c create mode 100644 components/esp_hal_security/test_apps/crypto/main/key_manager/km_ecdh0_verify.h diff --git a/components/esp_hal_security/test_apps/crypto/main/CMakeLists.txt b/components/esp_hal_security/test_apps/crypto/main/CMakeLists.txt index be2f094f423..438d5ca3c22 100644 --- a/components/esp_hal_security/test_apps/crypto/main/CMakeLists.txt +++ b/components/esp_hal_security/test_apps/crypto/main/CMakeLists.txt @@ -23,6 +23,7 @@ endif() if(CONFIG_CRYPTO_IS_KEY_MANAGER_SUPPORTED) list(APPEND srcs "key_manager/test_key_manager.c" + "key_manager/km_ecdh0_verify.c" "$ENV{IDF_PATH}/components/esp_security/src/esp_key_mgr.c") list(APPEND priv_include_dirs "$ENV{IDF_PATH}/components/esp_security/include") endif() diff --git a/components/esp_hal_security/test_apps/crypto/main/key_manager/km_ecdh0_verify.c b/components/esp_hal_security/test_apps/crypto/main/key_manager/km_ecdh0_verify.c new file mode 100644 index 00000000000..aa3db1870ac --- /dev/null +++ b/components/esp_hal_security/test_apps/crypto/main/key_manager/km_ecdh0_verify.c @@ -0,0 +1,180 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS + +#include +#include + +#include "esp_log.h" +#include "unity.h" + +#include "ecc_impl.h" +#include "psa/crypto.h" + +#include "mbedtls/private/aes.h" +#include "mbedtls/ecp.h" +#include "mbedtls/bignum.h" + +#include "km_ecdh0_verify.h" + +/* P-192 generator hardcoded in esp_ecc's little-endian layout. We don't pull + * P-192 from mbedtls because support for ECDSA P-192 is disabled by default in mbedtls. + * P-256 and P-384 are loaded from mbedtls at use time -- see load_curve_generator_le below. */ +static const uint8_t p192_G_x_le[P192_LEN] = { + 0x12, 0x10, 0xff, 0x82, 0xfd, 0x0a, 0xff, 0xf4, 0x00, 0x88, 0xa1, 0x43, + 0xeb, 0x20, 0xbf, 0x7c, 0xf6, 0x90, 0x30, 0xb0, 0x0e, 0xa8, 0x8d, 0x18, +}; +static const uint8_t p192_G_y_le[P192_LEN] = { + 0x11, 0x48, 0x79, 0x1e, 0xa1, 0x77, 0xf9, 0x73, 0xd5, 0xcd, 0x24, 0x6b, + 0xed, 0x11, 0x10, 0x63, 0x78, 0xda, 0xc8, 0xff, 0x95, 0x2b, 0x19, 0x07, +}; + +static void load_curve_generator_le(mbedtls_ecp_group_id grp_id, + uint8_t *gx_le, uint8_t *gy_le, + size_t coord_len) +{ + mbedtls_ecp_group grp; + mbedtls_ecp_group_init(&grp); + TEST_ASSERT_EQUAL(0, mbedtls_ecp_group_load(&grp, grp_id)); + + /* mbedtls_ecp_point_write_binary in uncompressed form gives + * 0x04 || X_BE || Y_BE. Reverse each coord into the LE byte order + * esp_ecc expects. */ + uint8_t buf[1 + 2 * P384_LEN]; + size_t olen = 0; + TEST_ASSERT_EQUAL(0, mbedtls_ecp_point_write_binary(&grp, &grp.G, + MBEDTLS_ECP_PF_UNCOMPRESSED, + &olen, buf, sizeof(buf))); + TEST_ASSERT_EQUAL(1 + 2 * coord_len, olen); + for (size_t i = 0; i < coord_len; ++i) { + gx_le[i] = buf[1 + coord_len - 1 - i]; + gy_le[i] = buf[1 + 2 * coord_len - 1 - i]; + } + + mbedtls_ecp_group_free(&grp); +} + +void km_verify_compute_x_be(const uint8_t *k1_be, size_t k1_len, + const uint8_t *k2_G_km, uint8_t x_be_out[32]) +{ + uint8_t k1_le[P256_LEN] = { 0 }; + TEST_ASSERT_LESS_OR_EQUAL(P256_LEN, k1_len); + for (size_t i = 0; i < k1_len; ++i) { + k1_le[i] = k1_be[k1_len - 1 - i]; + } + + ecc_point_t k2_G = { .len = P256_LEN }; + memcpy(k2_G.x, k2_G_km, P256_LEN); + memcpy(k2_G.y, k2_G_km + P256_LEN, P256_LEN); + + ecc_point_t result = { 0 }; + TEST_ASSERT_EQUAL(0, esp_ecc_point_multiply(&k2_G, k1_le, &result, true)); + + for (int i = 0; i < P256_LEN; ++i) { + x_be_out[i] = result.x[P256_LEN - 1 - i]; + } +} + +void km_verify_ecdsa_pubkey_from_scalar(unsigned curve_len, + const uint8_t *scalar_be, + size_t scalar_len, + uint8_t *pub_x_le_out, + uint8_t *pub_y_le_out) +{ + uint8_t scalar_le[P384_LEN] = { 0 }; + TEST_ASSERT_LESS_OR_EQUAL(curve_len, scalar_len); + for (size_t i = 0; i < scalar_len; ++i) { + scalar_le[i] = scalar_be[scalar_len - 1 - i]; + } + + ecc_point_t G = { .len = curve_len }; + switch (curve_len) { + case P192_LEN: + memcpy(G.x, p192_G_x_le, P192_LEN); + memcpy(G.y, p192_G_y_le, P192_LEN); + break; + case P256_LEN: + load_curve_generator_le(MBEDTLS_ECP_DP_SECP256R1, G.x, G.y, P256_LEN); + break; +#if SOC_ECC_SUPPORT_CURVE_P384 + case P384_LEN: + load_curve_generator_le(MBEDTLS_ECP_DP_SECP384R1, G.x, G.y, P384_LEN); + break; +#endif + default: + TEST_FAIL_MESSAGE("Unsupported curve length for ECDSA pubkey reconstruction"); + } + + ecc_point_t pub = { 0 }; + /* G is always a valid curve point, so verify_first=false. */ + TEST_ASSERT_EQUAL(0, esp_ecc_point_multiply(&G, scalar_le, &pub, false)); + + memcpy(pub_x_le_out, pub.x, curve_len); + memcpy(pub_y_le_out, pub.y, curve_len); +} + +void km_verify_flash_xts_encrypt(const uint8_t *key, size_t key_bits, + uint32_t flash_address, + const uint8_t *pt, size_t pt_len, + uint8_t *ct_out) +{ + TEST_ASSERT_LESS_OR_EQUAL(128, pt_len); + TEST_ASSERT_EQUAL(0, flash_address & 0x7F); + + mbedtls_aes_xts_context ctx; + mbedtls_aes_xts_init(&ctx); + TEST_ASSERT_EQUAL(0, mbedtls_aes_xts_setkey_enc(&ctx, key, key_bits)); + + uint8_t block_in[128] = { 0 }; + uint8_t block_rev[128] = { 0 }; + uint8_t block_cipher_rev[128]; + uint8_t block_cipher[128]; + memcpy(block_in, pt, pt_len); + for (int i = 0; i < 128; ++i) { + block_rev[i] = block_in[127 - i]; + } + + uint8_t data_unit[16] = { 0 }; + uint32_t tweak_addr = flash_address & ~0x7FU; + data_unit[0] = (uint8_t)(tweak_addr); + data_unit[1] = (uint8_t)(tweak_addr >> 8); + data_unit[2] = (uint8_t)(tweak_addr >> 16); + data_unit[3] = (uint8_t)(tweak_addr >> 24); + + TEST_ASSERT_EQUAL(0, mbedtls_aes_crypt_xts(&ctx, MBEDTLS_AES_ENCRYPT, 128, + data_unit, block_rev, block_cipher_rev)); + for (int i = 0; i < 128; ++i) { + block_cipher[i] = block_cipher_rev[127 - i]; + } + memcpy(ct_out, block_cipher, pt_len); + + mbedtls_aes_xts_free(&ctx); +} + +void km_verify_hmac_sha256(const uint8_t *key, size_t key_len, + const uint8_t *msg, size_t msg_len, + uint8_t mac_out[32]) +{ + psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_SIGN_MESSAGE); + psa_set_key_algorithm(&attr, PSA_ALG_HMAC(PSA_ALG_SHA_256)); + psa_set_key_type(&attr, PSA_KEY_TYPE_HMAC); + psa_set_key_bits(&attr, key_len * 8); + + psa_key_id_t key_id = 0; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attr, key, key_len, &key_id)); + + size_t mac_len = 0; + psa_status_t status = psa_mac_compute(key_id, + PSA_ALG_HMAC(PSA_ALG_SHA_256), + msg, msg_len, + mac_out, 32, &mac_len); + psa_destroy_key(key_id); + + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + TEST_ASSERT_EQUAL(32, mac_len); +} diff --git a/components/esp_hal_security/test_apps/crypto/main/key_manager/km_ecdh0_verify.h b/components/esp_hal_security/test_apps/crypto/main/key_manager/km_ecdh0_verify.h new file mode 100644 index 00000000000..7d45bebcb40 --- /dev/null +++ b/components/esp_hal_security/test_apps/crypto/main/key_manager/km_ecdh0_verify.h @@ -0,0 +1,63 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + * + * Runtime verification helpers for Key-Manager ECDH0 deployments. + * + * After an ECDH0 deploy the KM exports k2*G in `ecdh0_info`. The host side + * knows k1, so it can reconstruct x(k1*k2*G) on P-256 (via the ECC + * peripheral), derive the expected per-peripheral effective key, and + * assert the hardware output (HMAC / ECDSA pubkey / XTS ciphertext) + * matches bit-for-bit. + */ + +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Compute x(k1 * k2_G) on NIST P-256 using the ECC peripheral and return it + * as 32 big-endian bytes. + * + * k1_be: big-endian scalar bytes (24 or 32). + * k1_len: length of k1_be in bytes. + * k2_G_km: 64-byte KM-format public point exported in ecdh0_info: the + * peripheral's native LE-x || LE-y layout. + * x_be_out: 32 big-endian bytes of the result's x-coordinate. + */ +void km_verify_compute_x_be(const uint8_t *k1_be, size_t k1_len, + const uint8_t *k2_G_km, uint8_t x_be_out[32]); + +/* Given an ECDSA scalar (big-endian) and an ECC curve length + * (P192_LEN / P256_LEN / P384_LEN, from ecc_impl.h), compute scalar*G on + * that curve via the ECC peripheral and write pub_x / pub_y in the + * little-endian byte order the ECDSA peripheral exports. + */ +void km_verify_ecdsa_pubkey_from_scalar(unsigned curve_len, + const uint8_t *scalar_be, + size_t scalar_len, + uint8_t *pub_x_le_out, + uint8_t *pub_y_le_out); + +/* ESP32 flash-encryption XTS-AES in software (block-reversal wrapper around + * standard XTS, flash-address-based tweak). Encrypts `pt_len` <= 128 bytes + * at a 128-byte-aligned `flash_address`. + */ +void km_verify_flash_xts_encrypt(const uint8_t *key, size_t key_bits, + uint32_t flash_address, + const uint8_t *pt, size_t pt_len, + uint8_t *ct_out); + +/* HMAC-SHA256 one-shot via PSA */ +void km_verify_hmac_sha256(const uint8_t *key, size_t key_len, + const uint8_t *msg, size_t msg_len, + uint8_t mac_out[32]); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_security/test_apps/crypto/main/key_manager/test_key_manager.c b/components/esp_hal_security/test_apps/crypto/main/key_manager/test_key_manager.c index 95c219cff58..daed95b0cb0 100644 --- a/components/esp_hal_security/test_apps/crypto/main/key_manager/test_key_manager.c +++ b/components/esp_hal_security/test_apps/crypto/main/key_manager/test_key_manager.c @@ -24,6 +24,13 @@ #include "esp_flash.h" #include "key_manager_test_cases.h" #include "esp_log.h" +#include "esp_crypto_periph_clk.h" + +/* Runtime-verification helpers for ECDH0 deployments (ecc_point_multiply + * wrapper, ECDSA pubkey reconstruction, flash-XTS reference, HMAC). + * See km_ecdh0_verify.h for details. */ +#include "km_ecdh0_verify.h" +#include "ecc_impl.h" /* for P192_LEN / P256_LEN / P384_LEN */ #if SOC_KEY_MANAGER_ECDSA_KEY_DEPLOY #include "hal/ecdsa_types.h" @@ -48,8 +55,14 @@ const esp_partition_t *get_test_storage_partition(void) } return result; } +#endif /* SOC_KEY_MANAGER_FE_KEY_DEPLOY */ -static void test_xts_aes_key_aes_mode(test_data_aes_mode_t *test_data) +#if SOC_KEY_MANAGER_FE_KEY_DEPLOY +/* Common XTS-AES verify body. Used by both the AES-mode and ECDH1-mode XTS + * tests, which carry their own struct types but share the same plaintext + + * expected-ciphertext layout. */ +static void verify_xts_aes_test_data(const uint8_t *plaintext_data, + const test_xts_data_t *xts_test_data) { const esp_partition_t *partition = get_test_storage_partition(); ESP_ERROR_CHECK(esp_partition_erase_range(partition, 0, partition->size)); @@ -57,17 +70,27 @@ static void test_xts_aes_key_aes_mode(test_data_aes_mode_t *test_data) uint8_t read_data[128]; for (int i = 0; i < TEST_COUNT; i++) { memset(read_data, 0, sizeof(read_data)); - uint32_t address = test_data->xts_test_data[i].data_offset; - uint32_t data_size = test_data->xts_test_data[i].data_size; + uint32_t address = xts_test_data[i].data_offset; + uint32_t data_size = xts_test_data[i].data_size; - ESP_ERROR_CHECK(esp_flash_write_encrypted(NULL, address, test_data->plaintext_data, data_size)); + ESP_ERROR_CHECK(esp_flash_write_encrypted(NULL, address, plaintext_data, data_size)); ESP_ERROR_CHECK(esp_flash_read(NULL, read_data, address, data_size)); - TEST_ASSERT_EQUAL_HEX8_ARRAY(test_data->xts_test_data[i].ciphertext, read_data, data_size); + TEST_ASSERT_EQUAL_HEX8_ARRAY(xts_test_data[i].ciphertext, read_data, data_size); } } -static void test_xts_aes_key_ecdh0_mode(test_data_ecdh0_mode_t *test_data) +static void test_xts_aes_key_aes_mode(test_data_aes_mode_t *test_data) +{ + verify_xts_aes_test_data(test_data->plaintext_data, test_data->xts_test_data); +} + +/* Verify the ECDH0-deployed XTS key by writing plaintext through the HW + * flash-encrypt path and comparing the readback against the ciphertext we + * compute in software with mbedtls_xts under the derived key material. + */ +static void test_xts_aes_key_ecdh0_mode(test_data_ecdh0_mode_t *test_data, + const uint8_t *derived_key, size_t key_bits) { const esp_partition_t *partition = get_test_storage_partition(); ESP_ERROR_CHECK(esp_partition_erase_range(partition, 0, partition->size)); @@ -76,12 +99,13 @@ static void test_xts_aes_key_ecdh0_mode(test_data_ecdh0_mode_t *test_data) uint32_t address = partition->address; uint32_t data_size = 32; - ESP_LOG_BUFFER_HEXDUMP("Plaintext data", test_data->plaintext_data, data_size, ESP_LOG_DEBUG); - ESP_ERROR_CHECK(esp_flash_write_encrypted(NULL, address, test_data->plaintext_data, data_size)); ESP_ERROR_CHECK(esp_flash_read(NULL, read_data, address, data_size)); - ESP_LOG_BUFFER_HEXDUMP("Encrypted data", read_data, data_size, ESP_LOG_DEBUG); + uint8_t expected[32]; + km_verify_flash_xts_encrypt(derived_key, key_bits, address, + test_data->plaintext_data, data_size, expected); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, read_data, data_size); } #if SOC_KEY_MANAGER_FE_KEY_DEPLOY_XTS_AES_128 || SOC_KEY_MANAGER_FE_KEY_DEPLOY_XTS_AES_256 @@ -135,7 +159,24 @@ static void key_mgr_test_xts_aes_key_ecdh0_mode(esp_key_mgr_key_len_t key_len) #endif /* SOC_KEY_MANAGER_FE_KEY_DEPLOY_XTS_AES_256 */ TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info)); - test_xts_aes_key_ecdh0_mode(&test_data_ecdh0); + + /* Reconstruct the deployed XTS key from k1 and the exported k2*G, then + * assert the HW flash ciphertext matches what mbedtls_xts produces with + * that key. + */ + uint8_t derived_key[64]; + size_t key_bits = 256; + km_verify_compute_x_be(test_data_ecdh0.k1[0], sizeof(test_data_ecdh0.k1[0]), + ecdh0_info.k2_G[0], derived_key); +#if SOC_KEY_MANAGER_FE_KEY_DEPLOY_XTS_AES_256 + if (key_len == ESP_KEY_MGR_XTS_AES_LEN_256) { + km_verify_compute_x_be(test_data_ecdh0.k1[1], sizeof(test_data_ecdh0.k1[1]), + ecdh0_info.k2_G[1], derived_key + 32); + key_bits = 512; + } +#endif + test_xts_aes_key_ecdh0_mode(&test_data_ecdh0, derived_key, key_bits); + TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deactivate_key(key_recovery_info.key_type)); } #endif /* SOC_KEY_MANAGER_FE_KEY_DEPLOY_XTS_AES_128 || SOC_KEY_MANAGER_FE_KEY_DEPLOY_XTS_AES_256 */ @@ -354,6 +395,39 @@ static void key_mgr_test_ecdsa_key_ecdh0_mode(esp_key_mgr_key_len_t key_len) #endif TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info)); +#if SOC_ECDSA_SUPPORT_EXPORT_PUBKEY + /* Reconstruct the scalar the KM should have deployed from k1 and the + * exported k2*G, then compute scalar*G on the target curve in software + * and assert the ECDSA peripheral's exported pubkey matches byte-for-byte. + */ + uint8_t x_be_stage0[32]; + km_verify_compute_x_be(test_data_ecdh0.k1[0], sizeof(test_data_ecdh0.k1[0]), + ecdh0_info.k2_G[0], x_be_stage0); + + if (key_len == ESP_KEY_MGR_ECDSA_LEN_256) { + uint8_t pub_x_le[32], pub_y_le[32]; + km_verify_ecdsa_pubkey_from_scalar(P256_LEN, x_be_stage0, 32, pub_x_le, pub_y_le); + test_ecdsa_export_pubkey(ECDSA_CURVE_SECP256R1, pub_x_le, pub_y_le, 1); + } else if (key_len == ESP_KEY_MGR_ECDSA_LEN_192) { + uint8_t pub_x_le[24], pub_y_le[24]; + km_verify_ecdsa_pubkey_from_scalar(P192_LEN, x_be_stage0 + 8, 24, pub_x_le, pub_y_le); + test_ecdsa_export_pubkey(ECDSA_CURVE_SECP192R1, pub_x_le, pub_y_le, 1); + } +#if SOC_ECDSA_SUPPORT_CURVE_P384 + else if (key_len == ESP_KEY_MGR_ECDSA_LEN_384) { + uint8_t x_be_stage1[32]; + km_verify_compute_x_be(test_data_ecdh0.k1[1], sizeof(test_data_ecdh0.k1[1]), + ecdh0_info.k2_G[1], x_be_stage1); + uint8_t scalar_be[48]; + memcpy(scalar_be, x_be_stage0 + 16, 16); + memcpy(scalar_be + 16, x_be_stage1, 32); + uint8_t pub_x_le[48], pub_y_le[48]; + km_verify_ecdsa_pubkey_from_scalar(P384_LEN, scalar_be, 48, pub_x_le, pub_y_le); + test_ecdsa_export_pubkey(ECDSA_CURVE_SECP384R1, pub_x_le, pub_y_le, 1); + } +#endif +#endif /* SOC_ECDSA_SUPPORT_EXPORT_PUBKEY */ + #if SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE key_mgr_test_ecdsa_key(key_len, ECDSA_K_TYPE_DETERMINISITIC); #endif @@ -402,11 +476,28 @@ static void key_mgr_test_hmac_key_aes_mode(test_data_aes_mode_t *test_data) TEST_ASSERT_EQUAL_HEX8_ARRAY(test_data->hmac_test_data.hmac_result, hmac, sizeof(test_data->hmac_test_data.hmac_result)); } -static void key_mgr_test_hmac_key_ecdh0_mode(const uint8_t *message, size_t message_len) +/* Verify the ECDH0-deployed HMAC output. k2*G is exported via ecdh0_info, so + * the test can reconstruct x(k1 * k2*G) using the ECC peripheral, then compute + * HMAC(x_le, message) in software and compare against the hardware HMAC. */ +static void key_mgr_test_hmac_key_ecdh0_mode(const uint8_t *k1_be, size_t k1_len, + const uint8_t *k2_G_km, + const uint8_t *message, size_t message_len) { - uint8_t hmac[32] = {0}; - TEST_ASSERT_EQUAL(ESP_OK, hmac_calculate(HMAC_KEY_KM, message, message_len, hmac)); - // We cannot verify the result here as the HMAC key deployed is unknown. + uint8_t x_be[32]; + km_verify_compute_x_be(k1_be, k1_len, k2_G_km, x_be); + + /* HMAC peripheral reads the key slot in LE order, whereas the mbedtls needs it in BE.*/ + uint8_t x_le[32]; + for (int i = 0; i < 32; ++i) { + x_le[i] = x_be[31 - i]; + } + + uint8_t expected_mac[32]; + km_verify_hmac_sha256(x_le, sizeof(x_le), message, message_len, expected_mac); + + uint8_t hw_mac[32] = { 0 }; + TEST_ASSERT_EQUAL(ESP_OK, hmac_calculate(HMAC_KEY_KM, message, message_len, hw_mac)); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_mac, hw_mac, sizeof(hw_mac)); } static void key_mgr_test_hmac_key_aes_random_mode(const uint8_t *message, size_t message_len) @@ -447,7 +538,10 @@ static void key_mgr_test_hmac_ecdh0_mode(void) ESP_LOG_BUFFER_HEXDUMP("K2_G", ecdh0_info.k2_G[0], KEY_MGR_ECDH0_INFO_SIZE, ESP_LOG_DEBUG); TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info)); - key_mgr_test_hmac_key_ecdh0_mode(test_data_hmac.hmac_test_data.message, sizeof(test_data_hmac.hmac_test_data.message)); + key_mgr_test_hmac_key_ecdh0_mode(test_data_ecdh0.k1[0], sizeof(test_data_ecdh0.k1[0]), + ecdh0_info.k2_G[0], + test_data_hmac.hmac_test_data.message, + sizeof(test_data_hmac.hmac_test_data.message)); TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deactivate_key(key_recovery_info.key_type)); } @@ -514,7 +608,7 @@ TEST_SETUP(key_manager) TEST_IGNORE_MESSAGE("Key Manager not supported on this chip"); } test_utils_record_free_mem(); - TEST_ESP_OK(test_utils_set_leak_level(800, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL)); + TEST_ESP_OK(test_utils_set_leak_level(900, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL)); } TEST_TEAR_DOWN(key_manager) diff --git a/components/esp_security/src/esp_key_mgr.c b/components/esp_security/src/esp_key_mgr.c index 405d456d638..88959da212a 100644 --- a/components/esp_security/src/esp_key_mgr.c +++ b/components/esp_security/src/esp_key_mgr.c @@ -126,6 +126,12 @@ static void esp_key_mgr_acquire_hardware(bool deployment_mode) esp_crypto_ecc_lock_acquire(); esp_crypto_sha_aes_lock_acquire(); esp_crypto_key_manager_lock_acquire(); + // The KM peripheral uses the external ECC block for the ECDH0/ECDH1 + // scalar multiplications; its bus clock must be on, otherwise the KM + // deploys an incorrect key. +#if SOC_ECC_SUPPORTED + esp_crypto_ecc_enable_periph_clk(true); +#endif } // Reset the Key Manager Clock esp_crypto_key_mgr_enable_periph_clk(true); @@ -134,6 +140,9 @@ static void esp_key_mgr_acquire_hardware(bool deployment_mode) static void esp_key_mgr_release_hardware(bool deployment_mode) { if (deployment_mode) { +#if SOC_ECC_SUPPORTED + esp_crypto_ecc_enable_periph_clk(false); +#endif esp_crypto_key_manager_lock_release(); esp_crypto_sha_aes_lock_release(); esp_crypto_ecc_lock_release();