# 密钥管理器

[English]

ESP32-S31 中的密钥管理器外设为加密密钥提供了硬件辅助的 密钥部署和密钥恢复 功能，用于配置和使用加密密钥，而无需将明文密钥内容存储在 flash、RAM 或 eFuse 中。

密钥管理器适用于需要安全处理常驻加密密钥的应用程序。

密钥管理器具有以下特性：

- 设备唯一性

  密钥通过每块芯片独有的硬件唯一密钥 (HUK) 进行加密绑定。

- 无明文密钥存储

  密钥材料不会暴露于软件可访问的内存中。

- 灵活的密钥生命周期

  密钥可以被部署、恢复或替换为新密钥，无需为每个密钥重新烧录 eFuse。

- 抗物理提取

  读取 flash 或 eFuse 的内容不会泄露可用的密钥材料。

## 硬件唯一密钥 (HUK)

硬件唯一密钥 (HUK) 是完全由硬件 HUK 外设生成的设备专属密钥，源自 SRAM 物理不可克隆函数 (PUF)。重建 HUK 时，需要用到 HUK 恢复信息，该信息包含在密钥管理器为已部署密钥生成的密钥恢复信息中。有关 HUK 外设的更多信息，请参阅 《ESP32-S31 技术参考手册》 > 密钥管理器章节 [PDF] > HUK 生成器。

HUK 是所有通过密钥管理器部署的密钥的信任根。

## 密钥部署与恢复

密钥管理器分为两个不同的阶段运行：

- 密钥部署

  加密密钥在芯片内部生成或被安全导入，并与 HUK 绑定。此步骤通常在生产阶段、首次启动时，或在应用程序运行并生成临时/持久密钥时执行。

- 密钥恢复

  在后续启动过程中，密钥管理器部署的持久密钥会使用先前生成的密钥恢复信息进行还原，而不会暴露密钥值。

在部署过程中，密钥管理器生成 `esp_key_mgr_key_recovery_info_t` 数据结构。对于持久密钥，应用程序必须将此数据保存在非易失性存储器（例如 flash）中，以便在后续启动时恢复密钥。

## 支持的密钥类型

密钥管理器可以管理以下密钥类型：

- ECDSA

- HMAC

- 数字签名外设

每个密钥都与一个 `esp_key_mgr_key_purpose_t` 相关联，该类型定义了硬件外设如何使用密钥。

## 密钥部署模式

密钥管理器提供多种密钥部署模式，以满足不同的配置和安全需求。

### 随机部署模式

在此模式下，密钥管理器在内部生成一个随机私钥。

- 应用程序软件无法获取密钥值。

- 不需要外部密钥材料。

- 适用于不需要备份或导出密钥的场景。

### AES 部署模式

在此模式下，可以安全部署用户指定的私钥。

- 密钥在传输到芯片之前进行加密。

- 使用辅助密钥材料保护部署过程。

- 适用于需要预定义密钥值的出厂配置场景。

### ECDH0 部署模式

在此模式下，私钥通过椭圆曲线 Diffie-Hellman (ECDH) 协商生成。

- 最终私钥不会被传输。

- 部署过程可以通过不受信任的信道进行。

- 适用于高安全性的配置环境。

### ECDH1 部署模式

此模式类似于 ECDH0 部署模式，但为生产配置流程提供了额外的灵活性。

- 支持使用辅助恢复数据进行协商的密钥部署。

- 允许通过替换辅助信息来更新已部署的密钥。

- 适用于具有受控信任假设的大规模生产场景。

有关各种部署模式的详细信息，请参阅 《ESP32-S31 技术参考手册》 > 密钥管理器章节 [PDF] > 密钥管理器小节。

## 典型工作流程

### 首次启动或生产配置

典型的配置流程包括：

1. 生成硬件唯一密钥 (HUK)

2. 使用恰当的部署模式部署所需的加密密钥

3. 将生成的 `key_recovery_info` 保存至非易失性存储器中

4. 如有需要，锁定相关安全配置 eFuse

此过程通常每台设备仅执行一次。

### 正常启动

在正常启动过程中：

1. 应用程序提供先前由密钥管理器部署的密钥所生成的 `key_recovery_info`

2. HUK 由硬件自动重建

3. 密钥管理器在内部恢复已部署的密钥

4. 密码外设可以使用已恢复的密钥

## 安全注意事项

使用密钥管理器的应用程序应注意以下事项：

- 防止密钥管理器部署密钥的 `key_recovery_info` 遭受未授权的修改或丢失。

- 密钥部署成功后，锁定密钥管理器安全相关的 eFuse，防止重新部署同类型密钥。

- 除非明确需要，否则在已启用 flash 加密时，应避免部署新的 XTS-AES 密钥。

## API 参考

### Header File

