feat: enabled ecdsa support for c5

This commit adds support for ECDSA for ESP32-C5
This commit is contained in:
nilesh.kale 2024-03-07 15:49:11 +05:30
parent 3d7a0d6cd0
commit 00fa28259b
11 changed files with 504 additions and 8 deletions

View File

@ -75,6 +75,20 @@ void esp_crypto_ecc_lock_acquire(void);
*/
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

@ -32,6 +32,9 @@ static _lock_t s_crypto_sha_aes_lock;
/* 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_hmac_lock_acquire(void)
{
_lock_acquire(&s_crypto_hmac_lock);
@ -87,3 +90,15 @@ 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

@ -22,8 +22,6 @@
#define ESP_ROM_HAS_REGI2C_BUG (1) // ROM has the regi2c bug
#define ESP_ROM_HAS_NEWLIB (1) // ROM has newlib (at least parts of it) functions included
#define ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT (1) // ROM has the newlib normal/full version of formatting functions (as opposed to the nano versions)
// TODO: [ESP32C5] IDF-8618
// #define ESP_ROM_REV0_HAS_NO_ECDSA_INTERFACE (1) // ECO 0 does not have ets_ecdsa_verify symbol, future revision will have it
#define ESP_ROM_WDT_INIT_PATCH (1) // ROM version does not configure the clock
#define ESP_ROM_RAM_APP_NEEDS_MMU_INIT (1) // ROM doesn't init cache MMU when it's a RAM APP, needs MMU hal to init
#define ESP_ROM_HAS_VERSION (1) // ROM has version/eco information

View File

@ -9,6 +9,11 @@
#include "hal/ecdsa_hal.h"
#include "hal/efuse_hal.h"
// Need to remove in IDF-8621
#if CONFIG_IDF_TARGET_ESP32C5
#include "soc/keymng_reg.h"
#endif
#ifdef SOC_KEY_MANAGER_SUPPORTED
#include "hal/key_mgr_hal.h"
#endif
@ -22,6 +27,12 @@ static void configure_ecdsa_periph(ecdsa_hal_config_t *conf)
if (conf->use_km_key == 0) {
efuse_hal_set_ecdsa_key(conf->efuse_key_blk);
// Need to remove in IDF-8621
#if CONFIG_IDF_TARGET_ESP32C5
REG_SET_FIELD(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY, 1);
#endif
#if SOC_KEY_MANAGER_SUPPORTED
key_mgr_hal_set_key_usage(ESP_KEY_MGR_ECDSA_KEY, ESP_KEY_MGR_USE_EFUSE_KEY);
#endif

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

View File

@ -0,0 +1,443 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <string.h>
#include "hal/assert.h"
#include "soc/ecdsa_reg.h"
#include "soc/pcr_struct.h"
#include "hal/ecdsa_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Memory blocks of ECDSA parameters
*/
typedef enum {
ECDSA_PARAM_R,
ECDSA_PARAM_S,
ECDSA_PARAM_Z,
ECDSA_PARAM_QAX,
ECDSA_PARAM_QAY
} ecdsa_ll_param_t;
/**
* @brief Interrupt types in ECDSA
*/
typedef enum {
ECDSA_INT_CALC_DONE,
ECDSA_INT_SHA_RELEASE,
} ecdsa_ll_intr_type_t;
/**
* @brief Stages of ECDSA operation
*/
typedef enum {
ECDSA_STAGE_START_CALC,
ECDSA_STAGE_LOAD_DONE,
ECDSA_STAGE_GET_DONE
} ecdsa_ll_stage_t;
/**
* @brief States of ECDSA peripheral
*/
typedef enum {
ECDSA_STATE_IDLE,
ECDSA_STATE_LOAD,
ECDSA_STATE_GET,
ECDSA_STATE_BUSY
} ecdsa_ll_state_t;
/**
* @brief Types of SHA
*/
typedef enum {
ECDSA_SHA_224,
ECDSA_SHA_256
} ecdsa_ll_sha_type_t;
/**
* @brief Operation modes of SHA
*/
typedef enum {
ECDSA_MODE_SHA_START,
ECDSA_MODE_SHA_CONTINUE
} ecdsa_ll_sha_mode_t;
/**
* @brief Get the state of ECDSA peripheral
*
* @return State of ECDSA
*/
static inline uint32_t ecdsa_ll_get_state(void)
{
return REG_GET_FIELD(ECDSA_STATE_REG, ECDSA_BUSY);
}
/**
* @brief Enable the bus clock for ECDSA peripheral module
*
* @param true to enable the module, false to disable the module
*/
static inline void ecdsa_ll_enable_bus_clock(bool enable)
{
PCR.ecdsa_conf.ecdsa_clk_en = enable;
}
/**
* @brief Reset the ECDSA peripheral module
*/
static inline void ecdsa_ll_reset_register(void)
{
PCR.ecdsa_conf.ecdsa_rst_en = 1;
PCR.ecdsa_conf.ecdsa_rst_en = 0;
while (ecdsa_ll_get_state() != ECDSA_STATE_IDLE) {
;
}
}
/**
* @brief Enable interrupt of a given type
*
* @param type Interrupt type
*/
static inline void ecdsa_ll_enable_intr(ecdsa_ll_intr_type_t type)
{
switch (type) {
case ECDSA_INT_CALC_DONE:
#if !CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
REG_SET_FIELD(ECDSA_INT_ENA_REG, ECDSA_PREP_DONE_INT_ENA, 0);
#else
REG_SET_FIELD(ECDSA_INT_ENA_REG, ECDSA_CALC_DONE_INT_ENA, 0);
#endif
break;
case ECDSA_INT_SHA_RELEASE:
REG_SET_FIELD(ECDSA_INT_ENA_REG, ECDSA_SHA_RELEASE_INT_ENA, 1);
break;
default:
HAL_ASSERT(false && "Unsupported interrupt type");
break;
}
}
/**
* @brief Disable interrupt of a given type
*
* @param type Interrupt type
*/
static inline void ecdsa_ll_disable_intr(ecdsa_ll_intr_type_t type)
{
switch (type) {
case ECDSA_INT_CALC_DONE:
#if !CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
REG_SET_FIELD(ECDSA_INT_ENA_REG, ECDSA_PREP_DONE_INT_ENA, 0);
#else
REG_SET_FIELD(ECDSA_INT_ENA_REG, ECDSA_CALC_DONE_INT_ENA, 0);
#endif
break;
case ECDSA_INT_SHA_RELEASE:
REG_SET_FIELD(ECDSA_INT_ENA_REG, ECDSA_SHA_RELEASE_INT_ENA, 0);
break;
default:
HAL_ASSERT(false && "Unsupported interrupt type");
break;
}
}
/**
* @brief Clear interrupt of a given type
*
* @param type Interrupt type
*/
static inline void ecdsa_ll_clear_intr(ecdsa_ll_intr_type_t type)
{
switch (type) {
case ECDSA_INT_CALC_DONE:
#if !CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
REG_SET_FIELD(ECDSA_INT_ENA_REG, ECDSA_PREP_DONE_INT_CLR, 0);
#else
REG_SET_FIELD(ECDSA_INT_ENA_REG, ECDSA_CALC_DONE_INT_CLR, 0);
#endif
break;
case ECDSA_INT_SHA_RELEASE:
REG_SET_FIELD(ECDSA_INT_CLR_REG, ECDSA_SHA_RELEASE_INT_CLR, 1);
break;
default:
HAL_ASSERT(false && "Unsupported interrupt type");
break;
}
}
/**
* @brief Set working mode of ECDSA
*
* @param mode Mode of operation
*/
static inline void ecdsa_ll_set_mode(ecdsa_mode_t mode)
{
switch (mode) {
case ECDSA_MODE_SIGN_VERIFY:
REG_SET_FIELD(ECDSA_CONF_REG, ECDSA_WORK_MODE, 0);
break;
case ECDSA_MODE_SIGN_GEN:
REG_SET_FIELD(ECDSA_CONF_REG, ECDSA_WORK_MODE, 1);
break;
case ECDSA_MODE_EXPORT_PUBKEY:
REG_SET_FIELD(ECDSA_CONF_REG, ECDSA_WORK_MODE, 2);
break;
default:
HAL_ASSERT(false && "Unsupported mode");
break;
}
}
/**
* @brief Set curve for ECDSA operation
*
* @param curve ECDSA curve
*/
static inline void ecdsa_ll_set_curve(ecdsa_curve_t curve)
{
switch (curve) {
case ECDSA_CURVE_SECP256R1:
REG_SET_BIT(ECDSA_CONF_REG, ECDSA_ECC_CURVE);
break;
case ECDSA_CURVE_SECP192R1:
REG_CLR_BIT(ECDSA_CONF_REG, ECDSA_ECC_CURVE);
break;
default:
HAL_ASSERT(false && "Unsupported curve");
return;
}
}
/**
* @brief Set the source of `Z` (SHA message)
*
* @param mode Mode of SHA generation
*/
static inline void ecdsa_ll_set_z_mode(ecdsa_ll_sha_mode_t mode)
{
switch (mode) {
case ECDSA_Z_USE_SHA_PERI:
REG_CLR_BIT(ECDSA_CONF_REG, ECDSA_SOFTWARE_SET_Z);
break;
case ECDSA_Z_USER_PROVIDED:
REG_SET_BIT(ECDSA_CONF_REG, ECDSA_SOFTWARE_SET_Z);
break;
default:
HAL_ASSERT(false && "Unsupported curve");
break;
}
}
/**
* @brief Set the signature generation type of ECDSA operation
*
* @param type Type of the ECDSA signature
*/
static inline void ecdsa_ll_set_k_type(ecdsa_sign_type_t type)
{
switch (type) {
case ECDSA_K_TYPE_TRNG:
REG_CLR_BIT(ECDSA_CONF_REG, ECDSA_DETERMINISTIC_K);
break;
#ifdef SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE
case ECDSA_K_TYPE_DETERMINISITIC:
REG_SET_BIT(ECDSA_CONF_REG, ECDSA_DETERMINISTIC_K);
break;
#endif
default:
HAL_ASSERT(false && "Unsupported K type");
break;
}
}
/**
* @brief Set the loop number value that is used for deterministic derivation of K
*
* @param loop_number Loop number for deterministic K
*/
static inline void ecdsa_ll_set_deterministic_loop(uint16_t loop_number)
{
REG_SET_FIELD(ECDSA_CONF_REG, ECDSA_DETERMINISTIC_LOOP, loop_number);
}
/**
* @brief Set the stage of ECDSA operation
*
* @param stage Stage of operation
*/
static inline void ecdsa_ll_set_stage(ecdsa_ll_stage_t stage)
{
switch (stage) {
case ECDSA_STAGE_START_CALC:
REG_SET_BIT(ECDSA_START_REG, ECDSA_START);
break;
case ECDSA_STAGE_LOAD_DONE:
REG_SET_BIT(ECDSA_START_REG, ECDSA_LOAD_DONE);
break;
case ECDSA_STAGE_GET_DONE:
REG_SET_BIT(ECDSA_START_REG, ECDSA_GET_DONE);
break;
default:
HAL_ASSERT(false && "Unsupported state");
break;
}
}
/**
* @brief Set the SHA type
*
* @param type Type of SHA
*/
static inline void ecdsa_ll_sha_set_type(ecdsa_ll_sha_type_t type)
{
switch (type) {
case ECDSA_SHA_224:
REG_SET_FIELD(ECDSA_SHA_MODE_REG, ECDSA_SHA_MODE, 1);
break;
case ECDSA_SHA_256:
REG_SET_FIELD(ECDSA_SHA_MODE_REG, ECDSA_SHA_MODE, 2);
break;
default:
HAL_ASSERT(false && "Unsupported type");
break;
}
}
/**
* @brief Set the SHA operation mode
*
* @param mode Mode of SHA operation
*/
static inline void ecdsa_ll_sha_set_mode(ecdsa_ll_sha_mode_t mode)
{
switch (mode) {
case ECDSA_MODE_SHA_START:
REG_SET_BIT(ECDSA_SHA_START_REG, ECDSA_SHA_START);
break;
case ECDSA_MODE_SHA_CONTINUE:
REG_SET_BIT(ECDSA_SHA_CONTINUE_REG, ECDSA_SHA_CONTINUE);
break;
default:
HAL_ASSERT(false && "Unsupported type");
break;
}
}
/**
* @brief Check if SHA is busy
*
* @return - true, if SHA is busy
* - false, if SHA is IDLE
*/
static inline bool ecdsa_ll_sha_is_busy(void)
{
return REG_GET_BIT(ECDSA_SHA_BUSY_REG, ECDSA_SHA_BUSY);
}
/**
* @brief Write the ECDSA parameter
*
* @param param Parameter to be written
* @param buf Buffer containing data
* @param len Length of buffer
*/
static inline void ecdsa_ll_write_param(ecdsa_ll_param_t param, const uint8_t *buf, uint16_t len)
{
uint32_t reg;
uint32_t word;
switch (param) {
case ECDSA_PARAM_R:
reg = ECDSA_R_MEM;
break;
case ECDSA_PARAM_S:
reg = ECDSA_S_MEM;
break;
case ECDSA_PARAM_Z:
reg = ECDSA_Z_MEM;
break;
case ECDSA_PARAM_QAX:
reg = ECDSA_QAX_MEM;
break;
case ECDSA_PARAM_QAY:
reg = ECDSA_QAY_MEM;
break;
default:
HAL_ASSERT(false && "Invalid parameter");
return;
}
for (int i = 0; i < len; i += 4) {
memcpy(&word, buf + i, 4);
REG_WRITE(reg + i, word);
}
}
/**
* @brief Read the ECDSA parameter
*
* @param param Parameter to be read
* @param buf Buffer where the data will be written
* @param len Length of buffer
*/
static inline void ecdsa_ll_read_param(ecdsa_ll_param_t param, uint8_t *buf, uint16_t len)
{
uint32_t reg;
switch (param) {
case ECDSA_PARAM_R:
reg = ECDSA_R_MEM;
break;
case ECDSA_PARAM_S:
reg = ECDSA_S_MEM;
break;
case ECDSA_PARAM_Z:
reg = ECDSA_Z_MEM;
break;
case ECDSA_PARAM_QAX:
reg = ECDSA_QAX_MEM;
break;
case ECDSA_PARAM_QAY:
reg = ECDSA_QAY_MEM;
break;
default:
HAL_ASSERT(false && "Invalid parameter");
return;
}
memcpy(buf, (void *)reg, len);
}
/**
* @brief Check if the ECDSA operation is successful
*
* @return - 1, if ECDSA operation succeeds
* - 0, otherwise
*/
static inline int ecdsa_ll_get_operation_result(void)
{
return REG_GET_BIT(ECDSA_RESULT_REG, ECDSA_OPERATION_RESULT);
}
/**
* @brief Check if the k value is greater than the curve order.
*
* @return 0, k value is not greater than the curve order. In this case, the k value is the set k value.
* @return 1, k value is greater than than the curve order. In this case, the k value is the set (k mod n).
*/
static inline int ecdsa_ll_check_k_value(void)
{
return REG_GET_BIT(ECDSA_RESULT_REG, ECDSA_K_VALUE_WARNING);
}
#ifdef __cplusplus
}
#endif

