fix(esp_hw_support): Update key manager support

1) Added new Key Manager APIs
    2) Added crypto locking layer for Key Manager
    3) Remove support for deploying known key
    4) Format key manager support
    5) Fix build header error
    6) Updated the key_mgr_types.h file
    7) Added key manager tests
pull/13090/head
Aditya Patwardhan 2023-10-30 23:48:46 +05:30 zatwierdzone przez Mahavir Jain
rodzic 5a1726c18c
commit 4dc2ace0b7
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 99324EF4A00734E0
21 zmienionych plików z 1028 dodań i 261 usunięć

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -16,8 +16,8 @@
#include "esp_log.h"
#include "hal/wdt_hal.h"
#if CONFIG_IDF_TARGET_ESP32P4 //TODO-IDF-7925
#include "soc/keymng_reg.h"
#if SOC_KEY_MANAGER_SUPPORTED
#include "hal/key_mgr_hal.h"
#endif
#ifdef CONFIG_SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
@ -214,12 +214,6 @@ static esp_err_t check_and_generate_encryption_keys(void)
}
ESP_LOGI(TAG, "Using pre-loaded flash encryption key in efuse");
}
#if CONFIG_IDF_TARGET_ESP32P4 //TODO - IDF-7925
// Force Key Manager to use eFuse key for XTS-AES operation
REG_SET_FIELD(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY, 2);
#endif
return ESP_OK;
}

Wyświetl plik