- components/esp_security/include/esp_key_mgr.h

- This header file can be included with:

  >     #include "esp_key_mgr.h"

- This header file is a part of the API provided by the `esp_security` component. To declare that your component depends on `esp_security`, add the following to your CMakeLists.txt:

  >     REQUIRES esp_security

  > or

  >     PRIV_REQUIRES esp_security

### Functions

void key_mgr_wait_for_state(esp_key_mgr_state_t state)

  Wait for the Key Manager to reach the given state.

  参数:

    state -- The state to wait for

esp_err_t esp_key_mgr_deploy_key_in_aes_mode(const esp_key_mgr_aes_key_config_t *key_config, esp_key_mgr_key_recovery_info_t *key_info)

  Deploy key in AES deployment mode.

  参数:

    - key_config -- [in] AES key configuration

    - key_info -- [out] A writable struct of esp_key_mgr_key_recovery_info_t type. The recovery information for the deployed key shall be stored here.

  返回:

    - ESP_OK on success

    - ESP_FAIL or relevant error code on failure

esp_err_t esp_key_mgr_deploy_key_in_ecdh0_mode(const esp_key_mgr_ecdh0_key_config_t *key_config, esp_key_mgr_key_recovery_info_t *key_info, esp_key_mgr_ecdh0_info_t *ecdh0_key_info)

  Deploy key in ECDH0 deployment mode.

  参数:

    - key_config -- [in] ECDH0 key configuration

    - key_info -- [out] A writable struct of esp_key_mgr_key_recovery_info_t type. The recovery key info for the deployed key shall be stored here.

    - ecdh0_key_info -- [out] A writable struct of esp_key_mgr_ecdh0_info_t type. The ECDH0 info to recover the actual key shall be stored here.

  返回:

    - ESP_OK on success

    - ESP_FAIL or relevant error code on failure

esp_err_t esp_key_mgr_deploy_key_in_ecdh1_mode(const esp_key_mgr_ecdh1_key_config_t *key_config, esp_key_mgr_key_recovery_info_t *key_info)

  Deploy key in ECDH1 deployment mode.

  参数:

    - key_config -- [in] ECDH1 key configuration

    - key_info -- [out] A writable struct of esp_key_mgr_key_recovery_info_t type. The recovery key info for the deployed key shall be stored here.

  返回:

    - ESP_OK on success

    - ESP_FAIL or relevant error code on failure

esp_err_t esp_key_mgr_deploy_key_in_random_mode(const esp_key_mgr_random_key_config_t *key_config, esp_key_mgr_key_recovery_info_t *key_info)

  Deploy key in Random deployment mode.

  参数:

    - key_config -- [in] Random key configuration

    - key_info -- [out] A writable struct of esp_key_mgr_key_recovery_info_t type. The recovery key info for the deployed key shall be stored here.

  返回:

    - ESP_OK on success

    - ESP_FAIL or relevant error code on failure

esp_err_t esp_key_mgr_activate_key(esp_key_mgr_key_recovery_info_t *key_recovery_info)

  Recover and Activate a key from the given key info.

  备注

  Once a key of particular type is activated through Key Manager, then a different key of the same type cannot be activated at the same time. This key must be deactivated first through a call to esp_key_mgr_deactivate_key() before activating other key of the same type.

  参数:

    key_recovery_info -- [in] The key recovery info required to recover the key

  返回:

    - ESP_OK on success

    - ESP_FAIL or relevant error code on failure

esp_err_t esp_key_mgr_deactivate_key(esp_key_mgr_key_type_t key_type)

  De-activate a key of the given type.

  The key which is de-activated can no longer be used for any operation.

  参数:

    key_type -- [in] The type of the key to deactivate

  返回:

    - ESP_OK on success

    - ESP_FAIL or relevant error code on failure

### Structures

struct esp_key_mgr_aes_key_config_t

  Configuration for deploying a key in AES mode.

  Public Members

  esp_key_mgr_key_type_t key_type

    Type of key to deploy

  esp_key_mgr_key_len_t key_len

    Length of the key

  bool use_pre_generated_huk_info

    Use pre-generated HUK info if true

  bool use_pre_generated_sw_init_key

    Use pre-generated software init key if true

  esp_key_mgr_huk_info_t huk_info

    HUK recovery info

  uint8_t sw_init_key[KEY_MGR_SW_INIT_KEY_SIZE]

    Software init key

  uint8_t k2_info[KEY_MGR_K2_INFO_SIZE]

    K2 info for AES deployment

  uint8_t k1_encrypted[2][KEY_MGR_K1_ENCRYPTED_SIZE]

    Encrypted K1 key data

