feat(esp_security): Move DS, HMAC, DPA and crypto lock implementation

This commit is contained in:
Mahavir Jain 2024-08-07 15:17:32 +05:30
parent 262f27290b
commit 79f9c7d157
31 changed files with 220 additions and 170 deletions

View File

@ -8,9 +8,10 @@ if(${target} STREQUAL "linux")
return()
endif()
set(requires soc esp_security) # TODO: remove esp_security from REQUIRES in ESP-IDF v6.0
set(requires soc)
# only esp_hw_support/adc_share_hw_ctrl.c requires efuse component
set(priv_requires efuse spi_flash bootloader_support)
# TODO: remove esp_security from REQUIRES in ESP-IDF v6.0 (see IDF-10733)
set(priv_requires efuse spi_flash bootloader_support esp_security)
if(${target} STREQUAL "esp32c6")
list(APPEND priv_requires hal)
@ -187,7 +188,4 @@ if(NOT BOOTLOADER_BUILD)
if(CONFIG_SPIRAM)
idf_component_optional_requires(PRIVATE esp_psram)
endif()
if(CONFIG_SOC_CRYPTO_DPA_PROTECTION_SUPPORTED)
target_link_libraries(${COMPONENT_LIB} PRIVATE "-u esp_crypto_dpa_prot_include_impl")
endif()
endif()

View File

@ -243,44 +243,6 @@ menu "Hardware Settings"
orsource "./port/$IDF_TARGET/Kconfig.xtal"
endmenu
menu "Crypto DPA Protection"
depends on SOC_CRYPTO_DPA_PROTECTION_SUPPORTED
config ESP_CRYPTO_DPA_PROTECTION_AT_STARTUP
bool "Enable crypto DPA protection at startup"
default y
help
This config controls the DPA (Differential Power Analysis) protection
knob for the crypto peripherals. DPA protection dynamically adjusts the
clock frequency of the crypto peripheral. DPA protection helps to make it
difficult to perform SCA attacks on the crypto peripherals. However,
there is also associated performance impact based on the security level
set. Please refer to the TRM for more details.
choice ESP_CRYPTO_DPA_PROTECTION_LEVEL
prompt "DPA protection level"
depends on ESP_CRYPTO_DPA_PROTECTION_AT_STARTUP
default ESP_CRYPTO_DPA_PROTECTION_LEVEL_LOW
help
Configure the DPA protection security level
config ESP_CRYPTO_DPA_PROTECTION_LEVEL_LOW
bool "Security level low"
config ESP_CRYPTO_DPA_PROTECTION_LEVEL_MEDIUM
bool "Security level medium"
config ESP_CRYPTO_DPA_PROTECTION_LEVEL_HIGH
bool "Security level high"
endchoice
config ESP_CRYPTO_DPA_PROTECTION_LEVEL
int
default 1 if ESP_CRYPTO_DPA_PROTECTION_LEVEL_LOW
default 2 if ESP_CRYPTO_DPA_PROTECTION_LEVEL_MEDIUM
default 3 if ESP_CRYPTO_DPA_PROTECTION_LEVEL_HIGH
endmenu
orsource "./port/$IDF_TARGET/Kconfig.dcdc"
orsource "./port/$IDF_TARGET/Kconfig.ldo"

View File

@ -132,9 +132,9 @@ typedef struct {
* since the message digest matches.
*/
esp_err_t esp_ds_sign(const void *message,
const esp_ds_data_t *data,
hmac_key_id_t key_id,
void *signature);
const esp_ds_data_t *data,
hmac_key_id_t key_id,
void *signature);
/**
* @brief Start the signing process.
@ -172,9 +172,9 @@ esp_err_t esp_ds_sign(const void *message,
* - ESP_ERR_HW_CRYPTO_DS_INVALID_KEY if there's a problem with passing the HMAC key to the DS component
*/
esp_err_t esp_ds_start_sign(const void *message,
const esp_ds_data_t *data,
hmac_key_id_t key_id,
esp_ds_context_t **esp_ds_ctx);
const esp_ds_data_t *data,
hmac_key_id_t key_id,
esp_ds_context_t **esp_ds_ctx);
/**
* Return true if the DS peripheral is busy, otherwise false.
@ -227,9 +227,9 @@ esp_err_t esp_ds_finish_sign(void *signature, esp_ds_context_t *esp_ds_ctx);
* - ESP_ERR_INVALID_ARG if one of the parameters is NULL or p_data->rsa_length is too long
*/
esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data,
const void *iv,
const esp_ds_p_data_t *p_data,
const void *key);
const void *iv,
const esp_ds_p_data_t *p_data,
const void *key);
#ifdef __cplusplus
}