@ -1,25 +1,93 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// The Hardware Support layer for Key manager
#include "hal/key_mgr_types.h"
#include "hal/key_mgr_hal.h"
#include "hal/huk_types.h"
#include "hal/huk_hal.h"
#include <string.h>
#include <sys/lock.h>
#include "assert.h"
#include "esp_key_mgr.h"
#include "esp_private/periph_ctrl.h"
#include "hal/key_mgr_ll.h"
#include "esp_crypto_lock.h"
#include "esp_log.h"
#include "esp_err.h"
#include "assert.h"
#include "string.h"
#include "esp_random.h"
#include "esp_heap_caps.h"
#include "esp_rom_crc.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "hal/key_mgr_types.h"
#include "hal/key_mgr_hal.h"
#include "hal/key_mgr_ll.h"
#include "hal/huk_types.h"
#include "hal/huk_hal.h"
#include "rom/key_mgr.h"
#if CONFIG_LOG_DEFAULT_LEVEL_VERBOSE
#include "soc/huk_reg.h"
#include "soc/keymng_reg.h"
#endif
static const char *TAG = "esp_key_mgr";
#define KEY_MANAGER_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
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;
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_info_t) == sizeof(struct key_info), "Size of esp_key_mgr_key_info_t should match key_info (from ROM)");
ESP_STATIC_ASSERT(sizeof(esp_key_mgr_huk_info_t) == sizeof(struct huk_info), "Size of esp_key_mgr_huk_info_t should match huk_info (from ROM)");
static void esp_key_mgr_acquire_key_lock(esp_key_mgr_key_type_t key_type)
{
switch (key_type) {
case ESP_KEY_MGR_ECDSA_KEY:
_lock_acquire(&s_key_mgr_ecdsa_key_lock);
break;
case ESP_KEY_MGR_XTS_AES_128_KEY:
case ESP_KEY_MGR_XTS_AES_256_KEY:
_lock_acquire(&s_key_mgr_xts_aes_key_lock);
break;
}
}
static void esp_key_mgr_release_key_lock(esp_key_mgr_key_type_t key_type)
{
switch (key_type) {
case ESP_KEY_MGR_ECDSA_KEY:
_lock_release(&s_key_mgr_xts_aes_key_lock);
break;
case ESP_KEY_MGR_XTS_AES_128_KEY:
case ESP_KEY_MGR_XTS_AES_256_KEY:
_lock_release(&s_key_mgr_ecdsa_key_lock);
break;
}
}
static void esp_key_mgr_acquire_hardware(void)
{
esp_crypto_key_manager_lock_acquire();
// Reset the Key Manager Clock
KEY_MANAGER_RCC_ATOMIC() {
key_mgr_ll_enable_bus_clock(true);
key_mgr_ll_reset_register();
}
}
static void esp_key_mgr_release_hardware(void)
{
esp_crypto_key_manager_lock_release();
// Reset the Key Manager Clock
KEY_MANAGER_RCC_ATOMIC() {
key_mgr_ll_enable_bus_clock(false);
key_mgr_ll_reset_register();
}
}
static void key_mgr_wait_for_state(esp_key_mgr_state_t state)
{
while (key_mgr_hal_get_state() != state) {
@ -27,220 +95,617 @@ static void key_mgr_wait_for_state(esp_key_mgr_state_t state)
}
}
esp_err_t esp_key_mgr_deploy_key_in_aes_mode(esp_key_mgr_aes_key_config_t *key_config, esp_key_mgr_key_recovery_info_t *key_info)
typedef struct aes_deploy {
esp_key_mgr_key_purpose_t key_purpose;
const uint8_t *k1_encrypted;
const esp_key_mgr_aes_key_config_t *key_config;
esp_key_mgr_key_recovery_info_t *key_info;
} aes_deploy_config_t;
static void check_huk_risk_level(void)
{
ESP_LOGI(TAG, "Key Deployment");
// Reset the Key Manager Clock
KEY_MANAGER_RCC_ATOMIC() {
key_mgr_ll_enable_bus_clock(true);
key_mgr_ll_reset_register();
uint8_t huk_risk_level = huk_hal_get_risk_level();
if (huk_risk_level > KEY_MGR_HUK_RISK_ALERT_LEVEL) {
ESP_LOGE(TAG, "HUK Risk level too high (level %d)\n"
"It is recommended to immediately regenerate HUK in order"
"to avoid permenantly losing the deployed keys", huk_risk_level);
} else {
ESP_LOGI(TAG, "HUK Risk level - %d within acceptable limit (%d)", huk_risk_level, KEY_MGR_HUK_RISK_ALERT_LEVEL);
}
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_IDLE);
}
static bool check_huk_validity(const esp_key_mgr_huk_info_t *huk_info)
{
uint32_t calc_crc = esp_rom_crc32_le(0, huk_info->info, KEY_MGR_HUK_INFO_SIZE);
if (calc_crc != huk_info->crc) {
ESP_LOGE(TAG, "Calculated CRC for HUK %lX does not match with %lX", calc_crc, huk_info->crc);
return false;
}
return true;
}
static bool check_key_info_validity(const esp_key_mgr_key_info_t *key_info)
{
uint32_t calc_crc = esp_rom_crc32_le(0, key_info->info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
if (calc_crc != key_info->crc) {
ESP_LOGE(TAG, "Calculated CRC for Key info %lX does not match with %lX", calc_crc, key_info->crc);
return false;
}
return true;
}
typedef struct {
bool use_pre_generated_huk_info;
const esp_key_mgr_huk_info_t *pre_generated_huk_info;
esp_key_mgr_huk_info_t *huk_recovery_info;
} huk_deploy_config_t;
static esp_err_t deploy_huk(huk_deploy_config_t *config)
{
esp_err_t esp_ret = ESP_FAIL;
uint8_t *huk_recovery_info = (uint8_t *) heap_caps_calloc(1, KEY_MGR_HUK_INFO_SIZE, MALLOC_CAP_INTERNAL);
if (!huk_recovery_info) {
return ESP_ERR_NO_MEM;
}
if (config->use_pre_generated_huk_info) {
// If HUK info is provided then recover the HUK from given info
check_huk_risk_level();
if (!check_huk_validity(config->pre_generated_huk_info)) {
ESP_LOGE(TAG, "HUK info is not valid");
heap_caps_free(huk_recovery_info);
return ESP_ERR_INVALID_ARG;
}
memcpy(huk_recovery_info, config->pre_generated_huk_info->info, KEY_MGR_HUK_INFO_SIZE);
ESP_LOGI(TAG, "Recovering key from given HUK recovery info");
esp_ret = huk_hal_configure(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);
return esp_ret;
}
// Copy the pre generated huk info in the output key recovery info
memcpy(config->huk_recovery_info->info, huk_recovery_info, KEY_MGR_HUK_INFO_SIZE);
config->huk_recovery_info->crc = config->pre_generated_huk_info->crc;
} 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);
if (esp_ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to generate HUK");
heap_caps_free(huk_recovery_info);
return esp_ret;
}
memcpy(config->huk_recovery_info->info, huk_recovery_info, KEY_MGR_HUK_INFO_SIZE);
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_LOGI(TAG, "HUK recovery/generation successfull");
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);
return ESP_OK;
}
static esp_err_t key_mgr_deploy_key_aes_mode(aes_deploy_config_t *config)
{
esp_err_t esp_ret = ESP_FAIL;
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_IDLE);
if (!key_mgr_hal_is_huk_valid()) {
// For purpose ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_2 this part shall be already executed
huk_deploy_config_t huk_deploy_config;
huk_deploy_config.use_pre_generated_huk_info = config->key_config->use_pre_generated_huk_info;
huk_deploy_config.pre_generated_huk_info = &config->key_config->huk_info;
huk_deploy_config.huk_recovery_info = &config->key_info->huk_info;
esp_ret = deploy_huk(&huk_deploy_config);
if (esp_ret != ESP_OK) {
return esp_ret;
}
}
ESP_LOGI(TAG, "HUK deployed is Valid");
// STEP 1: Init Step
// Set mode
key_mgr_hal_set_key_generator_mode(ESP_KEY_MGR_KEYGEN_MODE_AES);
uint8_t *key_recovery_info = (uint8_t *) heap_caps_calloc(1, KEY_MGR_KEY_RECOVERY_INFO_SIZE, MALLOC_CAP_INTERNAL);
if (!key_recovery_info) {
return ESP_ERR_NO_MEM;
}
// Set key purpose (XTS/ECDSA)
ESP_LOGI(TAG, "purpose = %d", config->key_purpose);
key_mgr_hal_set_key_purpose(config->key_purpose);
if (key_config->huk_info && key_config->huk_info_size) {
if (key_config->huk_info_size != KEY_MGR_HUK_INFO_SIZE) {
ESP_LOGE(TAG, "Invalid HUK info given");
return ESP_ERR_INVALID_ARG;
}
ESP_LOGI(TAG, "Recovering key from given HUK recovery info");
// If HUK info is provided then recover the HUK from given info
huk_hal_configure(ESP_HUK_MODE_RECOVERY, key_config->huk_info);
} else {
// Generate new HUK and corresponding HUK info
ESP_LOGI(TAG, "Generating new HUK");
huk_hal_configure(ESP_HUK_MODE_GENERATION, huk_recovery_info);
// Set key length for XTS-AES key
esp_key_mgr_key_type_t key_type = (esp_key_mgr_key_type_t) config->key_config->key_type;
if (key_type == ESP_KEY_MGR_XTS_AES_128_KEY) {
key_mgr_hal_set_xts_aes_key_len(ESP_KEY_MGR_XTS_AES_LEN_256);
} else if (key_type == ESP_KEY_MGR_XTS_AES_256_KEY) {
key_mgr_hal_set_xts_aes_key_len(ESP_KEY_MGR_XTS_AES_LEN_512);
}
ESP_LOGI(TAG, "HUK generated successfully");
// Configure deployment mode to AES
key_mgr_hal_set_key_generator_mode(ESP_KEY_MGR_KEYGEN_MODE_AES);
// Set key purpose (XTS/ECDSA)
key_mgr_hal_set_key_purpose(key_config->key_purpose);
if (key_config->use_sw_init_key) {
if (config->key_config->use_pre_generated_sw_init_key) {
key_mgr_hal_use_sw_init_key();
}
key_mgr_hal_start();
key_mgr_hal_continue();
// Step 2: Load phase
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_LOAD);
if (key_config->use_sw_init_key) {
assert(key_config->sw_init_key_size == KEY_MGR_SW_INIT_KEY_SIZE);
key_mgr_hal_write_sw_init_key(key_config->sw_init_key, key_config->sw_init_key_size);
if (config->key_config->use_pre_generated_sw_init_key) {
key_mgr_hal_write_sw_init_key(config->key_config->sw_init_key, KEY_MGR_SW_INIT_KEY_SIZE);
}
ESP_LOG_BUFFER_HEX_LEVEL("SW_INIT_KEY", config->key_config->sw_init_key, KEY_MGR_SW_INIT_KEY_SIZE, ESP_LOG_DEBUG);
ESP_LOGI(TAG, "Writing Information into Key Manager Registers");
key_mgr_hal_write_assist_info(key_config->k2_info, KEY_MGR_K2_INFO_SIZE);
key_mgr_hal_write_public_info(key_config->k1_encrypted, KEY_MGR_K1_ENCRYPTED_SIZE);
key_mgr_hal_write_assist_info(config->key_config->k2_info, KEY_MGR_K2_INFO_SIZE);
ESP_LOG_BUFFER_HEX_LEVEL("K2_INFO", config->key_config->k2_info, KEY_MGR_K2_INFO_SIZE, ESP_LOG_DEBUG);
key_mgr_hal_write_public_info(config->k1_encrypted, KEY_MGR_K1_ENCRYPTED_SIZE);
ESP_LOG_BUFFER_HEX_LEVEL("K1_ENCRYPTED", config->k1_encrypted, KEY_MGR_K1_ENCRYPTED_SIZE, ESP_LOG_INFO);
key_mgr_hal_continue();
// Step 3: Gain phase
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_GAIN);
key_mgr_hal_read_public_info(key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
ESP_LOG_BUFFER_HEX_LEVEL("HUK INFO", huk_recovery_info, KEY_MGR_HUK_INFO_SIZE, ESP_LOG_INFO);
ESP_LOG_BUFFER_HEX_LEVEL("KEY_MGR KEY INFO", key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE, ESP_LOG_INFO);
ESP_LOG_BUFFER_HEX_LEVEL("KEY_RECOVERY_INFO", key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE, ESP_LOG_DEBUG);
//TODO - check if HUK is valid just after it is generated
if (!key_mgr_hal_is_huk_valid()) {
ESP_LOGE(TAG, "HUK is invalid");
// TODO - define error code
return ESP_FAIL;
if (config->key_purpose != ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_1) {
if (!key_mgr_hal_is_key_deployment_valid(config->key_config->key_type)) {
ESP_LOGE(TAG, "Key deployment is not valid");
heap_caps_free(key_recovery_info);
return ESP_FAIL;
}
ESP_LOGI(TAG, "Key deployment valid");
}
ESP_LOGI(TAG, "HUK deplpoyed is Valid");
if (!key_mgr_hal_is_key_deployment_valid(key_config->key_type)) {
ESP_LOGE(TAG, "Key deployment is not valid");
// Todo - Define respective error code;
return ESP_FAIL;
}
ESP_LOGI(TAG, "Key deployment valid");
// Wait till Key Manager deployment is complete
key_mgr_hal_continue();
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_IDLE);
//memcpy(&key_info->huk_recovery_info[0], huk_recovery_info, KEY_MGR_HUK_INFO_SIZE);
//memcpy(&key_info->key_recovery_info[0], key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
key_info->key_purpose = key_config->key_purpose;
if (config->key_purpose == ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_2) {
memcpy(config->key_info->key_info[1].info, key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
config->key_info->key_info[1].crc = esp_rom_crc32_le(0, key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
} else {
memcpy(config->key_info->key_info[0].info, key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
config->key_info->key_info[0].crc = esp_rom_crc32_le(0, key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
}
heap_caps_free(key_recovery_info);
heap_caps_free(huk_recovery_info);
key_mgr_hal_set_key_usage(ESP_KEY_MGR_XTS_KEY, ESP_KEY_MGR_USE_OWN_KEY);
return ESP_OK;
}
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_recovery_info)
{
ESP_LOGI(TAG, "Key deployment in AES mode");
aes_deploy_config_t aes_deploy_config;
aes_deploy_config.key_config = key_config;
aes_deploy_config.key_info = key_recovery_info;
aes_deploy_config.k1_encrypted = key_config->k1_encrypted[0];
esp_key_mgr_key_type_t key_type = (esp_key_mgr_key_type_t) key_config->key_type;
if (key_type == ESP_KEY_MGR_ECDSA_KEY) {
aes_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_ECDSA;
} else if (key_type == ESP_KEY_MGR_XTS_AES_128_KEY) {
aes_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_128;
} 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;
} else {
ESP_LOGE(TAG, "Invalid key type");
return ESP_ERR_INVALID_ARG;
}
esp_key_mgr_acquire_hardware();
esp_err_t esp_ret = key_mgr_deploy_key_aes_mode(&aes_deploy_config);
if (esp_ret != ESP_OK) {
ESP_LOGE(TAG, "Key deployment in AES mode failed");
}
if (key_type == ESP_KEY_MGR_XTS_AES_256_KEY) {
aes_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_2;
aes_deploy_config.k1_encrypted = key_config->k1_encrypted[1];
esp_ret = key_mgr_deploy_key_aes_mode(&aes_deploy_config);
if (esp_ret != ESP_OK) {
ESP_LOGE(TAG, "Key deployment in AES mode failed");
}
}
// Set the Key Manager Static Register to use own key for the respective key type
key_mgr_hal_set_key_usage(key_type, ESP_KEY_MGR_USE_OWN_KEY);
KEY_MANAGER_RCC_ATOMIC() {
key_mgr_ll_enable_bus_clock(false);
key_mgr_ll_reset_register();
}
return ESP_OK;
return esp_ret;
}
esp_err_t esp_key_mgr_recover_key(esp_key_mgr_key_recovery_info_t *key_recovery_info)
typedef struct key_recovery_config {
esp_key_mgr_key_purpose_t key_purpose;
esp_key_mgr_key_recovery_info_t *key_recovery_info;
} key_recovery_config_t;
static esp_err_t key_mgr_recover_key(key_recovery_config_t *config)
{
KEY_MANAGER_RCC_ATOMIC() {
key_mgr_ll_enable_bus_clock(true);
key_mgr_ll_reset_register();
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_IDLE);
if (!check_huk_validity(&config->key_recovery_info->huk_info)) {
ESP_LOGE(TAG, "HUK info is not valid");
return ESP_ERR_INVALID_ARG;
}
ESP_LOGD(TAG, "HUK info valid");
if (!key_mgr_hal_is_huk_valid()) {
check_huk_risk_level();
esp_err_t esp_ret = huk_hal_configure(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;
}
ESP_LOGI(TAG, "HUK deployed is Valid");
ESP_LOG_BUFFER_HEX_LEVEL("HUK INFO", config->key_recovery_info->huk_info.info, KEY_MGR_HUK_INFO_SIZE, ESP_LOG_DEBUG);
}
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_IDLE);
huk_hal_configure(ESP_HUK_MODE_RECOVERY, key_recovery_info->huk_recovery_info);
if (key_mgr_hal_is_huk_valid()) {
ESP_LOGD(TAG, "HUK is invalid");
// TODO - define error code
return ESP_FAIL;
key_mgr_hal_set_key_generator_mode(ESP_KEY_MGR_KEYGEN_MODE_RECOVER);
// Set AES-XTS key len
esp_key_mgr_key_type_t key_type = (esp_key_mgr_key_type_t) config->key_recovery_info->key_type;
if (key_type == ESP_KEY_MGR_XTS_AES_128_KEY) {
key_mgr_hal_set_xts_aes_key_len(ESP_KEY_MGR_XTS_AES_LEN_256);
} else if (key_type == ESP_KEY_MGR_XTS_AES_256_KEY) {
key_mgr_hal_set_xts_aes_key_len(ESP_KEY_MGR_XTS_AES_LEN_512);
}
ESP_LOGI(TAG, "purpose = %d", key_recovery_info->key_purpose);
key_mgr_hal_set_key_purpose(key_recovery_info->key_purpose);
key_mgr_hal_set_key_purpose(config->key_purpose);
key_mgr_hal_start();
key_mgr_hal_continue();
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_LOAD);
key_mgr_hal_write_assist_info(key_recovery_info->huk_recovery_info, KEY_MGR_HUK_INFO_SIZE);
if (config->key_purpose == ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_2) {
if (!check_key_info_validity(&config->key_recovery_info->key_info[1])) {
ESP_LOGE(TAG, "Key info not valid");
return ESP_FAIL;
}
key_mgr_hal_write_assist_info(config->key_recovery_info->key_info[1].info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
} else {
if (!check_key_info_validity(&config->key_recovery_info->key_info[0])) {
ESP_LOGE(TAG, "Key info not valid");
return ESP_FAIL;
}
key_mgr_hal_write_assist_info(config->key_recovery_info->key_info[0].info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
ESP_LOG_BUFFER_HEX_LEVEL("RECOVERY_INFO", config->key_recovery_info->key_info[0].info, KEY_MGR_KEY_RECOVERY_INFO_SIZE, ESP_LOG_INFO);
}
key_mgr_hal_continue();
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_GAIN);
if (!key_mgr_hal_is_key_deployment_valid(key_recovery_info->key_type)) {
ESP_LOGD(TAG, "Key deployment is not valid");
// Todo - Define respective error code;
return ESP_FAIL;
if (config->key_purpose != ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_1) {
if (!key_mgr_hal_is_key_deployment_valid(config->key_recovery_info->key_type)) {
ESP_LOGD(TAG, "Key deployment is not valid");
return ESP_FAIL;
}
ESP_LOGI(TAG, "Key Recovery valid");
}
ESP_LOGI(TAG, "Key deployment valid");
key_mgr_hal_continue();
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_IDLE);
KEY_MANAGER_RCC_ATOMIC() {
key_mgr_ll_enable_bus_clock(false);
key_mgr_ll_reset_register();
}
return ESP_OK;
}
esp_err_t esp_key_mgr_deploy_key_in_ecdh0_mode(esp_key_mgr_ecdh0_key_config_t *key_config, esp_key_mgr_key_recovery_info_t *key_info)
esp_err_t esp_key_mgr_activate_key(esp_key_mgr_key_recovery_info_t *key_recovery_info)
{
ESP_LOGI(TAG, "Key Deployment");
// Reset the Key Manager Clock
KEY_MANAGER_RCC_ATOMIC() {
key_mgr_ll_enable_bus_clock(true);
key_mgr_ll_reset_register();
esp_key_mgr_key_purpose_t key_purpose;
esp_key_mgr_key_type_t key_type = (esp_key_mgr_key_type_t) key_recovery_info->key_type;
if (key_type == ESP_KEY_MGR_ECDSA_KEY) {
key_purpose = ESP_KEY_MGR_KEY_PURPOSE_ECDSA;
} else if (key_type == ESP_KEY_MGR_XTS_AES_128_KEY) {
key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_128;
} else if (key_type == ESP_KEY_MGR_XTS_AES_256_KEY) {
key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_1;
} else {
ESP_LOGE(TAG, "Invalid key type");
return ESP_ERR_INVALID_ARG;
}
esp_err_t esp_ret = ESP_FAIL;
esp_key_mgr_acquire_key_lock(key_type);
key_recovery_config_t key_recovery_config;
key_recovery_config.key_recovery_info = key_recovery_info;
key_recovery_config.key_purpose = key_purpose;
esp_key_mgr_acquire_hardware();
esp_ret = key_mgr_recover_key(&key_recovery_config);
if (esp_ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to recover key");
goto cleanup;
}
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_IDLE);
uint8_t *huk_recovery_info = (uint8_t *) heap_caps_calloc(1, KEY_MGR_HUK_INFO_SIZE, MALLOC_CAP_INTERNAL);
if (!huk_recovery_info) {
return ESP_ERR_NO_MEM;
if (key_recovery_info->key_type == ESP_KEY_MGR_XTS_AES_256_KEY) {
key_recovery_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_2;
esp_ret = key_mgr_recover_key(&key_recovery_config);
if (esp_ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to recover key");
goto cleanup;
}
}
// Set the Key Manager Static Register to use own key for the respective key type
key_mgr_hal_set_key_usage(key_recovery_info->key_type, ESP_KEY_MGR_USE_OWN_KEY);
cleanup:
esp_key_mgr_release_hardware();
return esp_ret;
}
esp_err_t esp_key_mgr_deactivate_key(esp_key_mgr_key_type_t key_type)
{
esp_key_mgr_release_key_lock(key_type);
esp_key_mgr_acquire_hardware();
esp_key_mgr_release_hardware();
return ESP_OK;
}
typedef struct ecdh0_config {
esp_key_mgr_key_purpose_t key_purpose;
const esp_key_mgr_ecdh0_key_config_t *key_config;
esp_key_mgr_key_recovery_info_t *key_info;
uint8_t *ecdh0_key_info;
} ecdh0_deploy_config_t;
static esp_err_t key_mgr_deploy_key_ecdh0_mode(ecdh0_deploy_config_t *config)
{
esp_err_t esp_ret = ESP_FAIL;
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_IDLE);
if (!key_mgr_hal_is_huk_valid()) {
// For purpose ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_2 this part shall be already executed
huk_deploy_config_t huk_deploy_config;
huk_deploy_config.use_pre_generated_huk_info = config->key_config->use_pre_generated_huk_info;
huk_deploy_config.pre_generated_huk_info = &config->key_config->huk_info;
huk_deploy_config.huk_recovery_info = &config->key_info->huk_info;
esp_ret = deploy_huk(&huk_deploy_config);
if (esp_ret != ESP_OK) {
return esp_ret;
}
}
ESP_LOGI(TAG, "HUK deployed is Valid");
uint8_t *key_recovery_info = (uint8_t *) heap_caps_calloc(1, KEY_MGR_KEY_RECOVERY_INFO_SIZE, MALLOC_CAP_INTERNAL);
if (!key_recovery_info) {
return ESP_ERR_NO_MEM;
}
if (key_config->huk_info && key_config->huk_info_size) {
if (key_config->huk_info_size != KEY_MGR_HUK_INFO_SIZE) {
ESP_LOGE(TAG, "Invalid HUK info given");
return ESP_ERR_INVALID_ARG;
}
ESP_LOGI(TAG, "Recovering key from given HUK recovery info");
// If HUK info is provided then recover the HUK from given info
huk_hal_configure(ESP_HUK_MODE_RECOVERY, key_config->huk_info);
} else {
// Generate new HUK and corresponding HUK info
ESP_LOGI(TAG, "Generating new HUK");
huk_hal_configure(ESP_HUK_MODE_GENERATION, huk_recovery_info);
}
// Step 1 : Initialization
// Configure deployment mode to ECDH0
key_mgr_hal_set_key_generator_mode(ESP_KEY_MGR_KEYGEN_MODE_ECDH0);
ESP_LOGI(TAG, "HUK generated successfully");
// Configure deployment mode to AES
key_mgr_hal_set_key_generator_mode(ESP_KEY_MGR_KEYGEN_MODE_AES);
// Set AES-XTS key len
esp_key_mgr_key_type_t key_type = (esp_key_mgr_key_type_t) config->key_config->key_type;
if (key_type == ESP_KEY_MGR_XTS_AES_128_KEY) {
key_mgr_hal_set_xts_aes_key_len(ESP_KEY_MGR_XTS_AES_LEN_256);
} else if (key_type == ESP_KEY_MGR_XTS_AES_256_KEY) {
key_mgr_hal_set_xts_aes_key_len(ESP_KEY_MGR_XTS_AES_LEN_512);
}
// Set key purpose (XTS/ECDSA)
key_mgr_hal_set_key_purpose(key_config->key_purpose);
key_mgr_hal_set_key_purpose(config->key_purpose);
key_mgr_hal_start();
key_mgr_hal_continue();
if (key_config->use_sw_init_key) {
key_mgr_hal_use_sw_init_key();
// Step 2: Load phase
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_LOAD);
ESP_LOGD(TAG, "Writing Information into Key Manager Registers");
key_mgr_hal_write_public_info(config->key_config->k1_G, KEY_MGR_ECDH0_INFO_SIZE);
key_mgr_hal_continue();
// Step 3: Gain phase
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_GAIN);
key_mgr_hal_read_public_info(key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
key_mgr_hal_read_assist_info(config->ecdh0_key_info);
ESP_LOG_BUFFER_HEX_LEVEL("KEY_MGR KEY INFO", key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE, ESP_LOG_DEBUG);
ESP_LOGI(TAG, "HUK deplpoyed is Valid");
if (config->key_purpose != ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_1) {
if (!key_mgr_hal_is_key_deployment_valid(config->key_config->key_type)) {
ESP_LOGE(TAG, "Key deployment is not valid");
return ESP_FAIL;
}
ESP_LOGI(TAG, "Key deployment valid");
}
// Wait till Key Manager deployment is complete
key_mgr_hal_continue();
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_IDLE);
if (config->key_purpose == ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_2) {
memcpy(config->key_info->key_info[1].info, key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
config->key_info->key_info[1].crc = esp_rom_crc32_le(0, key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
} else {
memcpy(config->key_info->key_info[0].info, key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
config->key_info->key_info[0].crc = esp_rom_crc32_le(0, key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
}
config->key_info->key_type = config->key_config->key_type;
heap_caps_free(key_recovery_info);
return ESP_OK;
}
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)
{
ESP_LOGI(TAG, "Key Deployment in ECDH0 mode");
esp_key_mgr_key_purpose_t key_purpose;
esp_key_mgr_key_type_t key_type = (esp_key_mgr_key_type_t) key_config->key_type;
ecdh0_deploy_config_t ecdh0_deploy_config;
ecdh0_deploy_config.key_config = key_config;
ecdh0_deploy_config.key_info = key_info;
if (key_type == ESP_KEY_MGR_ECDSA_KEY) {
ecdh0_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_ECDSA;
ecdh0_deploy_config.ecdh0_key_info = ecdh0_key_info->k2_G[0];
} else if (key_type == ESP_KEY_MGR_XTS_AES_128_KEY) {
ecdh0_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_128;
ecdh0_deploy_config.ecdh0_key_info = ecdh0_key_info->k2_G[0];
} 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.ecdh0_key_info = ecdh0_key_info->k2_G[0];
} else {
ESP_LOGE(TAG, "Invalid key type");
return ESP_ERR_INVALID_ARG;
}
esp_key_mgr_acquire_hardware();
esp_err_t esp_ret = key_mgr_deploy_key_ecdh0_mode(&ecdh0_deploy_config);
if (esp_ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to deploy key in ECDH0 mode");
}
if (key_config->key_type == ESP_KEY_MGR_XTS_AES_256_KEY) {
key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_2;
ecdh0_deploy_config.key_purpose = key_purpose;
ecdh0_deploy_config.ecdh0_key_info = ecdh0_key_info->k2_G[1];
esp_ret = key_mgr_deploy_key_ecdh0_mode(&ecdh0_deploy_config);
if (esp_ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to deploy key in ECDH0 mode");
}
}
// Set the Key Manager Static Register to use own key for the respective key type
key_mgr_hal_set_key_usage(key_type, ESP_KEY_MGR_USE_OWN_KEY);
esp_key_mgr_release_hardware();
return ESP_OK;
}
typedef struct random_deploy {
esp_key_mgr_key_purpose_t key_purpose;
const esp_key_mgr_random_key_config_t *key_config;
esp_key_mgr_key_recovery_info_t *key_info;
} random_deploy_config_t;
static esp_err_t key_mgr_deploy_key_random_mode(random_deploy_config_t *config)
{
esp_err_t esp_ret = ESP_FAIL;
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_IDLE);
if (!key_mgr_hal_is_huk_valid()) {
// For purpose ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_2 this part shall be already executed
huk_deploy_config_t huk_deploy_config;
huk_deploy_config.use_pre_generated_huk_info = config->key_config->use_pre_generated_huk_info;
huk_deploy_config.pre_generated_huk_info = &config->key_config->huk_info;
huk_deploy_config.huk_recovery_info = &config->key_info->huk_info;
esp_ret = deploy_huk(&huk_deploy_config);
if (esp_ret != ESP_OK) {
return esp_ret;
}
}
ESP_LOGI(TAG, "HUK deployed is Valid");
// Configure deployment mode to RANDOM
key_mgr_hal_set_key_generator_mode(ESP_KEY_MGR_KEYGEN_MODE_RANDOM);
// Set AES-XTS key len
esp_key_mgr_key_type_t key_type = (esp_key_mgr_key_type_t) config->key_config->key_type;
if (key_type == ESP_KEY_MGR_XTS_AES_128_KEY) {
key_mgr_hal_set_xts_aes_key_len(ESP_KEY_MGR_XTS_AES_LEN_256);
} else if (key_type == ESP_KEY_MGR_XTS_AES_256_KEY) {
key_mgr_hal_set_xts_aes_key_len(ESP_KEY_MGR_XTS_AES_LEN_512);
}
uint8_t *key_recovery_info = (uint8_t *) heap_caps_calloc(1, KEY_MGR_KEY_RECOVERY_INFO_SIZE, MALLOC_CAP_INTERNAL);
if (!key_recovery_info) {
return ESP_ERR_NO_MEM;
}
// Set key purpose (XTS/ECDSA)
key_mgr_hal_set_key_purpose(config->key_purpose);
key_mgr_hal_start();
key_mgr_hal_continue();
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_LOAD);
if (key_config->use_sw_init_key) {
assert(key_config->sw_init_key_size == KEY_MGR_SW_INIT_KEY_SIZE);
key_mgr_hal_write_sw_init_key(key_config->sw_init_key, key_config->sw_init_key_size);
}
ESP_LOGI(TAG, "Writing Information into Key Manager Registers");
key_mgr_hal_write_public_info(key_config->k1_G, KEY_MGR_ECDH0_INFO_SIZE);
key_mgr_hal_continue();
// No configuration for Random deploy mode
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_GAIN);
key_mgr_hal_read_public_info(key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
key_mgr_hal_read_assist_info(key_config->k2_G);
ESP_LOG_BUFFER_HEX_LEVEL("HUK INFO", huk_recovery_info, KEY_MGR_HUK_INFO_SIZE, ESP_LOG_INFO);
ESP_LOG_BUFFER_HEX_LEVEL("KEY_MGR KEY INFO", key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE, ESP_LOG_INFO);
ESP_LOG_BUFFER_HEX_LEVEL("KEY_MGR KEY INFO", key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE, ESP_LOG_DEBUG);
//TODO - check if HUK is valid just after it is generated
if (!key_mgr_hal_is_huk_valid()) {
ESP_LOGE(TAG, "HUK is invalid");
// TODO - define error code
return ESP_FAIL;
if (config->key_purpose != ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_1) {
if (!key_mgr_hal_is_key_deployment_valid(config->key_config->key_type)) {
ESP_LOGE(TAG, "Key deployment is not valid");
heap_caps_free(key_recovery_info);
return ESP_FAIL;
}
ESP_LOGI(TAG, "Key deployment valid");
}
ESP_LOGI(TAG, "HUK deplpoyed is Valid");
if (!key_mgr_hal_is_key_deployment_valid(key_config->key_type)) {
ESP_LOGE(TAG, "Key deployment is not valid");
// Todo - Define respective error code;
return ESP_FAIL;
}
ESP_LOGI(TAG, "Key deployment valid");
// Wait till Key Manager deployment is complete
key_mgr_hal_continue();
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_IDLE);
//memcpy(&key_info->huk_recovery_info[0], huk_recovery_info, KEY_MGR_HUK_INFO_SIZE);
//memcpy(&key_info->key_recovery_info[0], key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
key_info->key_purpose = key_config->key_purpose;
heap_caps_free(key_recovery_info);
heap_caps_free(huk_recovery_info);
ESP_LOGI(TAG, "\nKey deployment complete\n");
//key_mgr_hal_set_key_usage(ESP_KEY_MGR_XTS_KEY, ESP_KEY_MGR_USE_OWN_KEY);
KEY_MANAGER_RCC_ATOMIC() {
key_mgr_ll_enable_bus_clock(false);
key_mgr_ll_reset_register();
if (config->key_purpose == ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_2) {
memcpy(config->key_info->key_info[1].info, key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
config->key_info->key_info[1].crc = esp_rom_crc32_le(0, key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
} else {
memcpy(config->key_info->key_info[0].info, key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
config->key_info->key_info[0].crc = esp_rom_crc32_le(0, key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
}
heap_caps_free(key_recovery_info);
return ESP_OK;
}
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_recovery_info)
{
ESP_LOGI(TAG, "Key deployment in Random mode");
random_deploy_config_t random_deploy_config;
random_deploy_config.key_config = key_config;
random_deploy_config.key_info = key_recovery_info;
esp_key_mgr_key_type_t key_type = (esp_key_mgr_key_type_t) key_config->key_type;
if (key_type == ESP_KEY_MGR_ECDSA_KEY) {
random_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_ECDSA;
} else if (key_type == ESP_KEY_MGR_XTS_AES_128_KEY) {
random_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_128;
} 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;
} else {
ESP_LOGE(TAG, "Invalid key type");
return ESP_ERR_INVALID_ARG;
}
esp_key_mgr_acquire_hardware();
esp_err_t esp_ret = key_mgr_deploy_key_random_mode(&random_deploy_config);
if (esp_ret != ESP_OK) {
ESP_LOGE(TAG, "Key deployment in Random mode failed");
return ESP_FAIL;
}
if (key_type == ESP_KEY_MGR_XTS_AES_256_KEY) {
random_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_2;
esp_ret = key_mgr_deploy_key_random_mode(&random_deploy_config);
if (esp_ret != ESP_OK) {
ESP_LOGE(TAG, "Key deployment in Random mode failed");
return ESP_FAIL;
}
}
// Set the Key Manager Static Register to use own key for the respective key type
key_mgr_hal_set_key_usage(key_config->key_type, ESP_KEY_MGR_USE_OWN_KEY);
esp_key_mgr_release_hardware();
return esp_ret;
}

Wyświetl plik

@ -1,11 +1,14 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_err.h"
#include "soc/soc_caps.h"
#if SOC_KEY_MANAGER_SUPPORTED
#ifdef __cplusplus
extern "C" {
@ -13,81 +16,113 @@ extern "C" {
#include "hal/key_mgr_types.h"
#include "hal/huk_types.h"
#include "esp_attr.h"
#define KEY_MGR_SW_INIT_KEY_SIZE 32
#define KEY_MGR_ASSIST_INFO_SIZE 64
#define KEY_MGR_KEY_RECOVERY_INFO_SIZE 64
#define KEY_MGR_HUK_INFO_SIZE HUK_INFO_SIZE
#define KEY_MGR_HUK_RISK_ALERT_LEVEL HUK_RISK_ALERT_LEVEL
/* AES deploy mode */
#define KEY_MGR_K2_INFO_SIZE 64
#define KEY_MGR_K1_ENCRYPTED_SIZE 32
#define KEY_MGR_ECDH0_INFO_SIZE 64
#define KEY_MGR_ECDH0_INFO_SIZE 64
#define KEY_MGR_PLAINTEXT_KEY_SIZE 32
typedef struct {
// TODO - Should we use fixed arrays here instead of pointers ?
esp_key_mgr_key_type_t key_type;
uint8_t *huk_info;
size_t huk_info_size;
esp_key_mgr_key_purpose_t key_purpose;
bool use_sw_init_key;
uint8_t *sw_init_key;
size_t sw_init_key_size;
uint8_t k2_info[KEY_MGR_K2_INFO_SIZE];
uint8_t k1_encrypted[KEY_MGR_K1_ENCRYPTED_SIZE];
bool use_pre_generated_huk_info;
bool use_pre_generated_sw_init_key;
WORD_ALIGNED_ATTR esp_key_mgr_huk_info_t huk_info;
WORD_ALIGNED_ATTR uint8_t sw_init_key[KEY_MGR_SW_INIT_KEY_SIZE];
WORD_ALIGNED_ATTR uint8_t k2_info[KEY_MGR_K2_INFO_SIZE];
WORD_ALIGNED_ATTR uint8_t k1_encrypted[2][KEY_MGR_K1_ENCRYPTED_SIZE];
} esp_key_mgr_aes_key_config_t;
typedef struct {
// TODO - Should we use fixed arrays here instead of pointers ?
esp_key_mgr_key_type_t key_type;
uint8_t *huk_info;
size_t huk_info_size;
esp_key_mgr_key_purpose_t key_purpose;
bool use_sw_init_key;
uint8_t *sw_init_key;
size_t sw_init_key_size;
uint8_t k1_G[KEY_MGR_ECDH0_INFO_SIZE];
uint8_t k2_G[KEY_MGR_ECDH0_INFO_SIZE];
bool use_pre_generated_huk_info;
WORD_ALIGNED_ATTR esp_key_mgr_huk_info_t huk_info;
WORD_ALIGNED_ATTR uint8_t k1_G[KEY_MGR_ECDH0_INFO_SIZE];
} esp_key_mgr_ecdh0_key_config_t;
typedef struct {
uint8_t huk_recovery_info[KEY_MGR_HUK_INFO_SIZE];
uint8_t key_recovery_info[KEY_MGR_KEY_RECOVERY_INFO_SIZE];
esp_key_mgr_key_type_t key_type;
esp_key_mgr_key_purpose_t key_purpose;
} __attribute__((packed)) esp_key_mgr_key_recovery_info_t;
bool use_pre_generated_huk_info;
WORD_ALIGNED_ATTR esp_key_mgr_huk_info_t huk_info;
} esp_key_mgr_random_key_config_t;
typedef struct {
esp_key_mgr_key_type_t key_type;
WORD_ALIGNED_ATTR uint8_t k2_G[2][KEY_MGR_ECDH0_INFO_SIZE];
} esp_key_mgr_ecdh0_info_t;
/**
* @brief Check if the deployed key is valid or not
* @brief Deploy key in AES deployment mode
* @input
* key_config(input) AES key configuration
* key_info(output) A writable struct of esp_key_mgr_key_info_t type. The recovery key info for the deplyed key shall be stored here
* key_info(output) A writable struct of esp_key_mgr_key_info_t type.
* The recovery information for the the deployed key shall be stored here
* @return
* ESP_OK for success
* ESP_FAIL/relevant error code for failure
*/
esp_err_t esp_key_mgr_deploy_key_in_aes_mode(esp_key_mgr_aes_key_config_t *key_config, esp_key_mgr_key_recovery_info_t *key_info);
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);
/**
* @brief Check if the deployed key is valid or not
* @brief Deploy key in ECDH0 deployment mode
* @input
* key_config(input) AES key configuration
* key_info(output) A writable struct of esp_key_mgr_key_info_t type. The recovery key info for the deplyed key shall be stored here
* key_config(input) ECDH0 key configuration
* key_info(output) A writable struct of esp_key_mgr_key_info_t type. The recovery key info for the deployed key shall be stored here
* ecdh0_key_info A writable struct of esp_key_mgr_ecdh0_info_t. The ecdh0 info to recover the actual key shall be stored here.
* @return
* ESP_OK for success
* ESP_FAIL/relevant error code for failure
*/
esp_err_t esp_key_mgr_deploy_key_in_ecdh0_mode(esp_key_mgr_ecdh0_key_config_t *key_config, esp_key_mgr_key_recovery_info_t *key_info);
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);
/**
* @brief Deploy key in Random deployment mode
* @input
* key_config(input) Random key configuration
* key_info(output) A writable struct of esp_key_mgr_key_info_t type. The recovery key info for the deployed key shall be stored here
* @return
* ESP_OK for success
* ESP_FAIL/relevant error code for 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);
/*
* @brief Recover a key from the given key info
* @brief Recover and Activate a key from the given key info
*
* @note
* 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
* @input
* key_info The key info required to recover the key
* @return
* ESP_OK for success
* ESP_FAIL/revevant error code for failure
* ESP_FAIL/relevant error code for failure
*/
esp_err_t esp_key_mgr_recover_key(esp_key_mgr_key_recovery_info_t *key_recovery_info);
esp_err_t esp_key_mgr_activate_key(esp_key_mgr_key_recovery_info_t *key_recovery_info);
/*
* @brief De-activate a key from the given key info
* The key which is de-activated can no longer be used for any operation
* @input
* key_info The key info required to recover the key
* @return
* ESP_OK for success
* ESP_FAIL/relevant error code for failure
*/
esp_err_t esp_key_mgr_deactivate_key(esp_key_mgr_key_type_t key_type);
#ifdef __cplusplus
}
#endif
#endif

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -91,6 +91,18 @@ void esp_crypto_ecdsa_lock_acquire(void);
*/
void esp_crypto_ecdsa_lock_release(void);
/**
* @brief Acquire lock for Key Manager peripheral
*
*/
void esp_crypto_key_manager_lock_acquire(void);
/**
* @brief Release lock for Key Manager peripheral
*
*/
void esp_crypto_key_manager_lock_release(void);
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -36,6 +36,9 @@ static _lock_t s_crypto_ecc_lock;
/* Lock for ECDSA peripheral */
static _lock_t s_crypto_ecdsa_lock;
/* Lock for Key Manager peripheral */
static _lock_t s_crypto_key_manager_lock;
void esp_crypto_hmac_lock_acquire(void)
{
_lock_acquire(&s_crypto_hmac_lock);
@ -105,3 +108,17 @@ void esp_crypto_ecdsa_lock_release(void)
esp_crypto_ecc_lock_release();
_lock_release(&s_crypto_ecdsa_lock);
}
void esp_crypto_key_manager_lock_acquire(void)
{
_lock_acquire(&s_crypto_key_manager_lock);
esp_crypto_ecc_lock_acquire();
esp_crypto_sha_aes_lock_acquire();
}
void esp_crypto_key_manager_lock_release(void)
{
esp_crypto_sha_aes_lock_release();
esp_crypto_ecc_lock_release();
_lock_release(&s_crypto_key_manager_lock);
}

Wyświetl plik

@ -6,6 +6,7 @@ set(srcs "test_app_main.c"
"test_ds.c"
"test_hmac.c"
"test_random.c"
"test_key_mgr.c"
)
if(CONFIG_SOC_MULTI_USAGE_LDO_SUPPORTED)
@ -19,5 +20,5 @@ endif()
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
# the component can be registered as WHOLE_ARCHIVE
idf_component_register(SRCS ${srcs}
REQUIRES unity esp_driver_gpio esp_driver_gptimer esp_driver_uart test_utils efuse
REQUIRES unity esp_driver_gpio esp_driver_gptimer esp_driver_uart test_utils efuse spi_flash
WHOLE_ARCHIVE)

Wyświetl plik

@ -0,0 +1,140 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <string.h>
#include "unity.h"
#include "soc/soc_caps.h"
#if SOC_KEY_MANAGER_SUPPORTED
#include "esp_partition.h"
#include "esp_flash.h"
#include "esp_log.h"
#include "esp_err.h"
#if CONFIG_IDF_TARGET_ESP32P4
#include "esp32p4/rom/efuse.h"
#endif
#include "soc/keymng_reg.h"
#include "esp_key_mgr.h"
static const char *TAG = "key_mgr_test";
#define ENCRYPTED_DATA_SIZE 128
static const uint8_t plaintext_data[ENCRYPTED_DATA_SIZE] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80,
};
static const uint8_t expected_ciphertext[ENCRYPTED_DATA_SIZE] = {
0x10, 0x5d, 0x20, 0x41, 0x87, 0xb7, 0x16, 0x09, 0x3f, 0x67, 0x32, 0x79, 0x06, 0x53, 0x97, 0x53,
0x2b, 0x88, 0x1a, 0x22, 0xb2, 0xdc, 0x4e, 0x5e, 0xc2, 0xc8, 0x25, 0xe9, 0xf9, 0x6b, 0xfe, 0xd6,
0x12, 0x2c, 0xfa, 0x2c, 0x67, 0x7f, 0x08, 0xae, 0xce, 0x50, 0x68, 0x00, 0x0c, 0xee, 0x27, 0x1a,
0x54, 0x94, 0xc8, 0xea, 0xc3, 0xf3, 0x3e, 0xd9, 0xe6, 0x11, 0x76, 0x80, 0x3e, 0xa2, 0x16, 0xc0,
0x66, 0xdc, 0xdf, 0xb1, 0x73, 0x59, 0xae, 0x3e, 0xfc, 0x64, 0x38, 0x60, 0xf6, 0xc8, 0xf8, 0x57,
0xa8, 0x0c, 0x56, 0xd6, 0x2e, 0xdd, 0x06, 0xb6, 0xef, 0xf4, 0xb6, 0xba, 0xae, 0x5e, 0xcc, 0xe0,
0x74, 0x7d, 0x76, 0x69, 0x34, 0x15, 0x6d, 0x6e, 0x0c, 0xbd, 0xae, 0xdf, 0xe5, 0x2a, 0xf0, 0xed,
0x6d, 0xb0, 0xbd, 0x75, 0xda, 0xd6, 0x78, 0x08, 0x4b, 0xeb, 0xdd, 0xfe, 0x72, 0xd1, 0xd2, 0x26,
};
/* Big endian */
uint8_t init_key[] = {
0x4d, 0x21, 0x64, 0x21, 0x8f, 0xa2, 0xe3, 0xa0, 0xab, 0x74, 0xb5, 0xab, 0x17, 0x9a, 0x5d, 0x08,
0x58, 0xf4, 0x22, 0x03, 0xbd, 0x52, 0xe7, 0x88, 0x3c, 0x22, 0x0f, 0x95, 0x89, 0x70, 0xe1, 0x93
};
/* Big endian */
uint8_t k2_info[] = {
0xd8, 0xcd, 0x04, 0x45, 0xb4, 0x45, 0xc4, 0x15, 0xf6, 0x40, 0x1c, 0x7d, 0x90, 0x1b, 0x99, 0xa4,
0x79, 0x6b, 0xfb, 0x5b, 0x2a, 0x40, 0x60, 0xe1, 0xc1, 0xe1, 0x48, 0xcd, 0x46, 0x6b, 0x9b, 0x48,
0xda, 0x7a, 0x70, 0x0a, 0x78, 0x0b, 0x9d, 0xf9, 0x0e, 0xed, 0x91, 0xfc, 0xa5, 0xc2, 0x96, 0x05,
0x91, 0x76, 0xdb, 0x68, 0x84, 0x5d, 0x5e, 0x5b, 0xa6, 0xe9, 0x6b, 0x3b, 0x12, 0x50, 0x05, 0xc3
};
/* Big endian */
uint8_t k1_ecdsa_encrypt[] = {
0xeb, 0x83, 0x24, 0x7d, 0xf8, 0x40, 0xc9, 0x88, 0x5f, 0x5e, 0x58, 0x57, 0x25, 0xa9, 0x23, 0x4a,
0xa4, 0xc4, 0x12, 0x17, 0xf3, 0x9e, 0x1f, 0xa0, 0xa0, 0xfa, 0xd5, 0xbf, 0xb6, 0x6c, 0xb5, 0x48
};
uint8_t k1_xts_encrypt[] = {
0xeb, 0x83, 0x24, 0x7d, 0xf8, 0x40, 0xc9, 0x88, 0x5f, 0x5e, 0x58, 0x57, 0x25, 0xa9, 0x23, 0x4a,
0xa4, 0xc4, 0x12, 0x17, 0xf3, 0x9e, 0x1f, 0xa0, 0xa0, 0xfa, 0xd5, 0xbf, 0xb6, 0x6c, 0xb5, 0x48
};
const esp_partition_t *get_test_storage_partition(void)
{
/* This finds "storage" partition defined partition table */
const esp_partition_t *result = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,
ESP_PARTITION_SUBTYPE_ANY, "storage");
if (!result) {
/* means partition table set wrong */
ESP_LOGE(TAG, "ERROR in obtaining storage partition");
return NULL;
}
return result;
}
static esp_err_t test_xts_aes_key(void)
{
const esp_partition_t *partition = get_test_storage_partition();
ESP_ERROR_CHECK(esp_partition_erase_range(partition, 0, partition->size));
uint32_t address = partition->address;
ESP_ERROR_CHECK(esp_flash_write_encrypted(NULL, address, plaintext_data, sizeof(plaintext_data)));
uint8_t read_data[ENCRYPTED_DATA_SIZE];
ESP_ERROR_CHECK(esp_flash_read(NULL, read_data, address, sizeof(read_data)));
if (memcmp(read_data, expected_ciphertext, sizeof(expected_ciphertext)) != 0) {
ESP_LOGE(TAG, "Encrypted data does not match expected data");
return ESP_FAIL;
}
return ESP_OK;
}
TEST_CASE("Key Manager AES mode: XTS-AES key deployment", "[hw_crypto] [key_mgr]")
{
static esp_key_mgr_aes_key_config_t key_config;
memcpy(key_config.k2_info, (uint8_t*) k2_info, KEY_MGR_K2_INFO_SIZE);
memcpy(key_config.k1_encrypted, (uint8_t*) k1_xts_encrypt, KEY_MGR_K1_ENCRYPTED_SIZE);
memcpy(key_config.sw_init_key, (uint8_t*) init_key, KEY_MGR_SW_INIT_KEY_SIZE);
key_config.use_pre_generated_sw_init_key = 1;
key_config.key_type = ESP_KEY_MGR_XTS_AES_128_KEY;
static esp_key_mgr_key_recovery_info_t key_info;
esp_err_t esp_ret = ESP_FAIL;
esp_ret = esp_key_mgr_deploy_key_in_aes_mode(&key_config, &key_info);
TEST_ASSERT_EQUAL(ESP_OK, esp_ret);
esp_ret = test_xts_aes_key();
TEST_ASSERT_EQUAL(ESP_OK, esp_ret);
}
TEST_CASE("Key Manager random mode: XTS_AES_128 key deployment", "[hw_crypto] [key_mgr]")
{
ESP_LOGI(TAG, "Key Manager Example Start");
static esp_key_mgr_random_key_config_t key_config;
key_config.key_type = ESP_KEY_MGR_XTS_AES_128_KEY;
static esp_key_mgr_key_recovery_info_t key_info;
esp_err_t esp_ret = ESP_FAIL;
esp_ret = esp_key_mgr_deploy_key_in_random_mode(&key_config, &key_info);
TEST_ASSERT_EQUAL(ESP_OK, esp_ret);
}
TEST_CASE("Key Manager random mode: ECDSA key deployment", "[hw_crypto] [key_mgr]")
{
static esp_key_mgr_random_key_config_t key_config;
static esp_key_mgr_key_recovery_info_t key_info;
esp_err_t esp_ret = ESP_FAIL;
key_config.key_type = ESP_KEY_MGR_ECDSA_KEY;
esp_ret = esp_key_mgr_deploy_key_in_random_mode(&key_config, &key_info);
TEST_ASSERT_EQUAL(ESP_OK, esp_ret);
}
#endif

Wyświetl plik

@ -1,2 +1,8 @@
CONFIG_ESP_TASK_WDT_INIT=n
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192
# set compiler optimization level
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
# we can silent the assertion to save the binary footprint
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y

Wyświetl plik

@ -35,7 +35,8 @@ struct huk_key_block {
#define KEY_HUK_SECTOR_MAGIC 0xDEA5CE5A
uint32_t magic;
uint32_t version; // for backward compatibility
uint8_t reserved[16];
uint8_t key_type;
uint8_t reserved[15];
struct huk_info huk_info;
struct key_info key_info[2]; // at most 2 key info (XTS-512_1 and XTS-512_2), at least use 1
} WORD_ALIGNED_ATTR PACKED_ATTR;

Wyświetl plik

@ -68,7 +68,10 @@
#elif CONFIG_IDF_TARGET_ESP32P4
#include "esp32p4/rtc.h"
#include "soc/hp_sys_clkrst_reg.h"
#include "soc/keymng_reg.h"
#endif
#if SOC_KEY_MANAGER_SUPPORTED
#include "hal/key_mgr_hal.h"
#endif
#include "esp_private/rtc_clk.h"
@ -305,11 +308,14 @@ static void start_other_core(void)
if(REG_GET_BIT(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_CORE1_GLOBAL)){
REG_CLR_BIT(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_CORE1_GLOBAL);
}
#endif
#if SOC_KEY_MANAGER_SUPPORTED
// The following operation makes the Key Manager to use eFuse key for ECDSA and XTS-AES operation by default
// This is to keep the default behavior same as the other chips
// If the Key Manager configuration is already locked then following operation does not have any effect
// TODO-IDF 7925 (Move this under SOC_KEY_MANAGER_SUPPORTED)
REG_SET_FIELD(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY, 3);
key_mgr_hal_set_key_usage(ESP_KEY_MGR_ECDSA_KEY, ESP_KEY_MGR_USE_EFUSE_KEY);
key_mgr_hal_set_key_usage(ESP_KEY_MGR_XTS_AES_128_KEY, ESP_KEY_MGR_USE_EFUSE_KEY);
#endif
ets_set_appcpu_boot_addr((uint32_t)call_start_cpu1);

Wyświetl plik

@ -26,6 +26,11 @@ if(CONFIG_SOC_WDT_SUPPORTED AND NOT CONFIG_HAL_WDT_USE_ROM_IMPL)
list(APPEND srcs "wdt_hal_iram.c")
endif()
if(CONFIG_SOC_KEY_MANAGER_SUPPORTED)
list(APPEND srcs "key_mgr_hal.c")
list(APPEND srcs "huk_hal.c")
endif()
if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP)
if(CONFIG_SOC_MMU_PERIPH_NUM)
list(APPEND srcs "mmu_hal.c")
@ -237,11 +242,6 @@ if(NOT BOOTLOADER_BUILD)
list(APPEND srcs "ds_hal.c")
endif()
if(CONFIG_SOC_KEY_MANAGER_SUPPORTED)
list(APPEND srcs "key_mgr_hal.c")
list(APPEND srcs "huk_hal.c")
endif()
if(CONFIG_SOC_USB_OTG_SUPPORTED)
list(APPEND srcs
"usb_dwc_hal.c"

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -10,7 +10,7 @@
#include "hal/efuse_hal.h"
#ifdef SOC_KEY_MANAGER_SUPPORTED
#include "soc/keymng_reg.h" // TODO: IDF-7901
#include "hal/key_mgr_hal.h"
#endif
#define ECDSA_HAL_P192_COMPONENT_LEN 24
@ -18,13 +18,19 @@
static void configure_ecdsa_periph(ecdsa_hal_config_t *conf)
{
#ifdef SOC_KEY_MANAGER_SUPPORTED
REG_SET_FIELD(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY, 1); // TODO: IDF-7901
#endif
if (conf->use_km_key == 0) {
efuse_hal_set_ecdsa_key(conf->efuse_key_blk);
#if SOC_KEY_MANAGER_SUPPORTED
key_mgr_hal_set_key_usage(ESP_KEY_MGR_ECDSA_KEY, ESP_KEY_MGR_USE_EFUSE_KEY);
#endif
}
#if SOC_KEY_MANAGER_SUPPORTED
else {
key_mgr_hal_set_key_usage(ESP_KEY_MGR_ECDSA_KEY, ESP_KEY_MGR_USE_OWN_KEY);
}
#endif
ecdsa_ll_set_mode(conf->mode);
ecdsa_ll_set_curve(conf->curve);

Wyświetl plik

@ -12,6 +12,7 @@
#pragma once
#include "soc/soc_caps.h"
#if SOC_KEY_MANAGER_SUPPORTED
#include <stdint.h>

Wyświetl plik

@ -112,7 +112,7 @@ void key_mgr_hal_write_public_info(const uint8_t *public_info_buf, const size_t
void key_mgr_hal_read_public_info(uint8_t *public_info_buf, const size_t read_len);
/* @brief Set the AES-XTS key length for the Key Manager */
void key_mgr_hal_set_aes_xts_key_len(const esp_key_mgr_xts_aes_key_len_t key_len);
void key_mgr_hal_set_xts_aes_key_len(const esp_key_mgr_xts_aes_key_len_t key_len);
/* @brief Get the AES-XTS key length for the Key Manager */
esp_key_mgr_xts_aes_key_len_t key_mgr_hal_get_aes_xts_key_len(void);

Wyświetl plik

@ -11,6 +11,7 @@
#pragma once
#include "soc/soc_caps.h"
#if SOC_KEY_MANAGER_SUPPORTED
#include <stdint.h>
#include <stdbool.h>
@ -118,14 +119,45 @@ static inline void key_mgr_ll_use_sw_init_key(void)
*/
static inline void key_mgr_ll_set_key_usage(const esp_key_mgr_key_type_t key_type, const esp_key_mgr_key_usage_t key_usage)
{
uint8_t read_value = ((0x03) & REG_GET_FIELD(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY));
uint8_t reg_value = (read_value & (~((uint8_t)key_type))) | (uint8_t) (key_type * key_usage);
REG_SET_FIELD(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY, reg_value);
switch (key_type) {
case ESP_KEY_MGR_ECDSA_KEY:
if (key_usage == ESP_KEY_MGR_USE_EFUSE_KEY) {
REG_SET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_ECDSA);
} else {
REG_CLR_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_ECDSA);
}
break;
case ESP_KEY_MGR_XTS_AES_128_KEY:
case ESP_KEY_MGR_XTS_AES_256_KEY:
if (key_usage == ESP_KEY_MGR_USE_EFUSE_KEY) {
REG_SET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_XTS);
} else {
REG_CLR_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_XTS);
}
break;
default:
HAL_ASSERT(false && "Unsupported mode");
return;
}
}
static inline esp_key_mgr_key_usage_t key_mgr_ll_get_key_usage(esp_key_mgr_key_type_t key_type)
{
return (esp_key_mgr_key_usage_t) (key_type & REG_GET_FIELD(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY));
switch (key_type) {
case ESP_KEY_MGR_ECDSA_KEY:
return (esp_key_mgr_key_usage_t) (REG_GET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_ECDSA));
break;
case ESP_KEY_MGR_XTS_AES_128_KEY:
case ESP_KEY_MGR_XTS_AES_256_KEY:
return (esp_key_mgr_key_usage_t) (REG_GET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_XTS));
break;
default:
HAL_ASSERT(false && "Unsupported mode");
return ESP_KEY_MGR_USAGE_INVALID;
}
return ESP_KEY_MGR_USAGE_INVALID;
}
/**
@ -143,9 +175,17 @@ static inline void key_mgr_ll_lock_use_sw_init_key_reg(void)
* After this lock has been set,
* The Key manager configuration about whether to use a paricular key from efuse or key manager cannot be changed.
*/
static inline void key_mgr_ll_lock_use_efuse_key_reg(void)
static inline void key_mgr_ll_lock_use_efuse_key_reg(esp_key_mgr_key_type_t key_type)
{
REG_SET_BIT(KEYMNG_LOCK_REG, KEYMNG_USE_EFUSE_KEY_LOCK);
switch(key_type) {
case ESP_KEY_MGR_ECDSA_KEY:
REG_SET_BIT(KEYMNG_LOCK_REG, KEYMNG_USE_EFUSE_KEY_LOCK_ECDSA);
break;
case ESP_KEY_MGR_XTS_AES_128_KEY:
case ESP_KEY_MGR_XTS_AES_256_KEY:
REG_SET_BIT(KEYMNG_LOCK_REG, KEYMNG_USE_EFUSE_KEY_LOCK_XTS);
break;
}
}
/* @brief Configure the key purpose to be used by the Key Manager for key generator opearation */
@ -180,15 +220,19 @@ 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_KEY:
return REG_GET_FIELD(KEYMNG_KEY_VLD_REG, KEYMNG_KEY_ECDSA_VLD);
break;
case ESP_KEY_MGR_XTS_KEY:
return REG_GET_FIELD(KEYMNG_KEY_VLD_REG, KEYMNG_KEY_XTS_VLD);
break;
default:
HAL_ASSERT(false && "Unsupported mode");
return 0;
case ESP_KEY_MGR_ECDSA_KEY:
return REG_GET_FIELD(KEYMNG_KEY_VLD_REG, KEYMNG_KEY_ECDSA_VLD);
break;
case ESP_KEY_MGR_XTS_AES_128_KEY:
case ESP_KEY_MGR_XTS_AES_256_KEY:
return REG_GET_FIELD(KEYMNG_KEY_VLD_REG, KEYMNG_KEY_XTS_VLD);
break;
default:
HAL_ASSERT(false && "Unsupported mode");
return 0;
}
}
@ -255,13 +299,13 @@ static inline bool key_mgr_ll_is_huk_valid(void)
}
/* @brief Set the AES-XTS key length for the Key Manager */
static inline void key_mgr_ll_set_aes_xts_key_len(const esp_key_mgr_xts_aes_key_len_t key_len)
static inline void key_mgr_ll_set_xts_aes_key_len(const esp_key_mgr_xts_aes_key_len_t key_len)
{
REG_SET_FIELD(KEYMNG_STATIC_REG, KEYMNG_XTS_AES_KEY_LEN, key_len);
}
/* @brief Get the AES-XTS key length for the Key Manager */
static inline esp_key_mgr_xts_aes_key_len_t key_mgr_ll_get_aes_xts_key_len(void)
static inline esp_key_mgr_xts_aes_key_len_t key_mgr_ll_get_xts_aes_key_len(void)
{
return (esp_key_mgr_xts_aes_key_len_t) REG_GET_FIELD(KEYMNG_STATIC_REG, KEYMNG_XTS_AES_KEY_LEN);
}

