From 2ad611ad73019d3fa4ff4ab75e38fbe5405c067c Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Sun, 18 Feb 2024 00:23:01 +0530 Subject: [PATCH 1/2] fix(esp_hw_support): Fix key mgr hw support 1) Fix re-deployment scenario for key manager 2) Fix magic for key manager APIs 3) Fix key manager eFuse check 4) Fix key manager test case --- components/esp_hw_support/esp_key_mgr.c | 28 ++++++++++++++---- .../main/test_app_main.c | 2 +- .../main/test_key_mgr.c | 29 +++++++++++++------ .../esp_hw_support_unity_tests/partitions.csv | 4 +++ .../sdkconfig.defaults.esp32p4 | 3 ++ 5 files changed, 51 insertions(+), 15 deletions(-) create mode 100644 components/esp_hw_support/test_apps/esp_hw_support_unity_tests/partitions.csv create mode 100644 components/esp_hw_support/test_apps/esp_hw_support_unity_tests/sdkconfig.defaults.esp32p4 diff --git a/components/esp_hw_support/esp_key_mgr.c b/components/esp_hw_support/esp_key_mgr.c index a3ceedb4ec..80ab17618e 100644 --- a/components/esp_hw_support/esp_key_mgr.c +++ b/components/esp_hw_support/esp_key_mgr.c @@ -15,6 +15,7 @@ #include "esp_random.h" #include "esp_heap_caps.h" #include "esp_rom_crc.h" +#include "esp_efuse.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "hal/key_mgr_types.h" @@ -112,6 +113,7 @@ typedef struct aes_deploy { const uint8_t *k1_encrypted; const esp_key_mgr_aes_key_config_t *key_config; esp_key_mgr_key_recovery_info_t *key_info; + bool huk_deployed; } aes_deploy_config_t; static void check_huk_risk_level(void) @@ -232,7 +234,7 @@ static esp_err_t key_mgr_deploy_key_aes_mode(aes_deploy_config_t *config) return ESP_ERR_NO_MEM; } // Set key purpose (XTS/ECDSA) - ESP_LOGI(TAG, "purpose = %d", config->key_purpose); + ESP_LOGD(TAG, "Key purpose = %d", config->key_purpose); key_mgr_hal_set_key_purpose(config->key_purpose); // Set key length for XTS-AES key @@ -246,6 +248,10 @@ static esp_err_t key_mgr_deploy_key_aes_mode(aes_deploy_config_t *config) if (config->key_config->use_pre_generated_sw_init_key) { key_mgr_hal_use_sw_init_key(); + } else { + if (!esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_KM_INIT_KEY, NULL)) { + return ESP_FAIL; + } } key_mgr_hal_start(); @@ -261,7 +267,7 @@ static esp_err_t key_mgr_deploy_key_aes_mode(aes_deploy_config_t *config) 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); + ESP_LOG_BUFFER_HEX_LEVEL("K1_ENCRYPTED", config->k1_encrypted, KEY_MGR_K1_ENCRYPTED_SIZE, ESP_LOG_DEBUG); key_mgr_hal_continue(); // Step 3: Gain phase key_mgr_wait_for_state(ESP_KEY_MGR_STATE_GAIN); @@ -288,6 +294,8 @@ static esp_err_t key_mgr_deploy_key_aes_mode(aes_deploy_config_t *config) 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); + config->key_info->key_type = config->key_config->key_type; + config->key_info->magic = KEY_HUK_SECTOR_MAGIC; return ESP_OK; } @@ -319,6 +327,7 @@ esp_err_t esp_key_mgr_deploy_key_in_aes_mode(const esp_key_mgr_aes_key_config_t if (esp_ret != ESP_OK) { ESP_LOGE(TAG, "Key deployment in AES mode failed"); } + aes_deploy_config.huk_deployed = true; if (key_type == ESP_KEY_MGR_XTS_AES_256_KEY) { aes_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_2; @@ -392,7 +401,7 @@ static esp_err_t key_mgr_recover_key(key_recovery_config_t *config) 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); + ESP_LOG_BUFFER_HEX_LEVEL("RECOVERY_INFO", config->key_recovery_info->key_info[0].info, KEY_MGR_KEY_RECOVERY_INFO_SIZE, ESP_LOG_DEBUG); } key_mgr_hal_continue(); @@ -467,6 +476,7 @@ typedef struct ecdh0_config { const esp_key_mgr_ecdh0_key_config_t *key_config; esp_key_mgr_key_recovery_info_t *key_info; uint8_t *ecdh0_key_info; + bool huk_deployed; } ecdh0_deploy_config_t; static esp_err_t key_mgr_deploy_key_ecdh0_mode(ecdh0_deploy_config_t *config) @@ -474,7 +484,7 @@ 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()) { + if (!key_mgr_hal_is_huk_valid() || !config->huk_deployed) { // 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; @@ -543,6 +553,8 @@ static esp_err_t key_mgr_deploy_key_ecdh0_mode(ecdh0_deploy_config_t *config) } config->key_info->key_type = config->key_config->key_type; + config->key_info->magic = KEY_HUK_SECTOR_MAGIC; + heap_caps_free(key_recovery_info); return ESP_OK; } @@ -578,6 +590,7 @@ esp_err_t esp_key_mgr_deploy_key_in_ecdh0_mode(const esp_key_mgr_ecdh0_key_confi if (esp_ret != ESP_OK) { ESP_LOGE(TAG, "Failed to deploy key in ECDH0 mode"); } + ecdh0_deploy_config.huk_deployed = true; if (key_config->key_type == ESP_KEY_MGR_XTS_AES_256_KEY) { key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_2; @@ -600,13 +613,14 @@ 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; + bool huk_deployed; } 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()) { + if (!key_mgr_hal_is_huk_valid() || !config->huk_deployed) { // 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; @@ -668,6 +682,9 @@ static esp_err_t key_mgr_deploy_key_random_mode(random_deploy_config_t *config) 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); + config->key_info->key_type = config->key_config->key_type; + config->key_info->magic = KEY_HUK_SECTOR_MAGIC; + return ESP_OK; } @@ -698,6 +715,7 @@ esp_err_t esp_key_mgr_deploy_key_in_random_mode(const esp_key_mgr_random_key_con ESP_LOGE(TAG, "Key deployment in Random mode failed"); return ESP_FAIL; } + random_deploy_config.huk_deployed = true; if (key_type == ESP_KEY_MGR_XTS_AES_256_KEY) { random_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_XTS_AES_256_2; diff --git a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_app_main.c b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_app_main.c index d127fae5c5..b893f539bc 100644 --- a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_app_main.c +++ b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_app_main.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 */ 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 index fa34b53f6f..40e2f1b526 100644 --- 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 @@ -17,7 +17,8 @@ #endif #include "soc/keymng_reg.h" #include "esp_key_mgr.h" - +#include "esp_system.h" +#include "unity_test_utils_memory.h" static const char *TAG = "key_mgr_test"; #define ENCRYPTED_DATA_SIZE 128 @@ -33,14 +34,14 @@ static const uint8_t plaintext_data[ENCRYPTED_DATA_SIZE] = { }; 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, + 0x1f, 0x41, 0xa4, 0xec, 0x0f, 0xd3, 0xaf, 0xe1, 0xb5, 0xc0, 0x56, 0x41, 0xcb, 0x28, 0x97, 0x1c, + 0x45, 0x02, 0x23, 0xcd, 0x45, 0x06, 0x19, 0xd8, 0xf9, 0x40, 0x8d, 0xdf, 0xb8, 0x71, 0xa7, 0x79, + 0xdf, 0xbb, 0x2d, 0x6a, 0xdd, 0x16, 0x18, 0x32, 0xe4, 0xa6, 0xfe, 0x23, 0xc9, 0x70, 0xa0, 0xfa, + 0xec, 0x74, 0xf4, 0x62, 0xea, 0x31, 0xc7, 0x1e, 0xfe, 0x94, 0xda, 0xe1, 0x70, 0xf8, 0x9f, 0xa3, + 0x03, 0xdf, 0x89, 0x77, 0x0a, 0x41, 0x7d, 0xc5, 0xe6, 0xc8, 0xb1, 0x10, 0xc8, 0x12, 0xa6, 0x3f, + 0xea, 0xf0, 0xfa, 0x7a, 0x5d, 0x33, 0xb3, 0xe6, 0xc2, 0x27, 0x07, 0x1e, 0x71, 0x22, 0x87, 0x73, + 0xc4, 0x2a, 0xbd, 0x59, 0x8f, 0xc6, 0xfb, 0x28, 0x2e, 0xec, 0xa2, 0x1f, 0x42, 0x7c, 0x54, 0xec, + 0x1e, 0x0f, 0x9f, 0xf2, 0x6e, 0x3f, 0xb8, 0x7d, 0xbf, 0xee, 0xf9, 0x7c, 0x93, 0xb2, 0x79, 0x98 }; /* Big endian */ @@ -97,8 +98,14 @@ static esp_err_t test_xts_aes_key(void) return ESP_OK; } +extern void set_leak_threshold(int threshold); TEST_CASE("Key Manager AES mode: XTS-AES key deployment", "[hw_crypto] [key_mgr]") { + // This threshold accounts for multiple locks obtained for the first time by the following APIs + // The larger threshold is only needed for aes mode as additional locks are used in aes mode + set_leak_threshold(-900); + + // Setting the leak threshold to not count the memory allocated for locks used by key manager 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); @@ -110,8 +117,12 @@ TEST_CASE("Key Manager AES mode: XTS-AES key deployment", "[hw_crypto] [key_mgr] 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 = esp_key_mgr_activate_key(&key_info); + TEST_ASSERT_EQUAL(ESP_OK, esp_ret); esp_ret = test_xts_aes_key(); TEST_ASSERT_EQUAL(ESP_OK, esp_ret); + esp_ret = esp_key_mgr_deactivate_key(key_info.key_type); + TEST_ASSERT_EQUAL(ESP_OK, esp_ret); } TEST_CASE("Key Manager random mode: XTS_AES_128 key deployment", "[hw_crypto] [key_mgr]") diff --git a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/partitions.csv b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/partitions.csv new file mode 100644 index 0000000000..0663c96a1a --- /dev/null +++ b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/partitions.csv @@ -0,0 +1,4 @@ +# Name, Type, SubType, Offset, Size, Flags +# Extra partition to demonstrate reading/writing of encrypted flash +factory, app, factory, , 1M, +storage, data, 0xff, 0x170000 , 0x1000, encrypted diff --git a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/sdkconfig.defaults.esp32p4 b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/sdkconfig.defaults.esp32p4 new file mode 100644 index 0000000000..8ff365b198 --- /dev/null +++ b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/sdkconfig.defaults.esp32p4 @@ -0,0 +1,3 @@ +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" From 7acc4d4326ca769f3c483f515b9417b7d4f18f86 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Mon, 25 Mar 2024 00:55:25 +0530 Subject: [PATCH 2/2] fix(esp_hw_support): Fix key manager hw support 1) Added NULL checks for public APIs 2) Added debug prints at necessary places 3) Updated the check for already deployed HUK --- components/esp_hw_support/esp_key_mgr.c | 82 +++++++++++++------ .../esp_hw_support/include/esp_key_mgr.h | 3 +- .../main/test_app_main.c | 11 +++ .../main/test_key_mgr.c | 5 -- 4 files changed, 69 insertions(+), 32 deletions(-) diff --git a/components/esp_hw_support/esp_key_mgr.c b/components/esp_hw_support/esp_key_mgr.c index 80ab17618e..178f0b8038 100644 --- a/components/esp_hw_support/esp_key_mgr.c +++ b/components/esp_hw_support/esp_key_mgr.c @@ -54,6 +54,7 @@ static void esp_key_mgr_acquire_key_lock(esp_key_mgr_key_type_t key_type) _lock_acquire(&s_key_mgr_xts_aes_key_lock); break; } + ESP_LOGV(TAG, "Key lock acquired for key type %d", key_type); } static void esp_key_mgr_release_key_lock(esp_key_mgr_key_type_t key_type) @@ -67,6 +68,7 @@ static void esp_key_mgr_release_key_lock(esp_key_mgr_key_type_t key_type) _lock_release(&s_key_mgr_xts_aes_key_lock); break; } + ESP_LOGV(TAG, "Key lock released for key type %d", key_type); } static void esp_key_mgr_acquire_hardware(bool deployment_mode) @@ -122,14 +124,14 @@ static void check_huk_risk_level(void) 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); + "to avoid permanently 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); } } -static bool check_huk_validity(const esp_key_mgr_huk_info_t *huk_info) +static bool check_huk_info_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) { @@ -162,17 +164,16 @@ static esp_err_t deploy_huk(huk_deploy_config_t *config) 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)) { + if (!check_huk_info_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_LOGI(TAG, "Recovering HUK 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"); @@ -201,7 +202,6 @@ static esp_err_t deploy_huk(huk_deploy_config_t *config) 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); @@ -212,9 +212,9 @@ 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()) { + if ((!key_mgr_hal_is_huk_valid()) || (!config->huk_deployed)) { // 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_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; @@ -222,8 +222,8 @@ static esp_err_t key_mgr_deploy_key_aes_mode(aes_deploy_config_t *config) if (esp_ret != ESP_OK) { return esp_ret; } + ESP_LOGI(TAG, "HUK deployed successfully"); } - ESP_LOGI(TAG, "HUK deployed is Valid"); // STEP 1: Init Step // Set mode @@ -250,6 +250,8 @@ static esp_err_t key_mgr_deploy_key_aes_mode(aes_deploy_config_t *config) key_mgr_hal_use_sw_init_key(); } else { if (!esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_KM_INIT_KEY, NULL)) { + ESP_LOGE(TAG, "Could not find key with purpose KM_INIT_KEY"); + heap_caps_free(key_recovery_info); return ESP_FAIL; } } @@ -263,7 +265,7 @@ static esp_err_t key_mgr_deploy_key_aes_mode(aes_deploy_config_t *config) } 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"); + ESP_LOGD(TAG, "Writing Information into Key Manager Registers"); 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); @@ -302,9 +304,13 @@ static esp_err_t key_mgr_deploy_key_aes_mode(aes_deploy_config_t *config) 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) { + if (key_config == NULL || key_recovery_info == NULL) { + return ESP_ERR_INVALID_ARG; + } + ESP_LOGI(TAG, "Key deployment in AES mode"); - aes_deploy_config_t aes_deploy_config; + 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]; @@ -348,18 +354,20 @@ esp_err_t esp_key_mgr_deploy_key_in_aes_mode(const esp_key_mgr_aes_key_config_t typedef struct key_recovery_config { esp_key_mgr_key_purpose_t key_purpose; esp_key_mgr_key_recovery_info_t *key_recovery_info; + bool huk_recovered; } key_recovery_config_t; static esp_err_t key_mgr_recover_key(key_recovery_config_t *config) { key_mgr_wait_for_state(ESP_KEY_MGR_STATE_IDLE); - if (!check_huk_validity(&config->key_recovery_info->huk_info)) { + if (!check_huk_info_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()) { + if ((!key_mgr_hal_is_huk_valid()) || (!config->huk_recovered)) + { 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) { @@ -371,8 +379,9 @@ static esp_err_t key_mgr_recover_key(key_recovery_config_t *config) // TODO - define error code return ESP_FAIL; } - ESP_LOGI(TAG, "HUK deployed is Valid"); + ESP_LOGI(TAG, "HUK recovered successfully"); ESP_LOG_BUFFER_HEX_LEVEL("HUK INFO", config->key_recovery_info->huk_info.info, KEY_MGR_HUK_INFO_SIZE, ESP_LOG_DEBUG); + config->huk_recovered = true; } key_mgr_hal_set_key_generator_mode(ESP_KEY_MGR_KEYGEN_MODE_RECOVER); @@ -395,13 +404,14 @@ static esp_err_t key_mgr_recover_key(key_recovery_config_t *config) return ESP_FAIL; } key_mgr_hal_write_assist_info(config->key_recovery_info->key_info[1].info, KEY_MGR_KEY_RECOVERY_INFO_SIZE); + ESP_LOG_BUFFER_HEX_LEVEL("RECOVERY_INFO[1]", config->key_recovery_info->key_info[0].info, KEY_MGR_KEY_RECOVERY_INFO_SIZE, ESP_LOG_DEBUG); } 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_DEBUG); + ESP_LOG_BUFFER_HEX_LEVEL("RECOVERY_INFO[0]", config->key_recovery_info->key_info[0].info, KEY_MGR_KEY_RECOVERY_INFO_SIZE, ESP_LOG_DEBUG); } key_mgr_hal_continue(); @@ -411,7 +421,7 @@ static esp_err_t key_mgr_recover_key(key_recovery_config_t *config) ESP_LOGD(TAG, "Key deployment is not valid"); return ESP_FAIL; } - ESP_LOGI(TAG, "Key Recovery valid"); + ESP_LOGD(TAG, "Key Recovery valid"); } key_mgr_hal_continue(); key_mgr_wait_for_state(ESP_KEY_MGR_STATE_IDLE); @@ -420,7 +430,12 @@ static esp_err_t key_mgr_recover_key(key_recovery_config_t *config) esp_err_t esp_key_mgr_activate_key(esp_key_mgr_key_recovery_info_t *key_recovery_info) { + if (key_recovery_info == NULL) { + return ESP_ERR_INVALID_ARG; + } + esp_key_mgr_key_purpose_t key_purpose; + ESP_LOGD(TAG, "Activating key of type %d", key_recovery_info->key_type); 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; @@ -432,9 +447,10 @@ esp_err_t esp_key_mgr_activate_key(esp_key_mgr_key_recovery_info_t *key_recovery 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_t key_recovery_config = {}; key_recovery_config.key_recovery_info = key_recovery_info; key_recovery_config.key_purpose = key_purpose; @@ -457,22 +473,27 @@ esp_err_t esp_key_mgr_activate_key(esp_key_mgr_key_recovery_info_t *key_recovery // 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); + ESP_LOGI(TAG, "Key activation for type %d successful", key_recovery_info->key_type); return ESP_OK; cleanup: + ESP_LOGI(TAG, "Key activation failed"); esp_key_mgr_release_hardware(false); return esp_ret; } esp_err_t esp_key_mgr_deactivate_key(esp_key_mgr_key_type_t key_type) { + ESP_LOGD(TAG, "Deactivating key of type %d", key_type); esp_key_mgr_release_key_lock(key_type); esp_key_mgr_release_hardware(false); + ESP_LOGI(TAG, "Key deactivation successful"); return ESP_OK; } typedef struct ecdh0_config { esp_key_mgr_key_purpose_t key_purpose; + const uint8_t *k1_G; const esp_key_mgr_ecdh0_key_config_t *key_config; esp_key_mgr_key_recovery_info_t *key_info; uint8_t *ecdh0_key_info; @@ -484,7 +505,7 @@ 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() || !config->huk_deployed) { + if ((!key_mgr_hal_is_huk_valid()) || (!config->huk_deployed)) { // 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; @@ -494,8 +515,8 @@ static esp_err_t key_mgr_deploy_key_ecdh0_mode(ecdh0_deploy_config_t *config) if (esp_ret != ESP_OK) { return esp_ret; } + ESP_LOGI(TAG, "HUK deployed successfully"); } - 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) { @@ -522,7 +543,7 @@ static esp_err_t key_mgr_deploy_key_ecdh0_mode(ecdh0_deploy_config_t *config) // 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_write_public_info(config->k1_G, KEY_MGR_ECDH0_INFO_SIZE); key_mgr_hal_continue(); // Step 3: Gain phase @@ -536,6 +557,7 @@ static esp_err_t key_mgr_deploy_key_ecdh0_mode(ecdh0_deploy_config_t *config) 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"); @@ -562,13 +584,17 @@ static esp_err_t key_mgr_deploy_key_ecdh0_mode(ecdh0_deploy_config_t *config) 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) { + if (key_config == NULL || key_info == NULL || ecdh0_key_info == NULL) { + return ESP_ERR_INVALID_ARG; + } 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_t ecdh0_deploy_config = {}; ecdh0_deploy_config.key_config = key_config; ecdh0_deploy_config.key_info = key_info; + ecdh0_deploy_config.k1_G = key_config->k1_G[0]; if (key_type == ESP_KEY_MGR_ECDSA_KEY) { ecdh0_deploy_config.key_purpose = ESP_KEY_MGR_KEY_PURPOSE_ECDSA; @@ -595,6 +621,8 @@ esp_err_t esp_key_mgr_deploy_key_in_ecdh0_mode(const esp_key_mgr_ecdh0_key_confi 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.k1_G = key_config->k1_G[1]; + 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) { @@ -620,9 +648,9 @@ 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() || !config->huk_deployed) { + if ((!key_mgr_hal_is_huk_valid()) || (!config->huk_deployed)) { // 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_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; @@ -630,8 +658,8 @@ static esp_err_t key_mgr_deploy_key_random_mode(random_deploy_config_t *config) if (esp_ret != ESP_OK) { return esp_ret; } + ESP_LOGI(TAG, "HUK deployed successfully"); } - 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); @@ -690,9 +718,13 @@ static esp_err_t key_mgr_deploy_key_random_mode(random_deploy_config_t *config) 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) { + if (key_config == NULL || key_recovery_info == NULL) { + return ESP_ERR_INVALID_ARG; + } + ESP_LOGI(TAG, "Key deployment in Random mode"); - random_deploy_config_t random_deploy_config; + 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; diff --git a/components/esp_hw_support/include/esp_key_mgr.h b/components/esp_hw_support/include/esp_key_mgr.h index 8ed708358d..e32e2acada 100644 --- a/components/esp_hw_support/include/esp_key_mgr.h +++ b/components/esp_hw_support/include/esp_key_mgr.h @@ -29,7 +29,6 @@ extern "C" { #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 { @@ -46,7 +45,7 @@ typedef struct { esp_key_mgr_key_type_t key_type; 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]; + WORD_ALIGNED_ATTR uint8_t k1_G[2][KEY_MGR_ECDH0_INFO_SIZE]; } esp_key_mgr_ecdh0_key_config_t; typedef struct { diff --git a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_app_main.c b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_app_main.c index b893f539bc..e51ca5870d 100644 --- a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_app_main.c +++ b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_app_main.c @@ -15,6 +15,8 @@ #include "memory_checks.h" #include "esp_heap_trace.h" #endif +#include "esp_crypto_lock.h" +#include "esp_partition.h" /* During merging of DS and HMAC testapps to this directory, maximum memory leak during running is 404, so, updating TEST_MEMORY_LEAK_THRESHOLD_DEFAULT */ @@ -48,6 +50,15 @@ void setUp(void) leak_threshold = TEST_MEMORY_LEAK_THRESHOLD_DEFAULT; +#if SOC_KEY_MANAGER_SUPPORTED + esp_crypto_ecc_lock_acquire(); + esp_crypto_sha_aes_lock_acquire(); + esp_crypto_ecc_lock_release(); + esp_crypto_sha_aes_lock_release(); + esp_crypto_key_manager_lock_acquire(); + esp_crypto_key_manager_lock_release(); + esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "storage"); +#endif before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); } 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 index 40e2f1b526..4484a9fde5 100644 --- 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 @@ -101,11 +101,6 @@ static esp_err_t test_xts_aes_key(void) extern void set_leak_threshold(int threshold); TEST_CASE("Key Manager AES mode: XTS-AES key deployment", "[hw_crypto] [key_mgr]") { - // This threshold accounts for multiple locks obtained for the first time by the following APIs - // The larger threshold is only needed for aes mode as additional locks are used in aes mode - set_leak_threshold(-900); - - // Setting the leak threshold to not count the memory allocated for locks used by key manager 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);