View File

@ -6,7 +6,6 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -40,7 +40,7 @@ typedef enum {
*
* @note Uses the HMAC peripheral in "upstream" mode.
*
* @param key_id Determines which of the 6 key blocks in the efuses should be used for the HMAC calcuation.
* @param key_id Determines which of the 6 key blocks in the efuses should be used for the HMAC calculation.
* The corresponding purpose field of the key block in the efuse must be set to the HMAC upstream purpose value.
* @param message the message for which to calculate the HMAC
* @param message_len message length

View File

@ -1,37 +0,0 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void esp_crypto_ecc_lock_acquire(void);
/**
* @brief Release lock for the ECC cryptography peripheral.
*
*/
void esp_crypto_ecc_lock_release(void);
/**
* @brief Acquire lock for ECDSA cryptography peripheral
*
* Internally also locks the ECC and MPI peripheral, as the ECDSA depends on these peripherals
*/
void esp_crypto_ecdsa_lock_acquire(void);
/**
* @brief Release lock for ECDSA cryptography peripheral
*
* Internally also releases the ECC and MPI peripheral, as the ECDSA depends on these peripherals
*/
void esp_crypto_ecdsa_lock_release(void);
#ifdef __cplusplus
}
#endif

View File

@ -1,46 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <sys/lock.h>
#include "esp_crypto_lock.h"
/* Lock overview:
SHA: peripheral independent, but DMA is shared with AES
AES: peripheral independent, but DMA is shared with SHA
MPI/RSA: independent
ECC: independent
HMAC: needs SHA
DS: needs HMAC (which needs SHA), AES and MPI
*/
/* Lock for ECC peripheral */
static _lock_t s_crypto_ecc_lock;
/* Lock for ECDSA peripheral */
static _lock_t s_crypto_ecdsa_lock;
void esp_crypto_ecc_lock_acquire(void)
{
_lock_acquire(&s_crypto_ecc_lock);
}
void esp_crypto_ecc_lock_release(void)
{
_lock_release(&s_crypto_ecc_lock);
}
void esp_crypto_ecdsa_lock_acquire(void)
{
_lock_acquire(&s_crypto_ecdsa_lock);
esp_crypto_ecc_lock_acquire();
}
void esp_crypto_ecdsa_lock_release(void)
{
esp_crypto_ecc_lock_release();
_lock_release(&s_crypto_ecdsa_lock);
}

View File

@ -1,24 +1,42 @@
idf_build_get_property(target IDF_TARGET)
if(${target} STREQUAL "linux")
return() # This component is not supported by the POSIX/Linux simulator
endif()
set(srcs "")
set(priv_requires "soc")
set(priv_requires "")
set(priv_includes "")
if(NOT BOOTLOADER_BUILD)
if(CONFIG_IDF_TARGET_ESP32H2 OR CONFIG_IDF_TARGET_ESP32P4 OR CONFIG_IDF_TARGET_ESP32C5)
list(APPEND srcs "src/crypto/${IDF_TARGET}/clk.c")
list(APPEND srcs "src/init.c")
list(APPEND priv_includes "src/${IDF_TARGET}")
if(CONFIG_SOC_HMAC_SUPPORTED)
list(APPEND srcs "src/esp_hmac.c")
endif()
if(CONFIG_SOC_DIG_SIGN_SUPPORTED)
list(APPEND srcs "src/esp_ds.c")
endif()
if(CONFIG_SOC_KEY_MANAGER_SUPPORTED)
list(APPEND srcs "src/esp_key_mgr.c")
endif()
if(CONFIG_SOC_CRYPTO_DPA_PROTECTION_SUPPORTED)
list(APPEND srcs "src/crypto/esp_dpa_protection.c")
list(APPEND srcs "src/esp_dpa_protection.c")
endif()
list(APPEND srcs "src/crypto/esp_crypto_lock.c")
list(APPEND srcs "src/esp_crypto_lock.c")
list(APPEND priv_requires efuse esp_hw_support esp_system esp_timer)
endif()
idf_component_register(SRCS ${srcs}
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS ${priv_includes}
PRIV_REQUIRES ${priv_requires})
if(NOT BOOTLOADER_BUILD)
if(CONFIG_SOC_CRYPTO_DPA_PROTECTION_SUPPORTED)
target_link_libraries(${COMPONENT_LIB} PRIVATE "-u esp_crypto_dpa_prot_include_impl")
endif()
target_link_libraries(${COMPONENT_LIB} PRIVATE "-u esp_security_init_include_impl")
endif()