Wyświetl plik

@ -17,6 +17,7 @@ extern "C" {
#endif
#define HUK_INFO_SIZE 384
#define HUK_RISK_ALERT_LEVEL 4
/**
* @brief Mode for Hardware Unique Key Process: recovery, generation

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -11,6 +11,7 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "esp_attr.h"
#define KEY_MGR_ASSIST_INFO_LEN 64
@ -23,25 +24,26 @@ extern "C" {
*/
typedef enum {
ESP_KEY_MGR_STATE_IDLE = 0, /* Key Manager is idle */
ESP_KEY_MGR_STATE_LOAD, /* Key Manager is read to recieve input */
ESP_KEY_MGR_STATE_GAIN, /* Key Manager is ready to provide output */
ESP_KEY_MGR_STATE_BUSY /* Key Manager is busy */
ESP_KEY_MGR_STATE_LOAD = 1, /* Key Manager is ready to recieve input */
ESP_KEY_MGR_STATE_GAIN = 2, /* Key Manager is ready to provide output */
ESP_KEY_MGR_STATE_BUSY = 3, /* Key Manager is busy */
} esp_key_mgr_state_t;
/**
* @brief Length of the XTS AES key
*/
typedef enum {
ESP_KEY_MGR_XTS_AES_LEN_512 = 0, /* xts-aes key is 512 bit, please note that xts-aes algorithm is XTS_AES_256 */
ESP_KEY_MGR_XTS_AES_LEN_256, /* xts-aes key is 256 bit, please note that xts-aes algorithm is XTS_AES_128*/
ESP_KEY_MGR_XTS_AES_LEN_256 = 0, /* xts-aes key is 256 bit, please note that xts-aes algorithm is XTS_AES_128*/
ESP_KEY_MGR_XTS_AES_LEN_512, /* xts-aes key is 512 bit, please note that xts-aes algorithm is XTS_AES_256 */
} esp_key_mgr_xts_aes_key_len_t;
/**
* @brief Type of the key: ECDSA, XTS
*/
typedef enum {
ESP_KEY_MGR_ECDSA_KEY = 1, /* ECDSA key */
ESP_KEY_MGR_XTS_KEY, /* XTS AES key */
ESP_KEY_MGR_ECDSA_KEY = 0, /* ECDSA key */
ESP_KEY_MGR_XTS_AES_128_KEY, /* XTS-AES 128 key */
ESP_KEY_MGR_XTS_AES_256_KEY, /* XTS-AES 256 key */
} esp_key_mgr_key_type_t;
/*
@ -50,6 +52,7 @@ typedef enum {
typedef enum {
ESP_KEY_MGR_USE_OWN_KEY = 0, /* Use key from the key manager */
ESP_KEY_MGR_USE_EFUSE_KEY, /* Use key from the eFuse */
ESP_KEY_MGR_USAGE_INVALID,
} esp_key_mgr_key_usage_t;
/**
@ -57,9 +60,9 @@ typedef enum {
*/
typedef enum {
ESP_KEY_MGR_KEY_PURPOSE_ECDSA = 1,
ESP_KEY_MGR_KEY_PURPOSE_XTS_256_1, /* First half of the XTS AES 256 bit key */
ESP_KEY_MGR_KEY_PURPOSE_XTS_256_2, /* Second half of the XTS AES 256 bit key */
ESP_KEY_MGR_KEY_PURPOSE_XTS_128 /* XTS AES 128 bit key */
ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_1 = 2, /* First half of the XTS AES 256 bit key */
ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_2 = 3, /* Second half of the XTS AES 256 bit key */
ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_128 = 4, /* XTS AES 128 bit key */
} esp_key_mgr_key_purpose_t;
/**
@ -67,11 +70,11 @@ typedef enum {
*/
typedef enum {
ESP_KEY_MGR_KEYGEN_MODE_RANDOM = 0,
ESP_KEY_MGR_KEYGEN_MODE_AES,
ESP_KEY_MGR_KEYGEN_MODE_ECDH0,
ESP_KEY_MGR_KEYGEN_MODE_ECDH1,
ESP_KEY_MGR_KEYGEN_MODE_RECOVER,
ESP_KEY_MGR_KEYGEN_MODE_EXPORT,
ESP_KEY_MGR_KEYGEN_MODE_AES = 1,
ESP_KEY_MGR_KEYGEN_MODE_ECDH0 = 2,
ESP_KEY_MGR_KEYGEN_MODE_ECDH1 = 3,
ESP_KEY_MGR_KEYGEN_MODE_RECOVER = 4,
ESP_KEY_MGR_KEYGEN_MODE_EXPORT = 5,
} esp_key_mgr_key_generator_mode_t;
/**
@ -84,6 +87,30 @@ typedef enum {
ESP_KEY_MGR_INT_POST_DONE,
} esp_key_mgr_interrupt_type_t;
// store huk info, occupy 96 words
typedef struct PACKED_ATTR {
#define HUK_INFO_LEN 384
uint8_t info[HUK_INFO_LEN];
uint32_t crc;
} esp_key_mgr_huk_info_t;
// store key info, occupy 512 bits
typedef struct PACKED_ATTR {
#define KEY_INFO_LEN 64
uint8_t info[KEY_INFO_LEN];
uint32_t crc;
} esp_key_mgr_key_info_t;
typedef struct WORD_ALIGNED_ATTR PACKED_ATTR {
#define KEY_HUK_SECTOR_MAGIC 0xDEA5CE5A
uint32_t magic;
uint32_t version; // for backward compatibility
uint8_t key_type;
uint8_t reserved[15];
esp_key_mgr_huk_info_t huk_info;
esp_key_mgr_key_info_t key_info[2]; // at most 2 key info (XTS-512_1 and XTS-512_2), at least use 1
} esp_key_mgr_key_recovery_info_t;
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -79,14 +79,14 @@ bool key_mgr_hal_is_huk_valid(void)
return key_mgr_ll_is_huk_valid();
}
void key_mgr_hal_set_aes_xts_key_len(const esp_key_mgr_xts_aes_key_len_t key_len)
void key_mgr_hal_set_xts_aes_key_len(const esp_key_mgr_xts_aes_key_len_t key_len)
{
key_mgr_ll_set_aes_xts_key_len(key_len);
key_mgr_ll_set_xts_aes_key_len(key_len);
}
esp_key_mgr_xts_aes_key_len_t key_mgr_hal_get_aes_xts_key_len(void)
esp_key_mgr_xts_aes_key_len_t key_mgr_hal_get_xts_aes_key_len(void)
{
return key_mgr_ll_get_aes_xts_key_len();
return key_mgr_ll_get_xts_aes_key_len();
}
void key_mgr_hal_continue(void)

Wyświetl plik

@ -29,7 +29,7 @@ typedef struct {
#ifdef SOC_ECDSA_SUPPORT_EXPORT_PUBKEY
bool load_pubkey; /*!< Export ECDSA public key from the hardware */
#endif
} esp_ecdsa_pk_conf_t; //TODO: IDF-7925 (Add a config to select the ecdsa key from the key manager peripheral)
} esp_ecdsa_pk_conf_t; //TODO: IDF-9008 (Add a config to select the ecdsa key from the key manager peripheral)
#if SOC_ECDSA_SUPPORT_EXPORT_PUBKEY || __DOXYGEN__

