mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
feat(esp_security): add ECDH1 deployment mode to Key Manager driver
This commit is contained in:
@@ -423,6 +423,10 @@ static esp_err_t key_mgr_deploy_key_aes_mode(aes_deploy_config_t *config)
|
||||
|
||||
key_mgr_hal_read_public_info(key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
|
||||
|
||||
// Wait till Key Manager deployment is complete
|
||||
key_mgr_hal_continue();
|
||||
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_IDLE);
|
||||
|
||||
// Check if key deployment validation should be skipped for this purpose
|
||||
// Primary purposes in multi-stage deployments skip validation after the first stage
|
||||
// because the key is not yet completely deployed.
|
||||
@@ -434,10 +438,6 @@ static esp_err_t key_mgr_deploy_key_aes_mode(aes_deploy_config_t *config)
|
||||
}
|
||||
ESP_LOGD(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);
|
||||
|
||||
config->key_info->key_info[key_recovery_info_index].crc = esp_rom_crc32_le(0, key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
|
||||
config->key_info->key_type = key_type;
|
||||
config->key_info->key_len = key_len;
|
||||
@@ -709,6 +709,10 @@ static esp_err_t key_mgr_deploy_key_ecdh0_mode(ecdh0_deploy_config_t *config)
|
||||
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);
|
||||
|
||||
// Wait till Key Manager deployment is complete
|
||||
key_mgr_hal_continue();
|
||||
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_IDLE);
|
||||
|
||||
// Check if key deployment validation should be skipped for this purpose
|
||||
// Primary purposes in multi-stage deployments skip validation after the first stage
|
||||
// because the key is not yet completely deployed.
|
||||
@@ -720,10 +724,6 @@ static esp_err_t key_mgr_deploy_key_ecdh0_mode(ecdh0_deploy_config_t *config)
|
||||
}
|
||||
ESP_LOGD(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);
|
||||
|
||||
config->key_info->key_info[key_recovery_info_index].crc = esp_rom_crc32_le(0, key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
|
||||
config->key_info->key_type = key_type;
|
||||
config->key_info->key_len = key_len;
|
||||
@@ -789,6 +789,155 @@ cleanup:
|
||||
return esp_ret;
|
||||
}
|
||||
|
||||
typedef struct ecdh1_deploy {
|
||||
esp_key_mgr_key_purpose_t key_purpose;
|
||||
const uint8_t *k1_G;
|
||||
const esp_key_mgr_ecdh1_key_config_t *key_config;
|
||||
esp_key_mgr_key_recovery_info_t *key_info;
|
||||
bool huk_deployed;
|
||||
} ecdh1_deploy_config_t;
|
||||
|
||||
static esp_err_t key_mgr_deploy_key_ecdh1_mode(ecdh1_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)) {
|
||||
huk_deploy_config_t huk_deploy_config = {
|
||||
.use_pre_generated_huk_info = config->key_config->use_pre_generated_huk_info,
|
||||
.pre_generated_huk_info = &config->key_config->huk_info,
|
||||
.huk_recovery_info = &config->key_info->huk_info,
|
||||
};
|
||||
|
||||
esp_ret = deploy_huk(&huk_deploy_config);
|
||||
if (esp_ret != ESP_OK) {
|
||||
return esp_ret;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "HUK deployed successfully");
|
||||
}
|
||||
|
||||
uint8_t key_recovery_info_index = is_multi_stage_key_purpose(config->key_purpose) ? 0 : 1;
|
||||
|
||||
uint8_t *key_recovery_info = config->key_info->key_info[key_recovery_info_index].info;
|
||||
|
||||
// Step 1: Initialization
|
||||
key_mgr_hal_set_key_generator_mode(ESP_KEY_MGR_KEYGEN_MODE_ECDH1);
|
||||
|
||||
key_mgr_hal_set_key_purpose(config->key_purpose);
|
||||
|
||||
esp_key_mgr_key_type_t key_type = config->key_config->key_type;
|
||||
esp_key_mgr_key_len_t key_len = config->key_config->key_len;
|
||||
|
||||
if (key_type == ESP_KEY_MGR_FLASH_XTS_AES_KEY || key_type == ESP_KEY_MGR_PSRAM_XTS_AES_KEY) {
|
||||
key_mgr_hal_set_xts_aes_key_len(key_type, key_len);
|
||||
}
|
||||
|
||||
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)) {
|
||||
ESP_LOGE(TAG, "Could not find key with purpose KM_INIT_KEY");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
key_mgr_hal_start();
|
||||
|
||||
// Step 2: Load phase
|
||||
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_LOAD);
|
||||
|
||||
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_LOGD(TAG, "Writing Information into Key Manager Registers");
|
||||
key_mgr_hal_write_assist_info(config->key_config->k2_info, KEY_MGR_K2_INFO_SIZE);
|
||||
|
||||
key_mgr_hal_write_public_info(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);
|
||||
|
||||
// Wait till Key Manager deployment is complete
|
||||
key_mgr_hal_continue();
|
||||
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_IDLE);
|
||||
|
||||
// Check if key deployment validation should be skipped for this purpose
|
||||
// Primary purposes in multi-stage deployments skip validation after the first stage
|
||||
// because the key is not yet completely deployed.
|
||||
if (!is_multi_stage_key_purpose(config->key_purpose)) {
|
||||
if (!key_mgr_hal_is_key_deployment_valid(key_type, key_len)) {
|
||||
ESP_LOGE(TAG, "Key deployment is not valid");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
ESP_LOGD(TAG, "Key deployment valid");
|
||||
|
||||
config->key_info->key_info[key_recovery_info_index].crc = esp_rom_crc32_le(0, key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
|
||||
config->key_info->key_type = key_type;
|
||||
config->key_info->key_len = key_len;
|
||||
config->key_info->key_deployment_mode = ESP_KEY_MGR_KEYGEN_MODE_ECDH1;
|
||||
config->key_info->magic = KEY_HUK_SECTOR_MAGIC;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_key_mgr_deploy_key_in_ecdh1_mode(const esp_key_mgr_ecdh1_key_config_t *key_config,
|
||||
esp_key_mgr_key_recovery_info_t *key_info)
|
||||
{
|
||||
if (!key_mgr_ll_is_supported()) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (key_config == NULL || key_info == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Key Deployment in ECDH1 mode");
|
||||
|
||||
ecdh1_deploy_config_t ecdh1_deploy_config = {
|
||||
.key_config = key_config,
|
||||
.key_info = key_info,
|
||||
.k1_G = key_config->k1_G[0],
|
||||
};
|
||||
|
||||
ecdh1_deploy_config.key_purpose = get_key_purpose(key_config->key_type, key_config->key_len);
|
||||
if (ecdh1_deploy_config.key_purpose == ESP_KEY_MGR_KEY_PURPOSE_INVALID) {
|
||||
ESP_LOGE(TAG, "Invalid key type");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_key_mgr_acquire_hardware(true);
|
||||
|
||||
esp_err_t esp_ret = key_mgr_deploy_key_ecdh1_mode(&ecdh1_deploy_config);
|
||||
if (esp_ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Key deployment in ECDH1 mode failed");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ecdh1_deploy_config.huk_deployed = true;
|
||||
|
||||
if (is_multi_stage_key_purpose(ecdh1_deploy_config.key_purpose)) {
|
||||
ecdh1_deploy_config.key_purpose = get_secondary_key_purpose(ecdh1_deploy_config.key_purpose);
|
||||
ecdh1_deploy_config.k1_G = key_config->k1_G[1];
|
||||
esp_ret = key_mgr_deploy_key_ecdh1_mode(&ecdh1_deploy_config);
|
||||
if (esp_ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Key deployment in ECDH1 mode failed");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
cleanup:
|
||||
esp_key_mgr_release_hardware(true);
|
||||
return esp_ret;
|
||||
}
|
||||
|
||||
typedef struct random_deploy {
|
||||
esp_key_mgr_key_purpose_t key_purpose;
|
||||
const esp_key_mgr_random_key_config_t *key_config;
|
||||
@@ -845,6 +994,10 @@ static esp_err_t key_mgr_deploy_key_random_mode(random_deploy_config_t *config)
|
||||
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);
|
||||
|
||||
// Wait till Key Manager deployment is complete
|
||||
key_mgr_hal_continue();
|
||||
key_mgr_wait_for_state(ESP_KEY_MGR_STATE_IDLE);
|
||||
|
||||
// Check if key deployment validation should be skipped for this purpose
|
||||
// Primary purposes in multi-stage deployments skip validation after the first stage
|
||||
// because the key is not yet completely deployed.
|
||||
@@ -856,10 +1009,6 @@ static esp_err_t key_mgr_deploy_key_random_mode(random_deploy_config_t *config)
|
||||
}
|
||||
ESP_LOGD(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);
|
||||
|
||||
config->key_info->key_info[key_recovery_info_index].crc = esp_rom_crc32_le(0, key_recovery_info, KEY_MGR_KEY_RECOVERY_INFO_SIZE);
|
||||
config->key_info->key_type = key_type;
|
||||
config->key_info->key_len = key_len;
|
||||
|
||||
Reference in New Issue
Block a user