struct esp_key_mgr_ecdh0_key_config_t

  Configuration for deploying a key in ECDH0 mode.

  Public Members

  esp_key_mgr_key_type_t key_type

    Type of key to deploy

  esp_key_mgr_key_len_t key_len

    Length of the key

  bool use_pre_generated_huk_info

    Use pre-generated HUK info if true

  esp_key_mgr_huk_info_t huk_info

    HUK recovery info

  uint8_t k1_G[2][KEY_MGR_ECDH0_INFO_SIZE]

    K1*G points for ECDH0 deployment

struct esp_key_mgr_ecdh1_key_config_t

  Configuration for deploying a key in ECDH1 mode.

  ECDH1 requires the same init_key/k2_info inputs as AES mode plus the ECDH k1*G public point(s). Unlike ECDH0, k2*G is computed by the user locally and is not read back from the Key Manager.

  Public Members

  esp_key_mgr_key_type_t key_type

    Type of key to deploy

  esp_key_mgr_key_len_t key_len

    Length of the key

  bool use_pre_generated_huk_info

    Use pre-generated HUK info if true

  bool use_pre_generated_sw_init_key

    Use pre-generated software init key if true

  esp_key_mgr_huk_info_t huk_info

    HUK recovery info

  uint8_t sw_init_key[KEY_MGR_SW_INIT_KEY_SIZE]

    Software init key

  uint8_t k2_info[KEY_MGR_K2_INFO_SIZE]

    K2 info for ECDH1 deployment

  uint8_t k1_G[2][KEY_MGR_ECDH0_INFO_SIZE]

    K1*G points for ECDH1 deployment

struct esp_key_mgr_random_key_config_t

  Configuration for deploying a key in Random mode.

  Public Members

  esp_key_mgr_key_type_t key_type

    Type of key to deploy

  esp_key_mgr_key_len_t key_len

    Length of the key

  bool use_pre_generated_huk_info

    Use pre-generated HUK info if true

  esp_key_mgr_huk_info_t huk_info

    HUK recovery info

struct esp_key_mgr_ecdh0_info_t

  ECDH0 key info generated during ECDH0 deployment.

  Public Members

  esp_key_mgr_key_type_t key_type

    Type of key

  esp_key_mgr_key_len_t key_len

    Length of the key

  uint8_t k2_G[2][KEY_MGR_ECDH0_INFO_SIZE]

    K2*G points from ECDH0 deployment

### Macros

KEY_MGR_SW_INIT_KEY_SIZE

KEY_MGR_ASSIST_INFO_SIZE

KEY_MGR_KEY_RECOVERY_INFO_SIZE

KEY_MGR_HUK_INFO_SIZE

KEY_MGR_HUK_RISK_ALERT_LEVEL

KEY_MGR_KEY_INFO_SIZE

KEY_MGR_K2_INFO_SIZE

KEY_MGR_K1_ENCRYPTED_SIZE

KEY_MGR_ECDH0_INFO_SIZE

KEY_MGR_PLAINTEXT_KEY_SIZE

### Header File

- components/esp_hal_security/include/hal/key_mgr_types.h

- This header file can be included with:

  >     #include "hal/key_mgr_types.h"

- This header file is a part of the API provided by the `esp_hal_security` component. To declare that your component depends on `esp_hal_security`, add the following to your CMakeLists.txt:

  >     REQUIRES esp_hal_security

  > or

  >     PRIV_REQUIRES esp_hal_security

### Structures

struct esp_key_mgr_huk_info_t

  HUK info structure, stores HUK recovery information.

  Public Members

  uint8_t info[HUK_INFO_LEN]

    HUK info data

  uint32_t crc

    CRC of the HUK info

struct esp_key_mgr_key_info_t

  Key info structure, stores key recovery information (512 bits)

  Public Members

  uint8_t info[KEY_INFO_LEN]

    Key info data

  uint32_t crc

    CRC of the key info

struct esp_key_mgr_key_recovery_info_t

  Key recovery info structure containing all data needed to recover a deployed key.

  Public Members

  uint32_t magic

    Magic number for validation

  uint32_t version

    Version for backward compatibility

  uint8_t key_type

    Type of the deployed key

  uint8_t key_len

    Length of the deployed key

  uint8_t key_deployment_mode

    Deployment mode used for the key

  uint8_t reserved[13]

    Reserved for future use

  esp_key_mgr_huk_info_t huk_info

    HUK recovery info

  esp_key_mgr_key_info_t key_info[2]

    Key info (up to 2 entries for XTS-AES-256)

### Macros

KEY_MGR_ASSIST_INFO_LEN

HUK_INFO_LEN

KEY_INFO_LEN

KEY_HUK_SECTOR_MAGIC

### Enumerations

enum esp_key_mgr_state_t

  State of Key Manager: idle, load, gain or busy.

  Values:

  enumerator ESP_KEY_MGR_STATE_IDLE
  enumerator ESP_KEY_MGR_STATE_LOAD
  enumerator ESP_KEY_MGR_STATE_GAIN
  enumerator ESP_KEY_MGR_STATE_BUSY