View File

@ -0,0 +1,40 @@
menu "ESP Security Specific"
menu "Crypto DPA Protection"
depends on SOC_CRYPTO_DPA_PROTECTION_SUPPORTED
config ESP_CRYPTO_DPA_PROTECTION_AT_STARTUP
bool "Enable crypto DPA protection at startup"
default y
help
This config controls the DPA (Differential Power Analysis) protection
knob for the crypto peripherals. DPA protection dynamically adjusts
clock frequency of the crypto peripheral. DPA protection helps to make it
difficult to perform SCA attacks on the crypto peripherals. However,
there is also associated performance impact based on the security level
set. Please refer to the TRM for more details.
choice ESP_CRYPTO_DPA_PROTECTION_LEVEL
prompt "DPA protection level"
depends on ESP_CRYPTO_DPA_PROTECTION_AT_STARTUP
default ESP_CRYPTO_DPA_PROTECTION_LEVEL_LOW
help
Configure the DPA protection security level
config ESP_CRYPTO_DPA_PROTECTION_LEVEL_LOW
bool "Security level low"
config ESP_CRYPTO_DPA_PROTECTION_LEVEL_MEDIUM
bool "Security level medium"
config ESP_CRYPTO_DPA_PROTECTION_LEVEL_HIGH
bool "Security level high"
endchoice
config ESP_CRYPTO_DPA_PROTECTION_LEVEL
int
default 1 if ESP_CRYPTO_DPA_PROTECTION_LEVEL_LOW
default 2 if ESP_CRYPTO_DPA_PROTECTION_LEVEL_MEDIUM
default 3 if ESP_CRYPTO_DPA_PROTECTION_LEVEL_HIGH
endmenu
endmenu

View File

@ -0,0 +1,10 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/* nothing to do */
static inline void esp_crypto_clk_init(void) {}

View File

@ -0,0 +1,10 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/* nothing to do */
static inline void esp_crypto_clk_init(void) {}

View File

@ -0,0 +1,10 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/* nothing to do */
static inline void esp_crypto_clk_init(void) {}

View File