View File

@ -16,7 +16,6 @@
extern "C" {
#endif
/**
* @brief get chip version
*/

View File

@ -135,6 +135,10 @@ config SOC_SPI_FLASH_SUPPORTED
bool
default y
config SOC_ECDSA_SUPPORTED
bool
default y
config SOC_LIGHT_SLEEP_SUPPORTED
bool
default y
@ -483,6 +487,10 @@ config SOC_SHA_SUPPORT_SHA256
bool
default y
config SOC_ECDSA_SUPPORT_EXPORT_PUBKEY
bool
default y
config SOC_SPI_PERIPH_NUM
int
default 2

View File

@ -73,7 +73,7 @@
// #define SOC_WDT_SUPPORTED 1 // TODO: [ESP32C5] IDF-8650
#define SOC_SPI_FLASH_SUPPORTED 1 // TODO: [ESP32C5] IDF-8715
// #define SOC_BITSCRAMBLER_SUPPORTED 1 // TODO: [ESP32C5] IDF-8711
// #define SOC_ECDSA_SUPPORTED 1 // TODO: [ESP32C5] IDF-8618
#define SOC_ECDSA_SUPPORTED 1
// #define SOC_KEY_MANAGER_SUPPORTED 1 // TODO: [ESP32C5] IDF-8621
// #define SOC_HUK_SUPPORTED 1 // TODO: [ESP32C5] IDF-8617
#define SOC_LIGHT_SLEEP_SUPPORTED 1
@ -376,7 +376,7 @@
#define SOC_SHA_SUPPORT_SHA256 (1)
/*--------------------------- ECDSA CAPS ---------------------------------------*/
// #define SOC_ECDSA_SUPPORT_EXPORT_PUBKEY (1)
#define SOC_ECDSA_SUPPORT_EXPORT_PUBKEY (1)
/*-------------------------- Sigma Delta Modulator CAPS -----------------*/
// #define SOC_SDM_GROUPS 1U

View File

@ -99,6 +99,10 @@ config SOC_SPI_FLASH_SUPPORTED
bool
default y
config SOC_ECDSA_SUPPORTED
bool
default y
config SOC_XTAL_SUPPORT_40M
bool
default y
@ -463,6 +467,10 @@ config SOC_SHA_SUPPORT_SHA256
bool
default y
config SOC_ECDSA_SUPPORT_EXPORT_PUBKEY
bool
default y
config SOC_SPI_PERIPH_NUM
int
default 2

View File

@ -69,7 +69,7 @@
// #define SOC_WDT_SUPPORTED 1 // TODO: [ESP32C5] IDF-8650
#define SOC_SPI_FLASH_SUPPORTED 1 // TODO: [ESP32C5] IDF-8715
// #define SOC_BITSCRAMBLER_SUPPORTED 1 // TODO: [ESP32C5] IDF-8711
// #define SOC_ECDSA_SUPPORTED 1 // TODO: [ESP32C5] IDF-8618
#define SOC_ECDSA_SUPPORTED 1
// #define SOC_KEY_MANAGER_SUPPORTED 1 // TODO: [ESP32C5] IDF-8621
// #define SOC_HUK_SUPPORTED 1 // TODO: [ESP32C5] IDF-8617
// #define SOC_MODEM_CLOCK_SUPPORTED 1 // TODO: [ESP32C5] IDF-8845
@ -376,7 +376,7 @@
#define SOC_SHA_SUPPORT_SHA256 (1)
/*--------------------------- ECDSA CAPS ---------------------------------------*/
// #define SOC_ECDSA_SUPPORT_EXPORT_PUBKEY (1)
#define SOC_ECDSA_SUPPORT_EXPORT_PUBKEY (1)
/*-------------------------- Sigma Delta Modulator CAPS -----------------*/
// #define SOC_SDM_GROUPS 1U