enum esp_key_mgr_key_len_t

  Length of the deployed key (XTS-AES, ECDSA)

  Values:

  enumerator ESP_KEY_MGR_ECDSA_LEN_192
  enumerator ESP_KEY_MGR_ECDSA_LEN_256
  enumerator ESP_KEY_MGR_ECDSA_LEN_384
  enumerator ESP_KEY_MGR_XTS_AES_LEN_128
  enumerator ESP_KEY_MGR_XTS_AES_LEN_256

enum esp_key_mgr_key_type_t

  Type of the key.

  Values:

  enumerator ESP_KEY_MGR_ECDSA_KEY
  enumerator ESP_KEY_MGR_FLASH_XTS_AES_KEY
  enumerator ESP_KEY_MGR_HMAC_KEY
  enumerator ESP_KEY_MGR_DS_KEY
  enumerator ESP_KEY_MGR_PSRAM_XTS_AES_KEY

enum esp_key_mgr_key_usage_t

  Key Manager key usage type.

  Values:

  enumerator ESP_KEY_MGR_USE_OWN_KEY
  enumerator ESP_KEY_MGR_USE_EFUSE_KEY
  enumerator ESP_KEY_MGR_USAGE_INVALID

enum esp_key_mgr_key_purpose_t

  Key Purpose to be set for a particular key in the Key Manager.

  Values:

  enumerator ESP_KEY_MGR_KEY_PURPOSE_INVALID
  enumerator ESP_KEY_MGR_KEY_PURPOSE_ECDSA_192
  enumerator ESP_KEY_MGR_KEY_PURPOSE_ECDSA_256
  enumerator ESP_KEY_MGR_KEY_PURPOSE_FLASH_256_1
  enumerator ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_1
  enumerator ESP_KEY_MGR_KEY_PURPOSE_FLASH_256_2
  enumerator ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_2
  enumerator ESP_KEY_MGR_KEY_PURPOSE_FLASH_128
  enumerator ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_128
  enumerator ESP_KEY_MGR_KEY_PURPOSE_HMAC
  enumerator ESP_KEY_MGR_KEY_PURPOSE_DS
  enumerator ESP_KEY_MGR_KEY_PURPOSE_PSRAM_256_1
  enumerator ESP_KEY_MGR_KEY_PURPOSE_PSRAM_256_2
  enumerator ESP_KEY_MGR_KEY_PURPOSE_PSRAM_128
  enumerator ESP_KEY_MGR_KEY_PURPOSE_ECDSA_384_L
  enumerator ESP_KEY_MGR_KEY_PURPOSE_ECDSA_384_H

enum esp_key_mgr_key_generator_mode_t

  Key Manager Generator mode.

  Values:

  enumerator ESP_KEY_MGR_KEYGEN_MODE_RANDOM
  enumerator ESP_KEY_MGR_KEYGEN_MODE_AES
  enumerator ESP_KEY_MGR_KEYGEN_MODE_ECDH0
  enumerator ESP_KEY_MGR_KEYGEN_MODE_ECDH1
  enumerator ESP_KEY_MGR_KEYGEN_MODE_RECOVER
  enumerator ESP_KEY_MGR_KEYGEN_MODE_EXPORT

enum esp_key_mgr_interrupt_type_t

  Key Manager interrupt types.

  Values:

  enumerator ESP_KEY_MGR_INT_PREP_DONE
  enumerator ESP_KEY_MGR_INT_PROC_DONE
  enumerator ESP_KEY_MGR_INT_POST_DONE

enum esp_key_mgr_force_use_km_key_t

  Force use key manager key type.

  备注

  This is used to force the key manager to use a specific key type.

  Values:

  enumerator ESP_KEY_MGR_FORCE_USE_KM_ECDSA_KEY
  enumerator ESP_KEY_MGR_FORCE_USE_KM_XTS_AES_KEY
  enumerator ESP_KEY_MGR_FORCE_USE_KM_HMAC_KEY
  enumerator ESP_KEY_MGR_FORCE_USE_KM_DS_KEY

## 应用示例

security/key_manager 演示了如何使用密钥管理器进行密钥部署，以及如何使用已部署的密钥执行签名操作。

该示例展示了如何：

- 初始化密钥管理器

- 使用 AES 部署模式部署密钥

- 使用 PSA 接口通过密钥管理器部署的密钥执行签名操作

此文档对您有帮助吗？

- 反馈已收到，谢谢！
- 如果您有其他意见，欢迎填写乐鑫文档反馈表。

- 我们重视您的反馈。
- 您可以填写乐鑫文档反馈表告诉我们如何改进该文档。