@ -3,10 +3,13 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/soc.h"
#include "soc/pcr_reg.h"
__attribute__((weak)) void esp_crypto_clk_init(void)
#pragma once
static inline void esp_crypto_clk_init(void)
{
// Set crypto clock (`clk_sec`) to use 480M SPLL clock
REG_SET_FIELD(PCR_SEC_CONF_REG, PCR_SEC_CLK_SEL, 0x2);

View File

@ -0,0 +1,10 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/* nothing to do */
static inline void esp_crypto_clk_init(void) {}

View File

@ -0,0 +1,16 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/soc.h"
#include "soc/pcr_reg.h"
#pragma once
static inline void esp_crypto_clk_init(void)
{
// Set crypto clock (`clk_sec`) to use 480M SPLL clock
REG_SET_FIELD(PCR_SEC_CONF_REG, PCR_SEC_CLK_SEL, 0x2);
}

View File

@ -3,10 +3,13 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/soc.h"
#include "soc/pcr_reg.h"
__attribute__((weak)) void esp_crypto_clk_init(void)
#pragma once
static inline void esp_crypto_clk_init(void)
{
// Set crypto clock (`clk_sec`) to use 96M PLL clock
REG_SET_FIELD(PCR_SEC_CONF_REG, PCR_SEC_CLK_SEL, 0x3);

View File

@ -6,7 +6,9 @@
#include "soc/soc.h"
#include "soc/hp_sys_clkrst_reg.h"
__attribute__((weak)) void esp_crypto_clk_init(void)
#pragma once
static inline void esp_crypto_clk_init(void)
{
// Set crypto clock (`clk_sec`) to use 240M PLL clock
REG_SET_FIELD(HP_SYS_CLKRST_PERI_CLK_CTRL25_REG, HP_SYS_CLKRST_REG_CRYPTO_CLK_SRC_SEL, 0x2);

View File

@ -0,0 +1,10 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/* nothing to do */
static inline void esp_crypto_clk_init(void) {}

View File

@ -0,0 +1,10 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/* nothing to do */
static inline void esp_crypto_clk_init(void) {}

View File

@ -16,12 +16,10 @@ static inline void esp_crypto_dpa_set_level(esp_crypto_dpa_sec_level_t level)
REG_SET_FIELD(HP_SYSTEM_SEC_DPA_CONF_REG, HP_SYSTEM_SEC_DPA_LEVEL, level);
}
#if CONFIG_ESP_CRYPTO_DPA_PROTECTION_AT_STARTUP
static void __attribute__((constructor)) esp_crypto_dpa_protection_startup(void)
void esp_crypto_dpa_protection_startup(void)
{
esp_crypto_dpa_set_level(CONFIG_ESP_CRYPTO_DPA_PROTECTION_LEVEL);
}
#endif
void esp_crypto_dpa_protection_enable(esp_crypto_dpa_sec_level_t level)
{
@ -32,8 +30,3 @@ void esp_crypto_dpa_protection_disable(void)
{
REG_CLR_BIT(HP_SYSTEM_SEC_DPA_CONF_REG, HP_SYSTEM_SEC_DPA_CFG_SEL);
}
void esp_crypto_dpa_prot_include_impl(void)
{
// Linker hook, exists for no other purpose
}

View File

@ -163,7 +163,8 @@ esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
return ESP_OK;
}
static ets_efuse_block_t convert_key_type(hmac_key_id_t key_id) {
static ets_efuse_block_t convert_key_type(hmac_key_id_t key_id)
{
return ETS_EFUSE_BLOCK_KEY0 + (ets_efuse_block_t) key_id;
}
@ -172,8 +173,9 @@ esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token)
int ets_status;
esp_err_t err = ESP_OK;
if ((!token) || (key_id >= HMAC_KEY_MAX))
if ((!token) || (key_id >= HMAC_KEY_MAX)) {
return ESP_ERR_INVALID_ARG;
}
/* Check if JTAG is permanently disabled by HW Disable eFuse */
if (esp_efuse_read_field_bit(JTAG_STATUS_BIT)) {
@ -224,18 +226,23 @@ esp_err_t esp_hmac_jtag_disable()
}
#else /* !CONFIG_IDF_TARGET_ESP32S2 */
static ets_efuse_block_t convert_key_type(hmac_key_id_t key_id) {
static ets_efuse_block_t convert_key_type(hmac_key_id_t key_id)
{
return ETS_EFUSE_BLOCK_KEY0 + (ets_efuse_block_t) key_id;
}
esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
const void *message,
size_t message_len,
uint8_t *hmac)
const void *message,
size_t message_len,
uint8_t *hmac)
{
int hmac_ret;
if (!message || !hmac) return ESP_ERR_INVALID_ARG;
if (key_id >= HMAC_KEY_MAX) return ESP_ERR_INVALID_ARG;
if (!message || !hmac) {
return ESP_ERR_INVALID_ARG;
}
if (key_id >= HMAC_KEY_MAX) {
return ESP_ERR_INVALID_ARG;
}
esp_crypto_dma_lock_acquire();
@ -257,8 +264,9 @@ esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token)
int ets_status;
esp_err_t err = ESP_OK;
if ((!token) || (key_id >= HMAC_KEY_MAX))
if ((!token) || (key_id >= HMAC_KEY_MAX)) {
return ESP_ERR_INVALID_ARG;
}
/* Check if JTAG is permanently disabled by HW Disable eFuse */
if (esp_efuse_read_field_bit(ESP_EFUSE_HARD_DIS_JTAG)) {

View File

@ -366,8 +366,7 @@ static esp_err_t key_mgr_recover_key(key_recovery_config_t *config)
}
ESP_LOGD(TAG, "HUK info valid");
if ((!key_mgr_hal_is_huk_valid()) || (!config->huk_recovered))
{
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) {

View File

@ -0,0 +1,11 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/* Private interface file */
void esp_crypto_dpa_protection_startup(void);

View File

@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_private/startup_internal.h"
#include "sdkconfig.h"
#include "esp_crypto_clk.h"
#include "esp_security_priv.h"
ESP_SYSTEM_INIT_FN(esp_security_init, SECONDARY, BIT(0), 103)
{
esp_crypto_clk_init();
#if CONFIG_ESP_CRYPTO_DPA_PROTECTION_AT_STARTUP
esp_crypto_dpa_protection_startup();
#endif
return ESP_OK;
}
void esp_security_init_include_impl(void)
{
// Linker hook, exists for no other purpose
}

View File

@ -106,9 +106,6 @@ __attribute__((weak)) void esp_clk_init(void)
// Re calculate the ccount to make time calculation correct.
esp_cpu_set_cycle_count((uint64_t)esp_cpu_get_cycle_count() * new_freq_mhz / old_freq_mhz);
// Set crypto clock (`clk_sec`) to use 480M SPLL clock
REG_SET_FIELD(PCR_SEC_CONF_REG, PCR_SEC_CLK_SEL, 0x2);
}
static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src)