Skip to content

Commit 8ab6b4d

Browse files
committed
fix(esp_security/esp_key_mgr): Recharge HUK before the first usage
1 parent a7c7b75 commit 8ab6b4d

File tree

7 files changed

+83
-25
lines changed

7 files changed

+83
-25
lines changed

components/esp_security/src/esp_key_mgr.c

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,30 @@ typedef struct {
157157
esp_key_mgr_huk_info_t *huk_recovery_info;
158158
} huk_deploy_config_t;
159159

160+
static esp_err_t configure_huk(esp_huk_mode_t huk_mode, uint8_t *huk_info)
161+
{
162+
esp_err_t ret = huk_hal_configure(huk_mode, huk_info);
163+
if (ret != ESP_OK) {
164+
return ret;
165+
}
166+
167+
#if SOC_HUK_MEM_NEEDS_RECHARGE
168+
if (!key_mgr_hal_is_huk_valid()) {
169+
huk_hal_recharge_huk_memory();
170+
ret = huk_hal_configure(huk_mode, huk_info);
171+
if (ret != ESP_OK) {
172+
return ret;
173+
}
174+
}
175+
#endif
176+
177+
if (!key_mgr_hal_is_huk_valid()) {
178+
return ESP_FAIL;
179+
}
180+
181+
return ESP_OK;
182+
}
183+
160184
static esp_err_t deploy_huk(huk_deploy_config_t *config)
161185
{
162186
esp_err_t esp_ret = ESP_FAIL;
@@ -174,7 +198,8 @@ static esp_err_t deploy_huk(huk_deploy_config_t *config)
174198
}
175199
memcpy(huk_recovery_info, config->pre_generated_huk_info->info, KEY_MGR_HUK_INFO_SIZE);
176200
ESP_LOGI(TAG, "Recovering HUK from given HUK recovery info");
177-
esp_ret = huk_hal_configure(ESP_HUK_MODE_RECOVERY, huk_recovery_info);
201+
202+
esp_ret = configure_huk(ESP_HUK_MODE_RECOVERY, huk_recovery_info);
178203
if (esp_ret != ESP_OK) {
179204
ESP_LOGE(TAG, "Failed to recover HUK");
180205
heap_caps_free(huk_recovery_info);
@@ -186,7 +211,8 @@ static esp_err_t deploy_huk(huk_deploy_config_t *config)
186211
} else {
187212
// Generate new HUK and corresponding HUK info
188213
ESP_LOGI(TAG, "Generating new HUK");
189-
esp_ret = huk_hal_configure(ESP_HUK_MODE_GENERATION, huk_recovery_info);
214+
215+
esp_ret = configure_huk(ESP_HUK_MODE_GENERATION, huk_recovery_info);
190216
if (esp_ret != ESP_OK) {
191217
ESP_LOGE(TAG, "Failed to generate HUK");
192218
heap_caps_free(huk_recovery_info);
@@ -196,12 +222,6 @@ static esp_err_t deploy_huk(huk_deploy_config_t *config)
196222
config->huk_recovery_info->crc = esp_rom_crc32_le(0, huk_recovery_info, KEY_MGR_HUK_INFO_SIZE);
197223
}
198224

199-
if (!key_mgr_hal_is_huk_valid()) {
200-
ESP_LOGE(TAG, "HUK is invalid");
201-
heap_caps_free(huk_recovery_info);
202-
return ESP_FAIL;
203-
}
204-
205225
ESP_LOG_BUFFER_HEX_LEVEL("HUK INFO", huk_recovery_info, KEY_MGR_HUK_INFO_SIZE, ESP_LOG_DEBUG);
206226
// Free the local buffer for huk recovery info
207227
heap_caps_free(huk_recovery_info);
@@ -368,15 +388,10 @@ static esp_err_t key_mgr_recover_key(key_recovery_config_t *config)
368388

369389
if ((!key_mgr_hal_is_huk_valid()) || (!config->huk_recovered)) {
370390
check_huk_risk_level();
371-
esp_err_t esp_ret = huk_hal_configure(ESP_HUK_MODE_RECOVERY, config->key_recovery_info->huk_info.info);
391+
esp_err_t esp_ret = configure_huk(ESP_HUK_MODE_RECOVERY, config->key_recovery_info->huk_info.info);
372392
if (esp_ret != ESP_OK) {
373393
ESP_LOGE(TAG, "Failed to recover HUK");
374-
return ESP_FAIL;
375-
}
376-
if (!key_mgr_hal_is_huk_valid()) {
377-
ESP_LOGE(TAG, "HUK is invalid");
378-
// TODO - define error code
379-
return ESP_FAIL;
394+
return esp_ret;
380395
}
381396
ESP_LOGI(TAG, "HUK recovered successfully");
382397
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
433448
return ESP_ERR_INVALID_ARG;
434449
}
435450

436-
esp_key_mgr_key_purpose_t key_purpose;
437451
ESP_LOGI(TAG, "Activating key of type %d", key_recovery_info->key_type);
452+
438453
esp_key_mgr_key_type_t key_type = (esp_key_mgr_key_type_t) key_recovery_info->key_type;
454+
esp_key_mgr_key_purpose_t key_purpose;
455+
439456
if (key_type == ESP_KEY_MGR_ECDSA_192_KEY) {
440457
key_purpose = ESP_KEY_MGR_KEY_PURPOSE_ECDSA_192;
441458
} 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
450467
}
451468

