diff --git a/components/esp_security/src/esp_key_mgr.c b/components/esp_security/src/esp_key_mgr.c index 356a659024..fa12e002c4 100644 --- a/components/esp_security/src/esp_key_mgr.c +++ b/components/esp_security/src/esp_key_mgr.c @@ -157,6 +157,30 @@ typedef struct { esp_key_mgr_huk_info_t *huk_recovery_info; } huk_deploy_config_t; +static esp_err_t configure_huk(esp_huk_mode_t huk_mode, uint8_t *huk_info) +{ + esp_err_t ret = huk_hal_configure(huk_mode, huk_info); + if (ret != ESP_OK) { + return ret; + } + +#if SOC_HUK_MEM_NEEDS_RECHARGE + if (!key_mgr_hal_is_huk_valid()) { + huk_hal_recharge_huk_memory(); + ret = huk_hal_configure(huk_mode, huk_info); + if (ret != ESP_OK) { + return ret; + } + } +#endif + + if (!key_mgr_hal_is_huk_valid()) { + return ESP_FAIL; + } + + return ESP_OK; +} + static esp_err_t deploy_huk(huk_deploy_config_t *config) { esp_err_t esp_ret = ESP_FAIL; @@ -174,7 +198,8 @@ static esp_err_t deploy_huk(huk_deploy_config_t *config) } memcpy(huk_recovery_info, config->pre_generated_huk_info->info, KEY_MGR_HUK_INFO_SIZE); ESP_LOGI(TAG, "Recovering HUK from given HUK recovery info"); - esp_ret = huk_hal_configure(ESP_HUK_MODE_RECOVERY, huk_recovery_info); + + esp_ret = configure_huk(ESP_HUK_MODE_RECOVERY, huk_recovery_info); if (esp_ret != ESP_OK) { ESP_LOGE(TAG, "Failed to recover HUK"); heap_caps_free(huk_recovery_info); @@ -186,7 +211,8 @@ static esp_err_t deploy_huk(huk_deploy_config_t *config) } else { // Generate new HUK and corresponding HUK info ESP_LOGI(TAG, "Generating new HUK"); - esp_ret = huk_hal_configure(ESP_HUK_MODE_GENERATION, huk_recovery_info); + + esp_ret = configure_huk(ESP_HUK_MODE_GENERATION, huk_recovery_info); if (esp_ret != ESP_OK) { ESP_LOGE(TAG, "Failed to generate HUK"); heap_caps_free(huk_recovery_info); @@ -196,12 +222,6 @@ static esp_err_t deploy_huk(huk_deploy_config_t *config) config->huk_recovery_info->crc = esp_rom_crc32_le(0, huk_recovery_info, KEY_MGR_HUK_INFO_SIZE); } - if (!key_mgr_hal_is_huk_valid()) { - ESP_LOGE(TAG, "HUK is invalid"); - heap_caps_free(huk_recovery_info); - return ESP_FAIL; - } - ESP_LOG_BUFFER_HEX_LEVEL("HUK INFO", huk_recovery_info, KEY_MGR_HUK_INFO_SIZE, ESP_LOG_DEBUG); // Free the local buffer for huk recovery info heap_caps_free(huk_recovery_info); @@ -368,15 +388,10 @@ static esp_err_t key_mgr_recover_key(key_recovery_config_t *config) if ((!key_mgr_hal_is_huk_valid()) || (!config->huk_recovered)) { check_huk_risk_level(); - esp_err_t esp_ret = huk_hal_configure(ESP_HUK_MODE_RECOVERY, config->key_recovery_info->huk_info.info); + esp_err_t esp_ret = configure_huk(ESP_HUK_MODE_RECOVERY, config->key_recovery_info->huk_info.info); if (esp_ret != ESP_OK) { ESP_LOGE(TAG, "Failed to recover HUK"); - return ESP_FAIL; - } - if (!key_mgr_hal_is_huk_valid()) { - ESP_LOGE(TAG, "HUK is invalid"); - // TODO - define error code - return ESP_FAIL; + return esp_ret; } ESP_LOGI(TAG, "HUK recovered successfully"); ESP_LOG_BUFFER_HEX_LEVEL("HUK INFO", config->key_recovery_info->huk_info.info, KEY_MGR_HUK_INFO_SIZE, ESP_LOG_DEBUG); @@ -433,9 +448,11 @@ esp_err_t esp_key_mgr_activate_key(esp_key_mgr_key_recovery_info_t *key_recovery return ESP_ERR_INVALID_ARG; } - esp_key_mgr_key_purpose_t key_purpose; ESP_LOGI(TAG, "Activating key of type %d", key_recovery_info->key_type); + esp_key_mgr_key_type_t key_type = (esp_key_mgr_key_type_t) key_recovery_info->key_type; + esp_key_mgr_key_purpose_t key_purpose; + if (key_type == ESP_KEY_MGR_ECDSA_192_KEY) { key_purpose = ESP_KEY_MGR_KEY_PURPOSE_ECDSA_192; } else if (key_type == ESP_KEY_MGR_ECDSA_256_KEY) { @@ -450,7 +467,6 @@ esp_err_t esp_key_mgr_activate_key(esp_key_mgr_key_recovery_info_t *key_recovery } esp_err_t esp_ret = ESP_FAIL; - ESP_LOGI(TAG, "Activating key of type %d", key_recovery_info->key_type); esp_key_mgr_acquire_key_lock(key_type); key_recovery_config_t key_recovery_config = {}; key_recovery_config.key_recovery_info = key_recovery_info; @@ -482,7 +498,7 @@ esp_err_t esp_key_mgr_activate_key(esp_key_mgr_key_recovery_info_t *key_recovery return ESP_OK; cleanup: - ESP_LOGI(TAG, "Key activation failed"); + ESP_LOGE(TAG, "Key activation failed"); esp_key_mgr_release_hardware(false); return esp_ret; } diff --git a/components/esp_security/src/init.c b/components/esp_security/src/init.c index de8866c31c..14ede2dc0d 100644 --- a/components/esp_security/src/init.c +++ b/components/esp_security/src/init.c @@ -14,6 +14,10 @@ #include "esp_err.h" #include "hal/efuse_hal.h" +#if SOC_HUK_MEM_NEEDS_RECHARGE +#include "hal/huk_hal.h" +#endif + #if SOC_KEY_MANAGER_SUPPORT_KEY_DEPLOYMENT #include "hal/key_mgr_ll.h" #endif /* SOC_KEY_MANAGER_SUPPORT_KEY_DEPLOYMENT */ diff --git a/components/hal/esp32c5/include/hal/huk_ll.h b/components/hal/esp32c5/include/hal/huk_ll.h index 37215ae35e..fb6e4e69f4 100644 --- a/components/hal/esp32c5/include/hal/huk_ll.h +++ b/components/hal/esp32c5/include/hal/huk_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 */ @@ -22,6 +22,8 @@ #include "hal/huk_types.h" #include "soc/huk_reg.h" #include "soc/soc_caps.h" +#include "soc/lp_aon_reg.h" +#include "esp_rom_sys.h" // HUK memory recharge workaround #ifdef __cplusplus extern "C" { @@ -103,6 +105,20 @@ static inline esp_huk_gen_status_t huk_ll_get_gen_status(void) return (esp_huk_gen_status_t) REG_GET_FIELD(HUK_STATUS_REG, HUK_STATUS); } + +static inline void __attribute__((always_inline)) huk_ll_recharge_huk_memory(void) +{ + REG_CLR_BIT(LP_AON_MEM_CTRL_REG, LP_AON_HUK_MEM_FORCE_PD); + + REG_CLR_BIT(LP_AON_PUF_MEM_SW_REG, LP_AON_PUF_MEM_SW); + REG_SET_BIT(LP_AON_PUF_MEM_DISCHARGE_REG, LP_AON_PUF_MEM_DISCHARGE); + esp_rom_delay_us(100000); + + REG_CLR_BIT(LP_AON_PUF_MEM_DISCHARGE_REG, LP_AON_PUF_MEM_DISCHARGE); + REG_SET_BIT(LP_AON_PUF_MEM_SW_REG, LP_AON_PUF_MEM_SW); + esp_rom_delay_us(100000); +} + /** * @brief Read the HUK date information */ diff --git a/components/hal/huk_hal.c b/components/hal/huk_hal.c index 70aa576459..c9f9e51399 100644 --- a/components/hal/huk_hal.c +++ b/components/hal/huk_hal.c @@ -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 */ @@ -13,6 +13,7 @@ #include "hal/log.h" #include "rom/km.h" #include "esp_err.h" +#include "soc/soc_caps.h" esp_huk_state_t huk_hal_get_state(void) { @@ -28,11 +29,11 @@ static void inline huk_hal_wait_for_state(esp_huk_state_t state) esp_err_t huk_hal_configure(const esp_huk_mode_t huk_mode, uint8_t *huk_info_buf) { - if (esp_rom_km_huk_conf(huk_mode, huk_info_buf) == ETS_OK) { - return ESP_OK; - } else { + if (esp_rom_km_huk_conf(huk_mode, huk_info_buf) != ETS_OK) { return ESP_FAIL; } + + return ESP_OK; } uint8_t huk_hal_get_risk_level(void) @@ -44,3 +45,10 @@ uint32_t huk_hal_get_date_info(void) { return huk_ll_get_date_info(); } + +#if SOC_HUK_MEM_NEEDS_RECHARGE +void huk_hal_recharge_huk_memory(void) +{ + huk_ll_recharge_huk_memory(); +} +#endif diff --git a/components/hal/include/hal/huk_hal.h b/components/hal/include/hal/huk_hal.h index e158f1fc66..3bdd04c896 100644 --- a/components/hal/include/hal/huk_hal.h +++ b/components/hal/include/hal/huk_hal.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,7 +9,7 @@ #include "soc/soc_caps.h" -#if SOC_KEY_MANAGER_SUPPORTED +#if SOC_HUK_SUPPORTED #include "hal/huk_types.h" #include #include "esp_err.h" @@ -51,6 +51,13 @@ uint8_t huk_hal_get_risk_level(void); */ uint32_t huk_hal_get_date_info(void); +#if SOC_HUK_MEM_NEEDS_RECHARGE +/** + * @brief Recharge HUK memory + */ +void huk_hal_recharge_huk_memory(void); +#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 f5bc36f1d9..d3c17598c2 100644 --- a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in @@ -1407,6 +1407,10 @@ config SOC_EFUSE_ECDSA_KEY_P384 bool default y +config SOC_HUK_MEM_NEEDS_RECHARGE + bool + default y + config SOC_KEY_MANAGER_SUPPORT_KEY_DEPLOYMENT bool default y diff --git a/components/soc/esp32c5/include/soc/soc_caps.h b/components/soc/esp32c5/include/soc/soc_caps.h index a659eaec90..9c535a21f9 100644 --- a/components/soc/esp32c5/include/soc/soc_caps.h +++ b/components/soc/esp32c5/include/soc/soc_caps.h @@ -540,6 +540,9 @@ #define SOC_EFUSE_ECDSA_KEY_P192 1 #define SOC_EFUSE_ECDSA_KEY_P384 1 +/*-------------------------- HUK CAPS----------------------------*/ +#define SOC_HUK_MEM_NEEDS_RECHARGE 1 + /*-------------------------- Key Manager CAPS----------------------------*/ #define SOC_KEY_MANAGER_SUPPORT_KEY_DEPLOYMENT 1 /*!< Key manager supports key deployment */ #define SOC_KEY_MANAGER_ECDSA_KEY_DEPLOY 1 /*!< Key manager responsible to deploy ECDSA key */