From 3eabb62850b69a91e3991cc881c61165979bd755 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Tue, 26 Sep 2023 10:22:56 +0530 Subject: [PATCH 1/3] feat(esp_hw_support): Add support for Key Manager --- components/esp_hw_support/CMakeLists.txt | 4 + components/esp_hw_support/esp_key_mgr.c | 219 ++++++++++++++++++ .../esp_hw_support/include/esp_key_mgr.h | 93 ++++++++ .../esp32p4/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32p4/include/soc/soc_caps.h | 2 +- examples/peripherals/README.md | 3 + 6 files changed, 324 insertions(+), 1 deletion(-) create mode 100644 components/esp_hw_support/esp_key_mgr.c create mode 100644 components/esp_hw_support/include/esp_key_mgr.h diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index dec7467301..309ebc3558 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -117,6 +117,10 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "esp_ds.c") endif() + if(CONFIG_SOC_KEY_MANAGER_SUPPORTED) + list(APPEND srcs "esp_key_mgr.c") + endif() + if(CONFIG_SOC_PAU_SUPPORTED) list(APPEND srcs "port/pau_regdma.c" "port/regdma_link.c") diff --git a/components/esp_hw_support/esp_key_mgr.c b/components/esp_hw_support/esp_key_mgr.c new file mode 100644 index 0000000000..c5b2e2d232 --- /dev/null +++ b/components/esp_hw_support/esp_key_mgr.c @@ -0,0 +1,219 @@ +/* + * SPDX-FileCopyrightText: 2023 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 "esp_key_mgr.h" +#include "hal/clk_gate_ll.h" +#include "esp_log.h" +#include "esp_err.h" +#include "assert.h" +#include "string.h" + +static const char *TAG = "esp_key_mgr"; +static void key_mgr_wait_for_state(esp_key_mgr_state_t state) +{ + while (key_mgr_hal_get_state() != 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) +{ + ESP_LOGI(TAG, "Key Deployment"); + // Reset the Key Manager Clock + periph_ll_enable_clk_clear_rst(PERIPH_KEY_MANAGER_MODULE); + + key_mgr_wait_for_state(ESP_KEY_MGR_STATE_IDLE); + uint8_t *huk_recovery_info = (uint8_t *) calloc(1, sizeof(KEY_MGR_HUK_INFO_SIZE)); + if (!huk_recovery_info) { + return ESP_ERR_NO_MEM; + } + uint8_t *key_recovery_info = (uint8_t *) calloc(1, sizeof(KEY_MGR_KEY_RECOVERY_INFO_SIZE)); + 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); + } + + 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) { + key_mgr_hal_use_sw_init_key(); + } + + 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_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_continue(); + 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); + + //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; + } + 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; + free(key_recovery_info); + 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_recover_key(esp_key_mgr_key_recovery_info_t *key_recovery_info) +{ + periph_ll_enable_clk_clear_rst(PERIPH_KEY_MANAGER_MODULE); + 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; + } + ESP_LOGI(TAG, "purpose = %d", key_recovery_info->key_purpose); + key_mgr_hal_set_key_purpose(key_recovery_info->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); + 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; + } + ESP_LOGI(TAG, "Key deployment valid"); + key_mgr_hal_continue(); + key_mgr_wait_for_state(ESP_KEY_MGR_STATE_IDLE); + 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_LOGI(TAG, "Key Deployment"); + // Reset the Key Manager Clock + periph_ll_enable_clk_clear_rst(PERIPH_KEY_MANAGER_MODULE); + + key_mgr_wait_for_state(ESP_KEY_MGR_STATE_IDLE); + uint8_t *huk_recovery_info = (uint8_t *) calloc(1, sizeof(KEY_MGR_HUK_INFO_SIZE)); + if (!huk_recovery_info) { + return ESP_ERR_NO_MEM; + } + uint8_t *key_recovery_info = (uint8_t *) calloc(1, sizeof(KEY_MGR_KEY_RECOVERY_INFO_SIZE)); + 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); + } + + 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) { + key_mgr_hal_use_sw_init_key(); + } + + 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(); + 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); + + //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; + } + 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; + free(key_recovery_info); + free(huk_recovery_info); + key_mgr_hal_set_key_usage(ESP_KEY_MGR_XTS_KEY, ESP_KEY_MGR_USE_OWN_KEY); + return ESP_OK; +} diff --git a/components/esp_hw_support/include/esp_key_mgr.h b/components/esp_hw_support/include/esp_key_mgr.h new file mode 100644 index 0000000000..04ac53283f --- /dev/null +++ b/components/esp_hw_support/include/esp_key_mgr.h @@ -0,0 +1,93 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal/key_mgr_types.h" +#include "hal/huk_types.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 64 +/* AES deploy mode */ +#define KEY_MGR_K2_INFO_SIZE 64 +#define KEY_MGR_K1_ENCRYPTED_SIZE 32 +#define KEY_MGR_ECDH0_INFO_SIZE 64 + +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]; +} 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]; +} 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; + +/** + * @brief Check if the deployed key is valid or not + * @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 + * @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); + +/** + * @brief Check if the deployed key is valid or not + * @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 + * @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); + +/* + * @brief Recover a key from the given key info + * + * @input + * key_info The key info required to recover the key + * @return + * ESP_OK for success + * ESP_FAIL/revevant error code for failure + */ +esp_err_t esp_key_mgr_recover_key(esp_key_mgr_key_recovery_info_t *key_recovery_info); +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index b2fb0c346f..1b99ded463 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -143,6 +143,10 @@ config SOC_ECDSA_SUPPORTED bool default y +config SOC_KEY_MANAGER_SUPPORTED + bool + default y + config SOC_FLASH_ENC_SUPPORTED bool default y diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 0358f666a3..b196fae992 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -60,7 +60,7 @@ #define SOC_ECC_SUPPORTED 1 #define SOC_ECC_EXTENDED_MODES_SUPPORTED 1 #define SOC_ECDSA_SUPPORTED 1 -// #define SOC_KEY_MANAGER_SUPPORTED 1 //TODO: IDF-7925 +#define SOC_KEY_MANAGER_SUPPORTED 1 #define SOC_FLASH_ENC_SUPPORTED 1 #define SOC_SECURE_BOOT_SUPPORTED 1 // #define SOC_BOD_SUPPORTED 1 //TODO: IDF-7519 diff --git a/examples/peripherals/README.md b/examples/peripherals/README.md index eef44e9462..363d8fcd27 100644 --- a/examples/peripherals/README.md +++ b/examples/peripherals/README.md @@ -1,3 +1,6 @@ +| 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 ESP32’s internal peripherals like GPIO, UART, I2C, SPI, timers, counters, ADC / DAC, PWM, etc. From 5a1726c18c87df42ecf45192330377bc3f025bdf Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Thu, 12 Oct 2023 16:55:40 +0530 Subject: [PATCH 2/3] feat(hal): Update HAL layer for Key manager 1)Added new clk related changes --- components/esp_hw_support/esp_key_mgr.c | 53 ++++++++++++++----- .../esp_hw_support/include/esp_key_mgr.h | 4 +- components/hal/esp32p4/include/hal/huk_ll.h | 14 ++--- .../hal/esp32p4/include/hal/key_mgr_ll.h | 2 - components/hal/huk_hal.c | 1 + 5 files changed, 50 insertions(+), 24 deletions(-) diff --git a/components/esp_hw_support/esp_key_mgr.c b/components/esp_hw_support/esp_key_mgr.c index c5b2e2d232..57930d9555 100644 --- a/components/esp_hw_support/esp_key_mgr.c +++ b/components/esp_hw_support/esp_key_mgr.c @@ -9,11 +9,15 @@ #include "hal/huk_types.h" #include "hal/huk_hal.h" #include "esp_key_mgr.h" -#include "hal/clk_gate_ll.h" +#include "esp_private/periph_ctrl.h" +#include "hal/key_mgr_ll.h" #include "esp_log.h" #include "esp_err.h" #include "assert.h" #include "string.h" +#include "esp_heap_caps.h" + +#define KEY_MANAGER_RCC_ATOMIC() PERIPH_RCC_ATOMIC() static const char *TAG = "esp_key_mgr"; static void key_mgr_wait_for_state(esp_key_mgr_state_t state) @@ -27,14 +31,17 @@ esp_err_t esp_key_mgr_deploy_key_in_aes_mode(esp_key_mgr_aes_key_config_t *key_c { ESP_LOGI(TAG, "Key Deployment"); // Reset the Key Manager Clock - periph_ll_enable_clk_clear_rst(PERIPH_KEY_MANAGER_MODULE); + 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); - uint8_t *huk_recovery_info = (uint8_t *) calloc(1, sizeof(KEY_MGR_HUK_INFO_SIZE)); + 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; } - uint8_t *key_recovery_info = (uint8_t *) calloc(1, sizeof(KEY_MGR_KEY_RECOVERY_INFO_SIZE)); + 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; } @@ -100,15 +107,23 @@ esp_err_t esp_key_mgr_deploy_key_in_aes_mode(esp_key_mgr_aes_key_config_t *key_c //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; - free(key_recovery_info); - free(huk_recovery_info); + 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); + 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_recover_key(esp_key_mgr_key_recovery_info_t *key_recovery_info) { - periph_ll_enable_clk_clear_rst(PERIPH_KEY_MANAGER_MODULE); + 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); huk_hal_configure(ESP_HUK_MODE_RECOVERY, key_recovery_info->huk_recovery_info); if (key_mgr_hal_is_huk_valid()) { @@ -132,6 +147,10 @@ esp_err_t esp_key_mgr_recover_key(esp_key_mgr_key_recovery_info_t *key_recovery_ 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; } @@ -139,14 +158,17 @@ esp_err_t esp_key_mgr_deploy_key_in_ecdh0_mode(esp_key_mgr_ecdh0_key_config_t *k { ESP_LOGI(TAG, "Key Deployment"); // Reset the Key Manager Clock - periph_ll_enable_clk_clear_rst(PERIPH_KEY_MANAGER_MODULE); + 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); - uint8_t *huk_recovery_info = (uint8_t *) calloc(1, sizeof(KEY_MGR_HUK_INFO_SIZE)); + 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; } - uint8_t *key_recovery_info = (uint8_t *) calloc(1, sizeof(KEY_MGR_KEY_RECOVERY_INFO_SIZE)); + 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; } @@ -212,8 +234,13 @@ esp_err_t esp_key_mgr_deploy_key_in_ecdh0_mode(esp_key_mgr_ecdh0_key_config_t *k //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; - free(key_recovery_info); - free(huk_recovery_info); - key_mgr_hal_set_key_usage(ESP_KEY_MGR_XTS_KEY, ESP_KEY_MGR_USE_OWN_KEY); + 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(); + } return ESP_OK; } diff --git a/components/esp_hw_support/include/esp_key_mgr.h b/components/esp_hw_support/include/esp_key_mgr.h index 04ac53283f..61fea463aa 100644 --- a/components/esp_hw_support/include/esp_key_mgr.h +++ b/components/esp_hw_support/include/esp_key_mgr.h @@ -17,7 +17,7 @@ extern "C" { #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 64 +#define KEY_MGR_HUK_INFO_SIZE HUK_INFO_SIZE /* AES deploy mode */ #define KEY_MGR_K2_INFO_SIZE 64 #define KEY_MGR_K1_ENCRYPTED_SIZE 32 @@ -76,7 +76,7 @@ esp_err_t esp_key_mgr_deploy_key_in_aes_mode(esp_key_mgr_aes_key_config_t *key_c * 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_ecdh0_mode(esp_key_mgr_ecdh0_key_config_t *key_config, esp_key_mgr_key_recovery_info_t *key_info); /* * @brief Recover a key from the given key info diff --git a/components/hal/esp32p4/include/hal/huk_ll.h b/components/hal/esp32p4/include/hal/huk_ll.h index ce87ac8984..9c4d987749 100644 --- a/components/hal/esp32p4/include/hal/huk_ll.h +++ b/components/hal/esp32p4/include/hal/huk_ll.h @@ -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 */ @@ -12,8 +12,8 @@ #pragma once #include "soc/soc_caps.h" - #if SOC_KEY_MANAGER_SUPPORTED + #include #include #include @@ -32,12 +32,12 @@ static inline void huk_ll_configure_mode(const esp_huk_mode_t huk_mode) REG_SET_FIELD(HUK_CONF_REG, HUK_MODE, huk_mode); } -void huk_ll_write_info(const uint8_t *buffer, const size_t size) +static inline void huk_ll_write_info(const uint8_t *buffer, const size_t size) { memcpy((uint8_t *)HUK_INFO_MEM, buffer, size); } -void huk_ll_read_info(uint8_t *buffer, const size_t size) +static inline void huk_ll_read_info(uint8_t *buffer, const size_t size) { memcpy(buffer, (uint8_t *)HUK_INFO_MEM, size); } @@ -91,15 +91,15 @@ static inline void huk_ll_clear_int(const esp_huk_interrupt_type_t intr) */ static inline esp_huk_state_t huk_ll_get_state(void) { - return REG_GET_FIELD(HUK_STATE_REG, HUK_STATE); + return (esp_huk_state_t) REG_GET_FIELD(HUK_STATE_REG, HUK_STATE); } /** - * @brief Get the HUK generation status: esp_huk_gen_status_t + * @brief Get the HUK generation status */ static inline esp_huk_gen_status_t huk_ll_get_gen_status(void) { - return REG_GET_FIELD(HUK_STATUS_REG, HUK_STATUS); + return (esp_huk_gen_status_t) REG_GET_FIELD(HUK_STATUS_REG, HUK_STATUS); } /** diff --git a/components/hal/esp32p4/include/hal/key_mgr_ll.h b/components/hal/esp32p4/include/hal/key_mgr_ll.h index 17ae6263d1..107b1d338c 100644 --- a/components/hal/esp32p4/include/hal/key_mgr_ll.h +++ b/components/hal/esp32p4/include/hal/key_mgr_ll.h @@ -10,9 +10,7 @@ ******************************************************************************/ #pragma once - #include "soc/soc_caps.h" - #if SOC_KEY_MANAGER_SUPPORTED #include #include diff --git a/components/hal/huk_hal.c b/components/hal/huk_hal.c index 41b4d06238..70aa576459 100644 --- a/components/hal/huk_hal.c +++ b/components/hal/huk_hal.c @@ -12,6 +12,7 @@ #include "hal/assert.h" #include "hal/log.h" #include "rom/km.h" +#include "esp_err.h" esp_huk_state_t huk_hal_get_state(void) { From 4dc2ace0b7ee2b681d394cd05997594da231c376 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Mon, 30 Oct 2023 23:48:46 +0530 Subject: [PATCH 3/3] 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 --- .../src/flash_encryption/flash_encrypt.c | 12 +- components/esp_hw_support/esp_key_mgr.c | 753 ++++++++++++++---- .../esp_hw_support/include/esp_key_mgr.h | 101 ++- .../include/soc/esp32p4/esp_crypto_lock.h | 14 +- .../port/esp32p4/esp_crypto_lock.c | 19 +- .../main/CMakeLists.txt | 3 +- .../main/test_key_mgr.c | 140 ++++ .../sdkconfig.defaults | 6 + .../esp_rom/include/esp32p4/rom/key_mgr.h | 3 +- components/esp_system/port/cpu_start.c | 12 +- components/hal/CMakeLists.txt | 10 +- components/hal/ecdsa_hal.c | 16 +- components/hal/esp32p4/include/hal/huk_ll.h | 1 + .../hal/esp32p4/include/hal/key_mgr_hal.h | 2 +- .../hal/esp32p4/include/hal/key_mgr_ll.h | 78 +- components/hal/include/hal/huk_types.h | 1 + components/hal/include/hal/key_mgr_types.h | 59 +- components/hal/key_mgr_hal.c | 8 +- .../mbedtls/port/include/ecdsa/ecdsa_alt.h | 2 +- .../soc/esp32p4/include/soc/keymng_reg.h | 46 +- examples/peripherals/README.md | 3 - 21 files changed, 1028 insertions(+), 261 deletions(-) create mode 100644 components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_key_mgr.c diff --git a/components/bootloader_support/src/flash_encryption/flash_encrypt.c b/components/bootloader_support/src/flash_encryption/flash_encrypt.c index 8bd1352b73..bf6f629648 100644 --- a/components/bootloader_support/src/flash_encryption/flash_encrypt.c +++ b/components/bootloader_support/src/flash_encryption/flash_encrypt.c @@ -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; } diff --git a/components/esp_hw_support/esp_key_mgr.c b/components/esp_hw_support/esp_key_mgr.c index 57930d9555..6b67decd90 100644 --- a/components/esp_hw_support/esp_key_mgr.c +++ b/components/esp_hw_support/esp_key_mgr.c @@ -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 +#include +#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; +} diff --git a/components/esp_hw_support/include/esp_key_mgr.h b/components/esp_hw_support/include/esp_key_mgr.h index 61fea463aa..8ed708358d 100644 --- a/components/esp_hw_support/include/esp_key_mgr.h +++ b/components/esp_hw_support/include/esp_key_mgr.h @@ -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 diff --git a/components/esp_hw_support/include/soc/esp32p4/esp_crypto_lock.h b/components/esp_hw_support/include/soc/esp32p4/esp_crypto_lock.h index 6855caae23..495a0736ff 100644 --- a/components/esp_hw_support/include/soc/esp32p4/esp_crypto_lock.h +++ b/components/esp_hw_support/include/soc/esp32p4/esp_crypto_lock.h @@ -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 diff --git a/components/esp_hw_support/port/esp32p4/esp_crypto_lock.c b/components/esp_hw_support/port/esp32p4/esp_crypto_lock.c index fbeee00aa9..fa663d2b1d 100644 --- a/components/esp_hw_support/port/esp32p4/esp_crypto_lock.c +++ b/components/esp_hw_support/port/esp32p4/esp_crypto_lock.c @@ -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); +} diff --git a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/CMakeLists.txt b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/CMakeLists.txt index 40a5a7555b..3ff1c7fabf 100644 --- a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/CMakeLists.txt +++ b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/CMakeLists.txt @@ -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) diff --git a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_key_mgr.c b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_key_mgr.c new file mode 100644 index 0000000000..fa34b53f6f --- /dev/null +++ b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_key_mgr.c @@ -0,0 +1,140 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#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 diff --git a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/sdkconfig.defaults b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/sdkconfig.defaults index b71277ca37..cc85282c55 100644 --- a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/sdkconfig.defaults +++ b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/sdkconfig.defaults @@ -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 diff --git a/components/esp_rom/include/esp32p4/rom/key_mgr.h b/components/esp_rom/include/esp32p4/rom/key_mgr.h index 2a5707fa80..eb0914f4b9 100644 --- a/components/esp_rom/include/esp32p4/rom/key_mgr.h +++ b/components/esp_rom/include/esp32p4/rom/key_mgr.h @@ -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; diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index d0109db8e0..b55965aa2c 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -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); diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index a023f7cde0..2fddbea5ce 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -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" diff --git a/components/hal/ecdsa_hal.c b/components/hal/ecdsa_hal.c index 3737e793ba..b7e661ec31 100644 --- a/components/hal/ecdsa_hal.c +++ b/components/hal/ecdsa_hal.c @@ -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); diff --git a/components/hal/esp32p4/include/hal/huk_ll.h b/components/hal/esp32p4/include/hal/huk_ll.h index 9c4d987749..6fa5b98f2a 100644 --- a/components/hal/esp32p4/include/hal/huk_ll.h +++ b/components/hal/esp32p4/include/hal/huk_ll.h @@ -12,6 +12,7 @@ #pragma once #include "soc/soc_caps.h" + #if SOC_KEY_MANAGER_SUPPORTED #include diff --git a/components/hal/esp32p4/include/hal/key_mgr_hal.h b/components/hal/esp32p4/include/hal/key_mgr_hal.h index 27e4a76e39..3bed3fa3fd 100644 --- a/components/hal/esp32p4/include/hal/key_mgr_hal.h +++ b/components/hal/esp32p4/include/hal/key_mgr_hal.h @@ -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); diff --git a/components/hal/esp32p4/include/hal/key_mgr_ll.h b/components/hal/esp32p4/include/hal/key_mgr_ll.h index 107b1d338c..1bcd5402bf 100644 --- a/components/hal/esp32p4/include/hal/key_mgr_ll.h +++ b/components/hal/esp32p4/include/hal/key_mgr_ll.h @@ -11,6 +11,7 @@ #pragma once #include "soc/soc_caps.h" + #if SOC_KEY_MANAGER_SUPPORTED #include #include @@ -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); } diff --git a/components/hal/include/hal/huk_types.h b/components/hal/include/hal/huk_types.h index 5b09f5c6f1..8812fe6f2f 100644 --- a/components/hal/include/hal/huk_types.h +++ b/components/hal/include/hal/huk_types.h @@ -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 diff --git a/components/hal/include/hal/key_mgr_types.h b/components/hal/include/hal/key_mgr_types.h index b7447f5155..82064e58d4 100644 --- a/components/hal/include/hal/key_mgr_types.h +++ b/components/hal/include/hal/key_mgr_types.h @@ -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 #include #include +#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 diff --git a/components/hal/key_mgr_hal.c b/components/hal/key_mgr_hal.c index 0db46c805b..3658371fd5 100644 --- a/components/hal/key_mgr_hal.c +++ b/components/hal/key_mgr_hal.c @@ -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) diff --git a/components/mbedtls/port/include/ecdsa/ecdsa_alt.h b/components/mbedtls/port/include/ecdsa/ecdsa_alt.h index a8646979a7..e409bf1cb1 100644 --- a/components/mbedtls/port/include/ecdsa/ecdsa_alt.h +++ b/components/mbedtls/port/include/ecdsa/ecdsa_alt.h @@ -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__ diff --git a/components/soc/esp32p4/include/soc/keymng_reg.h b/components/soc/esp32p4/include/soc/keymng_reg.h index d75565dbc8..a8f03edc6e 100644 --- a/components/soc/esp32p4/include/soc/keymng_reg.h +++ b/components/soc/esp32p4/include/soc/keymng_reg.h @@ -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. */ diff --git a/examples/peripherals/README.md b/examples/peripherals/README.md index 363d8fcd27..eef44e9462 100644 --- a/examples/peripherals/README.md +++ b/examples/peripherals/README.md @@ -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 ESP32’s internal peripherals like GPIO, UART, I2C, SPI, timers, counters, ADC / DAC, PWM, etc.