452469
esp_err_t esp_ret = ESP_FAIL;
453-
ESP_LOGI(TAG, "Activating key of type %d", key_recovery_info->key_type);
454470
esp_key_mgr_acquire_key_lock(key_type);
455471
key_recovery_config_t key_recovery_config = {};
456472
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
482498
return ESP_OK;
483499

484500
cleanup:
485-
ESP_LOGI(TAG, "Key activation failed");
501+
ESP_LOGE(TAG, "Key activation failed");
486502
esp_key_mgr_release_hardware(false);
487503
return esp_ret;
488504
}

components/esp_security/src/init.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
#include "esp_err.h"
1515
#include "hal/efuse_hal.h"
1616

17+
#if SOC_HUK_MEM_NEEDS_RECHARGE
18+
#include "hal/huk_hal.h"
19+
#endif
20+
1721
#if SOC_KEY_MANAGER_SUPPORT_KEY_DEPLOYMENT
1822
#include "hal/key_mgr_ll.h"
1923
#endif /* SOC_KEY_MANAGER_SUPPORT_KEY_DEPLOYMENT */

components/hal/esp32c5/include/hal/huk_ll.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -22,6 +22,8 @@
2222
#include "hal/huk_types.h"
2323
#include "soc/huk_reg.h"
2424
#include "soc/soc_caps.h"
25+
#include "soc/lp_aon_reg.h"
26+
#include "esp_rom_sys.h" // HUK memory recharge workaround
2527

2628
#ifdef __cplusplus
2729
extern "C" {
@@ -103,6 +105,20 @@ static inline esp_huk_gen_status_t huk_ll_get_gen_status(void)
103105
return (esp_huk_gen_status_t) REG_GET_FIELD(HUK_STATUS_REG, HUK_STATUS);
104106
}
105107

108+
109+
static inline void __attribute__((always_inline)) huk_ll_recharge_huk_memory(void)
110+
{
111+
REG_CLR_BIT(LP_AON_MEM_CTRL_REG, LP_AON_HUK_MEM_FORCE_PD);
112+
113+
REG_CLR_BIT(LP_AON_PUF_MEM_SW_REG, LP_AON_PUF_MEM_SW);
114+
REG_SET_BIT(LP_AON_PUF_MEM_DISCHARGE_REG, LP_AON_PUF_MEM_DISCHARGE);
115+
esp_rom_delay_us(100000);
116+
117+
REG_CLR_BIT(LP_AON_PUF_MEM_DISCHARGE_REG, LP_AON_PUF_MEM_DISCHARGE);
118+
REG_SET_BIT(LP_AON_PUF_MEM_SW_REG, LP_AON_PUF_MEM_SW);
119+
esp_rom_delay_us(100000);
120+
}
121+
106122
/**
107123
* @brief Read the HUK date information
108124
*/

