feat(esp_key_mgr): Support HMAC key deployments using Key Manager

This commit is contained in:
harshal.patil
2025-06-10 16:51:59 +05:30
parent 8ab6b4d694
commit 265b0d7579
7 changed files with 84 additions and 16 deletions

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -9,6 +9,7 @@
#include <stdbool.h> #include <stdbool.h>
#include "esp_err.h" #include "esp_err.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "hal/hmac_types.h"
#if !SOC_HMAC_SUPPORTED && !CI_HEADER_CHECK #if !SOC_HMAC_SUPPORTED && !CI_HEADER_CHECK
#error "HMAC peripheral is not supported for the selected target" #error "HMAC peripheral is not supported for the selected target"
@@ -18,19 +19,6 @@
extern "C" { extern "C" {
#endif #endif
/**
* The possible efuse keys for the HMAC peripheral
*/
typedef enum {
HMAC_KEY0 = 0,
HMAC_KEY1,
HMAC_KEY2,
HMAC_KEY3,
HMAC_KEY4,
HMAC_KEY5,
HMAC_KEY_MAX
} hmac_key_id_t;
/** /**
* @brief * @brief
* Calculate the HMAC of a given message. * Calculate the HMAC of a given message.

View File

@@ -34,6 +34,7 @@ static const char *TAG = "esp_key_mgr";
static _lock_t s_key_mgr_ecdsa_key_lock; 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_xts_aes_key_lock;
static _lock_t s_key_mgr_hmac_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)"); 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)");
@@ -53,6 +54,9 @@ static void esp_key_mgr_acquire_key_lock(esp_key_mgr_key_type_t key_type)
case ESP_KEY_MGR_XTS_AES_256_KEY: case ESP_KEY_MGR_XTS_AES_256_KEY:
_lock_acquire(&s_key_mgr_xts_aes_key_lock); _lock_acquire(&s_key_mgr_xts_aes_key_lock);
break; break;
case ESP_KEY_MGR_HMAC_KEY:
_lock_acquire(&s_key_mgr_hmac_key_lock);
break;
default: default:
ESP_LOGE(TAG, "Invalid key type"); ESP_LOGE(TAG, "Invalid key type");
break; break;
@@ -72,6 +76,9 @@ static void esp_key_mgr_release_key_lock(esp_key_mgr_key_type_t key_type)
case ESP_KEY_MGR_XTS_AES_256_KEY: case ESP_KEY_MGR_XTS_AES_256_KEY:
_lock_release(&s_key_mgr_xts_aes_key_lock); _lock_release(&s_key_mgr_xts_aes_key_lock);
break; break;
case ESP_KEY_MGR_HMAC_KEY:
_lock_release(&s_key_mgr_hmac_key_lock);
break;
default: default:
ESP_LOGE(TAG, "Invalid key type"); ESP_LOGE(TAG, "Invalid key type");
break; break;
@@ -342,6 +349,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_128; aes_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_128;
} else if (key_type == ESP_KEY_MGR_XTS_AES_256_KEY) { } else if (key_type == ESP_KEY_MGR_XTS_AES_256_KEY) {
aes_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_1; 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 { } else {
ESP_LOGE(TAG, "Invalid key type"); ESP_LOGE(TAG, "Invalid key type");
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
@@ -461,6 +470,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_128; key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_128;
} else if (key_type == ESP_KEY_MGR_XTS_AES_256_KEY) { } else if (key_type == ESP_KEY_MGR_XTS_AES_256_KEY) {
key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_1; 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 { } else {
ESP_LOGE(TAG, "Invalid key type"); ESP_LOGE(TAG, "Invalid key type");
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
@@ -629,6 +640,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_XTS_AES_256_KEY) { } else if (key_type == ESP_KEY_MGR_XTS_AES_256_KEY) {
ecdh0_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_1; ecdh0_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_1;
ecdh0_deploy_config.ecdh0_key_info = ecdh0_key_info->k2_G[0]; ecdh0_deploy_config.ecdh0_key_info = ecdh0_key_info->k2_G[0];
} 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 { } else {
ESP_LOGE(TAG, "Invalid key type"); ESP_LOGE(TAG, "Invalid key type");
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
@@ -761,6 +775,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_128; random_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_128;
} else if (key_type == ESP_KEY_MGR_XTS_AES_256_KEY) { } else if (key_type == ESP_KEY_MGR_XTS_AES_256_KEY) {
random_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_1; 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 { } else {
ESP_LOGE(TAG, "Invalid key type"); ESP_LOGE(TAG, "Invalid key type");
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;

View File

@@ -171,6 +171,7 @@ static inline void key_mgr_ll_set_key_usage(const esp_key_mgr_key_type_t key_typ
REG_CLR_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_ECDSA); REG_CLR_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_ECDSA);
} }
break; break;
case ESP_KEY_MGR_XTS_AES_128_KEY: case ESP_KEY_MGR_XTS_AES_128_KEY:
case ESP_KEY_MGR_XTS_AES_256_KEY: case ESP_KEY_MGR_XTS_AES_256_KEY:
if (key_usage == ESP_KEY_MGR_USE_EFUSE_KEY) { if (key_usage == ESP_KEY_MGR_USE_EFUSE_KEY) {
@@ -180,6 +181,14 @@ static inline void key_mgr_ll_set_key_usage(const esp_key_mgr_key_type_t key_typ
} }
break; break;
case ESP_KEY_MGR_HMAC_KEY:
if (key_usage == ESP_KEY_MGR_USE_EFUSE_KEY) {
REG_SET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_HMAC);
} else {
REG_CLR_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_HMAC);
}
break;
default: default:
HAL_ASSERT(false && "Unsupported mode"); HAL_ASSERT(false && "Unsupported mode");
return; return;
@@ -200,6 +209,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_FLASH)); return (esp_key_mgr_key_usage_t) (REG_GET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_FLASH));
break; break;
case ESP_KEY_MGR_HMAC_KEY:
return (esp_key_mgr_key_usage_t) (REG_GET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_HMAC));
break;
default: default:
HAL_ASSERT(false && "Unsupported mode"); HAL_ASSERT(false && "Unsupported mode");
return ESP_KEY_MGR_USAGE_INVALID; return ESP_KEY_MGR_USAGE_INVALID;
@@ -230,10 +243,16 @@ static inline void key_mgr_ll_lock_use_efuse_key_reg(esp_key_mgr_key_type_t key_
case ESP_KEY_MGR_ECDSA_384_KEY: case ESP_KEY_MGR_ECDSA_384_KEY:
REG_SET_BIT(KEYMNG_LOCK_REG, KEYMNG_USE_EFUSE_KEY_LOCK_ECDSA); REG_SET_BIT(KEYMNG_LOCK_REG, KEYMNG_USE_EFUSE_KEY_LOCK_ECDSA);
break; break;
case ESP_KEY_MGR_XTS_AES_128_KEY: case ESP_KEY_MGR_XTS_AES_128_KEY:
case ESP_KEY_MGR_XTS_AES_256_KEY: case ESP_KEY_MGR_XTS_AES_256_KEY:
REG_SET_BIT(KEYMNG_LOCK_REG, KEYMNG_USE_EFUSE_KEY_LOCK_FLASH); REG_SET_BIT(KEYMNG_LOCK_REG, KEYMNG_USE_EFUSE_KEY_LOCK_FLASH);
break; break;
case ESP_KEY_MGR_HMAC_KEY:
REG_SET_BIT(KEYMNG_LOCK_REG, KEYMNG_USE_EFUSE_KEY_LOCK_HMAC);
break;
default: default:
HAL_ASSERT(false && "Unsupported mode"); HAL_ASSERT(false && "Unsupported mode");
return; return;
@@ -286,6 +305,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_FLASH_VLD); return REG_GET_FIELD(KEYMNG_KEY_VLD_REG, KEYMNG_KEY_FLASH_VLD);
break; break;
case ESP_KEY_MGR_HMAC_KEY:
return REG_GET_FIELD(KEYMNG_KEY_VLD_REG, KEYMNG_KEY_HMAC_VLD);
break;
default: default:
HAL_ASSERT(false && "Unsupported mode"); HAL_ASSERT(false && "Unsupported mode");
return 0; return 0;

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -7,6 +7,11 @@
#include "stdio.h" #include "stdio.h"
#include "hal/hmac_hal.h" #include "hal/hmac_hal.h"
#include "hal/hmac_ll.h" #include "hal/hmac_ll.h"
#include "soc/soc_caps.h"
#if SOC_KEY_MANAGER_HMAC_KEY_DEPLOY
#include "hal/key_mgr_hal.h"
#endif
void hmac_hal_start(void) void hmac_hal_start(void)
{ {
@@ -18,6 +23,20 @@ uint32_t hmac_hal_configure(hmac_hal_output_t config, uint32_t key_id)
{ {
hmac_ll_wait_idle(); hmac_ll_wait_idle();
hmac_ll_config_output(config); hmac_ll_config_output(config);
#if SOC_KEY_MANAGER_HMAC_KEY_DEPLOY
if (key_id == HMAC_KEY_KM) {
if (config == HMAC_OUTPUT_USER) {
key_mgr_hal_set_key_usage(ESP_KEY_MGR_HMAC_KEY, ESP_KEY_MGR_USE_OWN_KEY);
} else {
// No other HMAC output type is allowed when using key manager
return 1;
}
} else {
key_mgr_hal_set_key_usage(ESP_KEY_MGR_HMAC_KEY, ESP_KEY_MGR_USE_EFUSE_KEY);
}
#endif
hmac_ll_config_hw_key_id(key_id); hmac_ll_config_hw_key_id(key_id);
hmac_ll_config_finish(); hmac_ll_config_finish();
hmac_ll_wait_idle(); hmac_ll_wait_idle();

View File

@@ -1,14 +1,31 @@
/* /*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#pragma once #pragma once
#include "soc/soc_caps.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/**
* The possible efuse keys for the HMAC peripheral
*/
typedef enum {
HMAC_KEY0 = 0,
HMAC_KEY1,
HMAC_KEY2,
HMAC_KEY3,
HMAC_KEY4,
HMAC_KEY5,
#if SOC_KEY_MANAGER_HMAC_KEY_DEPLOY
HMAC_KEY_KM = 7,
#endif
HMAC_KEY_MAX = 8,
} hmac_key_id_t;
/** /**
* The HMAC peripheral can be configured to deliver its output to the user directly, or to deliver * The HMAC peripheral can be configured to deliver its output to the user directly, or to deliver
* the output directly to another peripheral instead, e.g. the Digital Signature peripheral. * the output directly to another peripheral instead, e.g. the Digital Signature peripheral.

View File

@@ -1423,6 +1423,10 @@ config SOC_KEY_MANAGER_FE_KEY_DEPLOY
bool bool
default y default y
config SOC_KEY_MANAGER_HMAC_KEY_DEPLOY
bool
default y
config SOC_SECURE_BOOT_V2_RSA config SOC_SECURE_BOOT_V2_RSA
bool bool
default y default y

View File

@@ -547,6 +547,7 @@
#define SOC_KEY_MANAGER_SUPPORT_KEY_DEPLOYMENT 1 /*!< Key manager supports key deployment */ #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 */ #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_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 */
/*-------------------------- Secure Boot CAPS----------------------------*/ /*-------------------------- Secure Boot CAPS----------------------------*/
#define SOC_SECURE_BOOT_V2_RSA 1 #define SOC_SECURE_BOOT_V2_RSA 1