Wyświetl plik

@ -138,14 +138,21 @@ extern "C" {
* Key Manager static configuration register
*/
#define KEYMNG_STATIC_REG (DR_REG_KEYMNG_BASE + 0x18)
/** KEYMNG_USE_EFUSE_KEY : R/W; bitpos: [1:0]; default: 0;
* Set each bit to choose efuse key instead of key manager deployed key. Each bit
* stands for a key type: bit 1 for xts_key; bit 0 for ecdsa_key
*/
#define KEYMNG_USE_EFUSE_KEY 0x00000003U
#define KEYMNG_USE_EFUSE_KEY_M (KEYMNG_USE_EFUSE_KEY_V << KEYMNG_USE_EFUSE_KEY_S)
#define KEYMNG_USE_EFUSE_KEY_V 0x00000003U
#define KEYMNG_USE_EFUSE_KEY_S 0
/* KEYMNG_USE_EFUSE_KEY_XTS : R/W ;bitpos:[1] ;default: 1'd0 ; */
/*description: Set this bit to choose efuse key instead of key manager deployed key for xts_key.*/
#define KEYMNG_USE_EFUSE_KEY_XTS (BIT(1))
#define KEYMNG_USE_EFUSE_KEY_XTS_M ((KEYMNG_USE_EFUSE_KEY_XTS_V)<<(KEYMNG_USE_EFUSE_KEY_XTS_S))
#define KEYMNG_USE_EFUSE_KEY_XTS_V 0x1
#define KEYMNG_USE_EFUSE_KEY_XTS_S 1
/* KEYMNG_USE_EFUSE_KEY_ECDSA : R/W ;bitpos:[0] ;default: 1'd0 ; */
/*description: Set this bit to choose efuse key instead of key manager deployed key for ecdsa_key.*/
#define KEYMNG_USE_EFUSE_KEY_ECDSA (BIT(0))
#define KEYMNG_USE_EFUSE_KEY_ECDSA_M ((KEYMNG_USE_EFUSE_KEY_ECDSA_V)<<(KEYMNG_USE_EFUSE_KEY_ECDSA_S))
#define KEYMNG_USE_EFUSE_KEY_ECDSA_V 0x1
#define KEYMNG_USE_EFUSE_KEY_ECDSA_S 0
/** KEYMNG_RND_SWITCH_CYCLE : R/W; bitpos: [8:4]; default: 15;
* The core clock cycle number to sample one rng input data. Please set it bigger than
* the clock cycle ratio: T_rng/T_km
@ -174,14 +181,21 @@ extern "C" {
* Key Manager static configuration locker register
*/
#define KEYMNG_LOCK_REG (DR_REG_KEYMNG_BASE + 0x1c)
/** KEYMNG_USE_EFUSE_KEY_LOCK : R/W1; bitpos: [1:0]; default: 0;
* Write 1 to lock reg_use_efuse_key. Each bit locks the corresponding bit of
* reg_use_efuse_key.
*/
#define KEYMNG_USE_EFUSE_KEY_LOCK 0x00000003U
#define KEYMNG_USE_EFUSE_KEY_LOCK_M (KEYMNG_USE_EFUSE_KEY_LOCK_V << KEYMNG_USE_EFUSE_KEY_LOCK_S)
#define KEYMNG_USE_EFUSE_KEY_LOCK_V 0x00000003U
#define KEYMNG_USE_EFUSE_KEY_LOCK_S 0
/* KEYMNG_USE_EFUSE_KEY_XTS : R/W ; bitpos:[1] ; default: 1'd0 ; */
/* description: Set thus bit to choose efuse key instead of key manager deployed key for xts_key */
#define KEYMNG_USE_EFUSE_KEY_LOCK_XTS (BIT(1))
#define KEYMNG_USE_EFUSE_KEY_LOCK_XTS_M ((KEYMNG_USE_EFUSE_KEY_LOCK_XTS_V)<<(KEYMNG_USE_EFUSE_KEY_LOCK_XTS_S))
#define KEYMNG_USE_EFUSE_KEY_LOCK_XTS_V 0x1
#define KEYMNG_USE_EFUSE_KEY_LOCK_XTS_S 1
/* KEYMNG_USE_EFUSE_KEY_LOCK_ECDSA : R/W ; bitpos:[0] ; default: 1'd0 ; */
/* description: Write 1 to lock ecdsa-key */
#define KEYMNG_USE_EFUSE_KEY_LOCK_ECDSA (BIT(0))
#define KEYMNG_USE_EFUSE_KEY_LOCK_ECDSA_M ((KEYMNG_USE_EFUSE_KEY_LOCK_ECDSA_V)<<(KEYMNG_USE_EFUSE_KEY_LOCK_ECDSA_S))
#define KEYMNG_USE_EFUSE_KEY_LOCK_ECDSA_V 0x1
#define KEYMNG_USE_EFUSE_KEY_LOCK_ECDSA_S 0
/** KEYMNG_RND_SWITCH_CYCLE_LOCK : R/W1; bitpos: [4]; default: 0;
* Write 1 to lock reg_rnd_switch_cycle.
*/

Wyświetl plik

@ -1,6 +1,3 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
# Peripherals Examples
This section provides examples how to configure and use ESP32s internal peripherals like GPIO, UART, I2C, SPI, timers, counters, ADC / DAC, PWM, etc.