components/hal/huk_hal.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -13,6 +13,7 @@
1313
#include "hal/log.h"
1414
#include "rom/km.h"
1515
#include "esp_err.h"
16+
#include "soc/soc_caps.h"
1617

1718
esp_huk_state_t huk_hal_get_state(void)
1819
{
@@ -28,11 +29,11 @@ static void inline huk_hal_wait_for_state(esp_huk_state_t state)
2829

2930
esp_err_t huk_hal_configure(const esp_huk_mode_t huk_mode, uint8_t *huk_info_buf)
3031
{
31-
if (esp_rom_km_huk_conf(huk_mode, huk_info_buf) == ETS_OK) {
32-
return ESP_OK;
33-
} else {
32+
if (esp_rom_km_huk_conf(huk_mode, huk_info_buf) != ETS_OK) {
3433
return ESP_FAIL;
3534
}
35+
36+
return ESP_OK;
3637
}
3738

3839
uint8_t huk_hal_get_risk_level(void)
@@ -44,3 +45,10 @@ uint32_t huk_hal_get_date_info(void)
4445
{
4546
return huk_ll_get_date_info();
4647
}
48+
49+
#if SOC_HUK_MEM_NEEDS_RECHARGE
50+
void huk_hal_recharge_huk_memory(void)
51+
{
52+
huk_ll_recharge_huk_memory();
53+
}
54+
#endif

components/hal/include/hal/huk_hal.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -9,7 +9,7 @@
99

1010
#include "soc/soc_caps.h"
1111

12-
#if SOC_KEY_MANAGER_SUPPORTED
12+
#if SOC_HUK_SUPPORTED
1313
#include "hal/huk_types.h"
1414
#include <stdint.h>
1515
#include "esp_err.h"
@@ -51,6 +51,13 @@ uint8_t huk_hal_get_risk_level(void);
5151
*/
5252
uint32_t huk_hal_get_date_info(void);
5353

54+
#if SOC_HUK_MEM_NEEDS_RECHARGE
55+
/**
56+
* @brief Recharge HUK memory
57+
*/
58+
void huk_hal_recharge_huk_memory(void);
59+
#endif
60+
5461
#ifdef __cplusplus
5562
}
5663
#endif

components/soc/esp32c5/include/soc/Kconfig.soc_caps.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,6 +1407,10 @@ config SOC_EFUSE_ECDSA_KEY_P384
14071407
bool
14081408
default y
14091409

1410+
config SOC_HUK_MEM_NEEDS_RECHARGE
1411+
bool
1412+
default y
1413+
14101414
config SOC_KEY_MANAGER_SUPPORT_KEY_DEPLOYMENT
14111415
bool
14121416
default y

components/soc/esp32c5/include/soc/soc_caps.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,9 @@
540540
#define SOC_EFUSE_ECDSA_KEY_P192 1
541541
#define SOC_EFUSE_ECDSA_KEY_P384 1
542542

543+
/*-------------------------- HUK CAPS----------------------------*/
544+
#define SOC_HUK_MEM_NEEDS_RECHARGE 1
545+
543546
/*-------------------------- Key Manager CAPS----------------------------*/
544547
#define SOC_KEY_MANAGER_SUPPORT_KEY_DEPLOYMENT 1 /*!< Key manager supports key deployment */
545548
#define SOC_KEY_MANAGER_ECDSA_KEY_DEPLOY 1 /*!< Key manager responsible to deploy ECDSA key */

0 commit comments

Comments
 (0)