From 33d8c05d95e7b06efe94d1a970eb2dea7c3907ef Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Tue, 10 Jun 2025 16:57:20 +0530 Subject: [PATCH] feat(esp_key_mgr): Support Digital Signature key deployments using Key Manager --- components/esp_security/src/esp_ds.c | 38 ++++++++++++------- components/esp_security/src/esp_key_mgr.c | 16 ++++++++ components/hal/ds_hal.c | 10 ++++- components/hal/esp32c5/include/hal/ds_ll.h | 10 ++++- .../hal/esp32c5/include/hal/key_mgr_ll.h | 21 +++++++++- components/hal/include/hal/ds_hal.h | 10 ++++- components/hal/include/hal/ds_types.h | 11 +++++- .../esp32c5/include/soc/Kconfig.soc_caps.in | 4 ++ components/soc/esp32c5/include/soc/soc_caps.h | 1 + 9 files changed, 103 insertions(+), 18 deletions(-) diff --git a/components/esp_security/src/esp_ds.c b/components/esp_security/src/esp_ds.c index 6bdcad3376..ae941f4369 100644 --- a/components/esp_security/src/esp_ds.c +++ b/components/esp_security/src/esp_ds.c @@ -17,6 +17,7 @@ #include "esp_cpu.h" #endif +#include "soc/soc_caps.h" #include "esp_ds.h" #include "esp_crypto_lock.h" #include "esp_crypto_periph_clk.h" @@ -37,6 +38,10 @@ #include "hal/sha_ll.h" #endif /* !CONFIG_IDF_TARGET_ESP32S2 */ +#ifdef SOC_KEY_MANAGER_DS_KEY_DEPLOY +#include "hal/key_mgr_hal.h" +#endif + /** * The vtask delay \c esp_ds_sign() is using while waiting for completion of the signing operation. */ @@ -247,22 +252,14 @@ static void ds_acquire_enable(void) // We also enable SHA and HMAC here. SHA is used by HMAC, HMAC is used by DS. esp_crypto_hmac_enable_periph_clk(true); - esp_crypto_sha_enable_periph_clk(true); - esp_crypto_ds_enable_periph_clk(true); - - hmac_hal_start(); } static void ds_disable_release(void) { - ds_hal_finish(); - esp_crypto_ds_enable_periph_clk(false); - esp_crypto_sha_enable_periph_clk(false); - esp_crypto_hmac_enable_periph_clk(false); esp_crypto_ds_lock_release(); @@ -326,12 +323,24 @@ esp_err_t esp_ds_start_sign(const void *message, ds_acquire_enable(); - // initiate hmac - uint32_t conf_error = hmac_hal_configure(HMAC_OUTPUT_DS, key_id); - if (conf_error) { - ds_disable_release(); - return ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL; +#if SOC_KEY_MANAGER_DS_KEY_DEPLOY + if (key_id == HMAC_KEY_KM) { + key_mgr_hal_set_key_usage(ESP_KEY_MGR_DS_KEY, ESP_KEY_MGR_USE_OWN_KEY); + ds_hal_set_key_source(DS_KEY_SOURCE_KEY_MGR); + } else { + key_mgr_hal_set_key_usage(ESP_KEY_MGR_DS_KEY, ESP_KEY_MGR_USE_EFUSE_KEY); + ds_hal_set_key_source(DS_KEY_SOURCE_EFUSE); +#endif + // initiate hmac + hmac_hal_start(); + uint32_t conf_error = hmac_hal_configure(HMAC_OUTPUT_DS, key_id); + if (conf_error) { + ds_disable_release(); + return ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL; + } +#if SOC_KEY_MANAGER_DS_KEY_DEPLOY } +#endif ds_hal_start(); @@ -339,6 +348,7 @@ esp_err_t esp_ds_start_sign(const void *message, int64_t start_time = get_time_us(); while (ds_ll_busy() != 0) { if ((get_time_us() - start_time) > SOC_DS_KEY_CHECK_MAX_WAIT_US) { + ds_hal_finish(); ds_disable_release(); return ESP_ERR_HW_CRYPTO_DS_INVALID_KEY; } @@ -348,6 +358,7 @@ esp_err_t esp_ds_start_sign(const void *message, *esp_ds_ctx = malloc(sizeof(esp_ds_context_t)); #endif if (!*esp_ds_ctx) { + ds_hal_finish(); ds_disable_release(); return ESP_ERR_NO_MEM; } @@ -398,6 +409,7 @@ esp_err_t esp_ds_finish_sign(void *signature, esp_ds_context_t *esp_ds_ctx) #endif hmac_hal_clean(); + ds_hal_finish(); ds_disable_release(); diff --git a/components/esp_security/src/esp_key_mgr.c b/components/esp_security/src/esp_key_mgr.c index 948ed4a47f..a53f085ca5 100644 --- a/components/esp_security/src/esp_key_mgr.c +++ b/components/esp_security/src/esp_key_mgr.c @@ -35,6 +35,7 @@ static const char *TAG = "esp_key_mgr"; static _lock_t s_key_mgr_ecdsa_key_lock; static _lock_t s_key_mgr_xts_aes_key_lock; static _lock_t s_key_mgr_hmac_key_lock; +static _lock_t s_key_mgr_ds_key_lock; ESP_STATIC_ASSERT(sizeof(esp_key_mgr_key_recovery_info_t) == sizeof(struct huk_key_block), "Size of esp_key_mgr_key_recovery_info_t should match huk_key_block (from ROM)"); @@ -57,6 +58,9 @@ static void esp_key_mgr_acquire_key_lock(esp_key_mgr_key_type_t key_type) case ESP_KEY_MGR_HMAC_KEY: _lock_acquire(&s_key_mgr_hmac_key_lock); break; + case ESP_KEY_MGR_DS_KEY: + _lock_acquire(&s_key_mgr_ds_key_lock); + break; default: ESP_LOGE(TAG, "Invalid key type"); break; @@ -79,6 +83,9 @@ static void esp_key_mgr_release_key_lock(esp_key_mgr_key_type_t key_type) case ESP_KEY_MGR_HMAC_KEY: _lock_release(&s_key_mgr_hmac_key_lock); break; + case ESP_KEY_MGR_DS_KEY: + _lock_release(&s_key_mgr_ds_key_lock); + break; default: ESP_LOGE(TAG, "Invalid key type"); break; @@ -351,6 +358,8 @@ esp_err_t esp_key_mgr_deploy_key_in_aes_mode(const esp_key_mgr_aes_key_config_t aes_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_1; } else if (key_type == ESP_KEY_MGR_HMAC_KEY) { aes_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_HMAC; + } else if (key_type == ESP_KEY_MGR_DS_KEY) { + aes_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_DS; } else { ESP_LOGE(TAG, "Invalid key type"); return ESP_ERR_INVALID_ARG; @@ -472,6 +481,8 @@ esp_err_t esp_key_mgr_activate_key(esp_key_mgr_key_recovery_info_t *key_recovery key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_1; } else if (key_type == ESP_KEY_MGR_HMAC_KEY) { key_purpose = ESP_KEY_MGR_KEY_PURPOSE_HMAC; + } else if (key_type == ESP_KEY_MGR_DS_KEY) { + key_purpose = ESP_KEY_MGR_KEY_PURPOSE_DS; } else { ESP_LOGE(TAG, "Invalid key type"); return ESP_ERR_INVALID_ARG; @@ -643,6 +654,9 @@ esp_err_t esp_key_mgr_deploy_key_in_ecdh0_mode(const esp_key_mgr_ecdh0_key_confi } else if (key_type == ESP_KEY_MGR_HMAC_KEY) { ecdh0_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_HMAC; ecdh0_deploy_config.ecdh0_key_info = ecdh0_key_info->k2_G[0]; + } else if (key_type == ESP_KEY_MGR_DS_KEY) { + ecdh0_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_DS; + ecdh0_deploy_config.ecdh0_key_info = ecdh0_key_info->k2_G[0]; } else { ESP_LOGE(TAG, "Invalid key type"); return ESP_ERR_INVALID_ARG; @@ -777,6 +791,8 @@ esp_err_t esp_key_mgr_deploy_key_in_random_mode(const esp_key_mgr_random_key_con random_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_1; } else if (key_type == ESP_KEY_MGR_HMAC_KEY) { random_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_HMAC; + } else if (key_type == ESP_KEY_MGR_DS_KEY) { + random_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_DS; } else { ESP_LOGE(TAG, "Invalid key type"); return ESP_ERR_INVALID_ARG; diff --git a/components/hal/ds_hal.c b/components/hal/ds_hal.c index 53f9279456..7591eff3a8 100644 --- a/components/hal/ds_hal.c +++ b/components/hal/ds_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,7 @@ #include "hal/systimer_hal.h" #include "hal/ds_hal.h" #include "hal/ds_ll.h" +#include "soc/soc_caps.h" void ds_hal_start(void) { @@ -23,6 +24,13 @@ void ds_hal_configure_iv(const uint32_t *iv) ds_ll_configure_iv(iv); } +#if SOC_KEY_MANAGER_DS_KEY_DEPLOY +void ds_hal_set_key_source(ds_key_source_t key_source) +{ + ds_ll_set_key_source(key_source); +} +#endif + void ds_hal_write_message(const uint8_t *msg, size_t size) { ds_ll_write_message(msg, size); diff --git a/components/hal/esp32c5/include/hal/ds_ll.h b/components/hal/esp32c5/include/hal/ds_ll.h index 02b4e41c35..61ebbc4870 100644 --- a/components/hal/esp32c5/include/hal/ds_ll.h +++ b/components/hal/esp32c5/include/hal/ds_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -78,6 +78,14 @@ static inline ds_key_check_t ds_ll_key_error_source(void) } } +/** + * @brief Set the DS key source. + */ +static inline void ds_ll_set_key_source(ds_key_source_t key_source) +{ + REG_WRITE(DS_KEY_SOURCE_REG, key_source); +} + /** * @brief Write the initialization vector to the corresponding register field. */ diff --git a/components/hal/esp32c5/include/hal/key_mgr_ll.h b/components/hal/esp32c5/include/hal/key_mgr_ll.h index e8657f0465..b84e4d5e9b 100644 --- a/components/hal/esp32c5/include/hal/key_mgr_ll.h +++ b/components/hal/esp32c5/include/hal/key_mgr_ll.h @@ -189,6 +189,14 @@ static inline void key_mgr_ll_set_key_usage(const esp_key_mgr_key_type_t key_typ } break; + case ESP_KEY_MGR_DS_KEY: + if (key_usage == ESP_KEY_MGR_USE_EFUSE_KEY) { + REG_SET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_DS); + } else { + REG_CLR_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_DS); + } + break; + default: HAL_ASSERT(false && "Unsupported mode"); return; @@ -213,6 +221,10 @@ static inline esp_key_mgr_key_usage_t key_mgr_ll_get_key_usage(esp_key_mgr_key_t return (esp_key_mgr_key_usage_t) (REG_GET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_HMAC)); break; + case ESP_KEY_MGR_DS_KEY: + return (esp_key_mgr_key_usage_t) (REG_GET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_DS)); + break; + default: HAL_ASSERT(false && "Unsupported mode"); return ESP_KEY_MGR_USAGE_INVALID; @@ -253,6 +265,10 @@ static inline void key_mgr_ll_lock_use_efuse_key_reg(esp_key_mgr_key_type_t key_ REG_SET_BIT(KEYMNG_LOCK_REG, KEYMNG_USE_EFUSE_KEY_LOCK_HMAC); break; + case ESP_KEY_MGR_DS_KEY: + REG_SET_BIT(KEYMNG_LOCK_REG, KEYMNG_USE_EFUSE_KEY_LOCK_DS); + break; + default: HAL_ASSERT(false && "Unsupported mode"); return; @@ -291,7 +307,6 @@ static inline bool key_mgr_ll_is_result_success(void) static inline bool key_mgr_ll_is_key_deployment_valid(const esp_key_mgr_key_type_t key_type) { switch (key_type) { - case ESP_KEY_MGR_ECDSA_192_KEY: return REG_GET_FIELD(KEYMNG_KEY_VLD_REG, KEYMNG_KEY_ECDSA_192_VLD); case ESP_KEY_MGR_ECDSA_256_KEY: @@ -309,6 +324,10 @@ static inline bool key_mgr_ll_is_key_deployment_valid(const esp_key_mgr_key_type return REG_GET_FIELD(KEYMNG_KEY_VLD_REG, KEYMNG_KEY_HMAC_VLD); break; + case ESP_KEY_MGR_DS_KEY: + return REG_GET_FIELD(KEYMNG_KEY_VLD_REG, KEYMNG_KEY_DS_VLD); + break; + default: HAL_ASSERT(false && "Unsupported mode"); return 0; diff --git a/components/hal/include/hal/ds_hal.h b/components/hal/include/hal/ds_hal.h index bf9a18df5d..766854d8b9 100644 --- a/components/hal/include/hal/ds_hal.h +++ b/components/hal/include/hal/ds_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +15,7 @@ #include #include #include +#include "soc/soc_caps.h" #include "hal/ds_types.h" #ifdef __cplusplus @@ -38,6 +39,13 @@ void ds_hal_finish(void); */ void ds_hal_configure_iv(const uint32_t *iv); +#if SOC_KEY_MANAGER_DS_KEY_DEPLOY +/** + * @brief Set the DS key source. + */ +void ds_hal_set_key_source(ds_key_source_t key_source); +#endif + /** * @brief Write the message which should be signed. * diff --git a/components/hal/include/hal/ds_types.h b/components/hal/include/hal/ds_types.h index f739a11b66..7734a6fae1 100644 --- a/components/hal/include/hal/ds_types.h +++ b/components/hal/include/hal/ds_types.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,8 @@ extern "C" { #endif +#include "soc/soc_caps.h" + /** * The result when checking whether the key to decrypt the RSA parameters is ready. */ @@ -25,6 +27,13 @@ typedef enum { DS_SIGNATURE_PADDING_AND_MD_FAIL = 3, /**< Both padding and MD check failed. */ } ds_signature_check_t; +#if SOC_KEY_MANAGER_DS_KEY_DEPLOY +typedef enum { + DS_KEY_SOURCE_EFUSE = 0, + DS_KEY_SOURCE_KEY_MGR = 1, +} ds_key_source_t; +#endif + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in index 4c8b621955..8e75e2282b 100644 --- a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in @@ -1427,6 +1427,10 @@ config SOC_KEY_MANAGER_HMAC_KEY_DEPLOY bool default y +config SOC_KEY_MANAGER_DS_KEY_DEPLOY + bool + default y + config SOC_SECURE_BOOT_V2_RSA bool default y diff --git a/components/soc/esp32c5/include/soc/soc_caps.h b/components/soc/esp32c5/include/soc/soc_caps.h index 2bf4d14e89..1236a27002 100644 --- a/components/soc/esp32c5/include/soc/soc_caps.h +++ b/components/soc/esp32c5/include/soc/soc_caps.h @@ -548,6 +548,7 @@ #define SOC_KEY_MANAGER_ECDSA_KEY_DEPLOY 1 /*!< Key manager responsible to deploy ECDSA key */ #define SOC_KEY_MANAGER_FE_KEY_DEPLOY 1 /*!< Key manager responsible to deploy Flash Encryption key */ #define SOC_KEY_MANAGER_HMAC_KEY_DEPLOY 1 /*!< Key manager responsible to deploy HMAC key */ +#define SOC_KEY_MANAGER_DS_KEY_DEPLOY 1 /*!< Key manager responsible to deploy DS key */ /*-------------------------- Secure Boot CAPS----------------------------*/ #define SOC_SECURE_BOOT_V2_RSA 1