mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-29 18:27:20 +02:00
Merge branch 'bugfix/esp32h2_ecdsa_hardware_k_v5.2' into 'release/v5.2'
fix(esp32h2): program use_hardware_k efuse bit for ECDSA key purpose (v5.2) See merge request espressif/esp-idf!27234
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -235,7 +235,7 @@ esp_err_t esp_efuse_write_reg(esp_efuse_block_t blk, unsigned int num_reg, uint3
|
||||
/**
|
||||
* @brief Return efuse coding scheme for blocks.
|
||||
*
|
||||
* Note: The coding scheme is applicable only to 1, 2 and 3 blocks. For 0 block, the coding scheme is always ``NONE``.
|
||||
* @note The coding scheme is applicable only to 1, 2 and 3 blocks. For 0 block, the coding scheme is always ``NONE``.
|
||||
*
|
||||
* @param[in] blk Block number of eFuse.
|
||||
* @return Return efuse coding scheme for blocks
|
||||
@ -708,6 +708,12 @@ esp_err_t esp_efuse_set_write_protect_of_digest_revoke(unsigned num_digest);
|
||||
*
|
||||
* The burn of a key, protection bits, and a purpose happens in batch mode.
|
||||
*
|
||||
* @note This API also enables the read protection efuse bit for certain key blocks like XTS-AES, HMAC, ECDSA etc.
|
||||
* This ensures that the key is only accessible to hardware peripheral.
|
||||
*
|
||||
* @note For SoC's with capability `SOC_EFUSE_ECDSA_USE_HARDWARE_K` (e.g., ESP32-H2), this API writes an additional
|
||||
* efuse bit for ECDSA key purpose to enforce hardware TRNG generated k mode in the peripheral.
|
||||
*
|
||||
* @param[in] block Block to read purpose for. Must be in range EFUSE_BLK_KEY0 to EFUSE_BLK_KEY_MAX. Key block must be unused (esp_efuse_key_block_unused).
|
||||
* @param[in] purpose Purpose to set for this key. Purpose must be already unset.
|
||||
* @param[in] key Pointer to data to write.
|
||||
@ -727,6 +733,12 @@ esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpo
|
||||
*
|
||||
* The burn of keys, protection bits, and purposes happens in batch mode.
|
||||
*
|
||||
* @note This API also enables the read protection efuse bit for certain key blocks like XTS-AES, HMAC, ECDSA etc.
|
||||
* This ensures that the key is only accessible to hardware peripheral.
|
||||
*
|
||||
* @note For SoC's with capability `SOC_EFUSE_ECDSA_USE_HARDWARE_K` (e.g., ESP32-H2), this API writes an additional
|
||||
* efuse bit for ECDSA key purpose to enforce hardware TRNG generated k mode in the peripheral.
|
||||
*
|
||||
* @param[in] purposes Array of purposes (purpose[number_of_keys]).
|
||||
* @param[in] keys Array of keys (uint8_t keys[number_of_keys][32]). Each key is 32 bytes long.
|
||||
* @param[in] number_of_keys The number of keys to write (up to 6 keys).
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -315,6 +315,12 @@ esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpo
|
||||
purpose == ESP_EFUSE_KEY_PURPOSE_HMAC_UP) {
|
||||
ESP_EFUSE_CHK(esp_efuse_set_key_dis_read(block));
|
||||
}
|
||||
#if SOC_EFUSE_ECDSA_USE_HARDWARE_K
|
||||
if (purpose == ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY) {
|
||||
// Permanently enable the hardware TRNG supplied k mode (most secure mode)
|
||||
ESP_EFUSE_CHK(esp_efuse_write_field_bit(ESP_EFUSE_ECDSA_FORCE_USE_HARDWARE_K));
|
||||
}
|
||||
#endif
|
||||
ESP_EFUSE_CHK(esp_efuse_set_key_purpose(block, purpose));
|
||||
ESP_EFUSE_CHK(esp_efuse_set_keypurpose_dis_write(block));
|
||||
return esp_efuse_batch_write_commit();
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "esp_newlib.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_table.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "esp_xt_wdt.h"
|
||||
@ -348,6 +349,15 @@ static void do_core_init(void)
|
||||
esp_secure_boot_init_checks();
|
||||
#endif
|
||||
|
||||
#if SOC_EFUSE_ECDSA_USE_HARDWARE_K
|
||||
if (esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY, NULL)) {
|
||||
// ECDSA key purpose block is present and hence permanently enable
|
||||
// the hardware TRNG supplied k mode (most secure mode)
|
||||
err = esp_efuse_write_field_bit(ESP_EFUSE_ECDSA_FORCE_USE_HARDWARE_K);
|
||||
assert(err == ESP_OK && "Failed to enable ECDSA hardware k mode");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_SECURE_DISABLE_ROM_DL_MODE
|
||||
err = esp_efuse_disable_rom_download_mode();
|
||||
assert(err == ESP_OK && "Failed to disable ROM download mode");
|
||||
|
@ -30,22 +30,17 @@ static void configure_ecdsa_periph(ecdsa_hal_config_t *conf)
|
||||
ecdsa_ll_set_curve(conf->curve);
|
||||
|
||||
if (conf->mode != ECDSA_MODE_EXPORT_PUBKEY) {
|
||||
ecdsa_ll_set_k_mode(conf->k_mode);
|
||||
ecdsa_ll_set_z_mode(conf->sha_mode);
|
||||
}
|
||||
}
|
||||
|
||||
void ecdsa_hal_gen_signature(ecdsa_hal_config_t *conf, const uint8_t *k, const uint8_t *hash,
|
||||
void ecdsa_hal_gen_signature(ecdsa_hal_config_t *conf, const uint8_t *hash,
|
||||
uint8_t *r_out, uint8_t *s_out, uint16_t len)
|
||||
{
|
||||
if (len != ECDSA_HAL_P192_COMPONENT_LEN && len != ECDSA_HAL_P256_COMPONENT_LEN) {
|
||||
HAL_ASSERT(false && "Incorrect length");
|
||||
}
|
||||
|
||||
if (conf->k_mode == ECDSA_K_USER_PROVIDED && k == NULL) {
|
||||
HAL_ASSERT(false && "Mismatch in K configuration");
|
||||
}
|
||||
|
||||
if (conf->sha_mode == ECDSA_Z_USER_PROVIDED && hash == NULL) {
|
||||
HAL_ASSERT(false && "Mismatch in SHA configuration");
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ typedef enum {
|
||||
ECDSA_PARAM_R,
|
||||
ECDSA_PARAM_S,
|
||||
ECDSA_PARAM_Z,
|
||||
ECDSA_PARAM_K,
|
||||
ECDSA_PARAM_QAX,
|
||||
ECDSA_PARAM_QAY
|
||||
} ecdsa_ll_param_t;
|
||||
@ -190,26 +189,6 @@ static inline void ecdsa_ll_set_curve(ecdsa_curve_t curve)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the source of `K`
|
||||
*
|
||||
* @param mode Mode of K generation
|
||||
*/
|
||||
static inline void ecdsa_ll_set_k_mode(ecdsa_k_mode_t mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case ECDSA_K_USE_TRNG:
|
||||
REG_CLR_BIT(ECDSA_CONF_REG, ECDSA_SOFTWARE_SET_K);
|
||||
break;
|
||||
case ECDSA_K_USER_PROVIDED:
|
||||
REG_SET_BIT(ECDSA_CONF_REG, ECDSA_SOFTWARE_SET_K);
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false && "Unsupported curve");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the source of `Z` (SHA message)
|
||||
*
|
||||
@ -335,7 +314,6 @@ static inline void ecdsa_ll_write_param(ecdsa_ll_param_t param, const uint8_t *b
|
||||
case ECDSA_PARAM_Z:
|
||||
reg = ECDSA_Z_MEM;
|
||||
break;
|
||||
case ECDSA_PARAM_K:
|
||||
case ECDSA_PARAM_QAX:
|
||||
reg = ECDSA_QAX_MEM;
|
||||
break;
|
||||
@ -373,7 +351,6 @@ static inline void ecdsa_ll_read_param(ecdsa_ll_param_t param, uint8_t *buf, uin
|
||||
case ECDSA_PARAM_Z:
|
||||
reg = ECDSA_Z_MEM;
|
||||
break;
|
||||
case ECDSA_PARAM_K:
|
||||
case ECDSA_PARAM_QAX:
|
||||
reg = ECDSA_QAX_MEM;
|
||||
break;
|
||||
|
@ -23,7 +23,6 @@ typedef enum {
|
||||
ECDSA_PARAM_R,
|
||||
ECDSA_PARAM_S,
|
||||
ECDSA_PARAM_Z,
|
||||
ECDSA_PARAM_K,
|
||||
ECDSA_PARAM_QAX,
|
||||
ECDSA_PARAM_QAY
|
||||
} ecdsa_ll_param_t;
|
||||
@ -199,26 +198,6 @@ static inline void ecdsa_ll_set_curve(ecdsa_curve_t curve)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the source of `K`
|
||||
*
|
||||
* @param mode Mode of K generation
|
||||
*/
|
||||
static inline void ecdsa_ll_set_k_mode(ecdsa_k_mode_t mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case ECDSA_K_USE_TRNG:
|
||||
REG_CLR_BIT(ECDSA_CONF_REG, ECDSA_SOFTWARE_SET_K);
|
||||
break;
|
||||
case ECDSA_K_USER_PROVIDED:
|
||||
REG_SET_BIT(ECDSA_CONF_REG, ECDSA_SOFTWARE_SET_K);
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false && "Unsupported curve");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the source of `Z` (SHA message)
|
||||
*
|
||||
@ -344,7 +323,6 @@ static inline void ecdsa_ll_write_param(ecdsa_ll_param_t param, const uint8_t *b
|
||||
case ECDSA_PARAM_Z:
|
||||
reg = ECDSA_Z_MEM;
|
||||
break;
|
||||
case ECDSA_PARAM_K:
|
||||
case ECDSA_PARAM_QAX:
|
||||
reg = ECDSA_QAX_MEM;
|
||||
break;
|
||||
@ -382,7 +360,6 @@ static inline void ecdsa_ll_read_param(ecdsa_ll_param_t param, uint8_t *buf, uin
|
||||
case ECDSA_PARAM_Z:
|
||||
reg = ECDSA_Z_MEM;
|
||||
break;
|
||||
case ECDSA_PARAM_K:
|
||||
case ECDSA_PARAM_QAX:
|
||||
reg = ECDSA_QAX_MEM;
|
||||
break;
|
||||
|
@ -27,7 +27,6 @@ extern "C" {
|
||||
typedef struct {
|
||||
ecdsa_mode_t mode; /* Mode of operation */
|
||||
ecdsa_curve_t curve; /* Curve to use for operation */
|
||||
ecdsa_k_mode_t k_mode; /* Source of K */
|
||||
ecdsa_sha_mode_t sha_mode; /* Source of SHA that needs to be signed */
|
||||
int efuse_key_blk; /* Efuse block to use as ECDSA key (The purpose of the efuse block must be ECDSA_KEY) */
|
||||
bool use_km_key; /* Use an ECDSA key from the Key Manager peripheral */
|
||||
@ -37,13 +36,12 @@ typedef struct {
|
||||
* @brief Generate ECDSA signature
|
||||
*
|
||||
* @param conf Configuration for ECDSA operation, see ``ecdsa_hal_config_t``
|
||||
* @param k Value of K used internally. Set this to NULL if K is generated by hardware
|
||||
* @param hash Hash that is to be signed
|
||||
* @param r_out Buffer that will contain `R` component of ECDSA signature
|
||||
* @param s_out Buffer that will contain `S` component of ECDSA signature
|
||||
* @param len Length of the r_out and s_out buffer (32 bytes for SECP256R1, 24 for SECP192R1)
|
||||
*/
|
||||
void ecdsa_hal_gen_signature(ecdsa_hal_config_t *conf, const uint8_t *k, const uint8_t *hash,
|
||||
void ecdsa_hal_gen_signature(ecdsa_hal_config_t *conf, const uint8_t *hash,
|
||||
uint8_t *r_out, uint8_t *s_out, uint16_t len);
|
||||
|
||||
/**
|
||||
|
@ -26,14 +26,6 @@ typedef enum {
|
||||
ECDSA_CURVE_SECP256R1,
|
||||
} ecdsa_curve_t;
|
||||
|
||||
/**
|
||||
* @brief Source of 'K' used internally for generating signature
|
||||
*/
|
||||
typedef enum {
|
||||
ECDSA_K_USE_TRNG,
|
||||
ECDSA_K_USER_PROVIDED,
|
||||
} ecdsa_k_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Source of SHA message that is to be signed/verified
|
||||
*/
|
||||
|
@ -50,7 +50,6 @@ static int test_ecdsa_verify(bool is_p256, uint8_t* sha, uint8_t* r_le, uint8_t*
|
||||
|
||||
ecdsa_hal_config_t conf = {
|
||||
.mode = ECDSA_MODE_SIGN_VERIFY,
|
||||
.k_mode = ECDSA_K_USE_TRNG,
|
||||
.sha_mode = ECDSA_Z_USER_PROVIDED,
|
||||
};
|
||||
|
||||
@ -119,7 +118,6 @@ static void test_ecdsa_sign(bool is_p256, uint8_t* sha, uint8_t* r_le, uint8_t*
|
||||
|
||||
ecdsa_hal_config_t conf = {
|
||||
.mode = ECDSA_MODE_SIGN_GEN,
|
||||
.k_mode = ECDSA_K_USE_TRNG,
|
||||
.sha_mode = ECDSA_Z_USER_PROVIDED,
|
||||
.use_km_key = use_km_key,
|
||||
};
|
||||
@ -144,7 +142,7 @@ static void test_ecdsa_sign(bool is_p256, uint8_t* sha, uint8_t* r_le, uint8_t*
|
||||
ecdsa_enable_and_reset();
|
||||
|
||||
do {
|
||||
ecdsa_hal_gen_signature(&conf, NULL, sha_le, r_le, s_le, len);
|
||||
ecdsa_hal_gen_signature(&conf, sha_le, r_le, s_le, len);
|
||||
} while(!memcmp(r_le, zeroes, len) || !memcmp(s_le, zeroes, len));
|
||||
|
||||
ecdsa_disable();
|
||||
|
@ -244,13 +244,12 @@ static int esp_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi* r, mbedtls_mpi* s
|
||||
ecdsa_hal_config_t conf = {
|
||||
.mode = ECDSA_MODE_SIGN_GEN,
|
||||
.curve = curve,
|
||||
.k_mode = ECDSA_K_USE_TRNG,
|
||||
.sha_mode = ECDSA_Z_USER_PROVIDED,
|
||||
.efuse_key_blk = d->MBEDTLS_PRIVATE(n),
|
||||
.use_km_key = 0, //TODO: IDF-7992
|
||||
};
|
||||
|
||||
ecdsa_hal_gen_signature(&conf, NULL, sha_le, r_le, s_le, len);
|
||||
ecdsa_hal_gen_signature(&conf, sha_le, r_le, s_le, len);
|
||||
} while (!memcmp(r_le, zeroes, len) || !memcmp(s_le, zeroes, len));
|
||||
|
||||
esp_ecdsa_release_hardware();
|
||||
@ -470,7 +469,6 @@ static int esp_ecdsa_verify(mbedtls_ecp_group *grp,
|
||||
ecdsa_hal_config_t conf = {
|
||||
.mode = ECDSA_MODE_SIGN_VERIFY,
|
||||
.curve = curve,
|
||||
.k_mode = ECDSA_K_USE_TRNG,
|
||||
.sha_mode = ECDSA_Z_USER_PROVIDED,
|
||||
};
|
||||
|
||||
|
@ -24,14 +24,14 @@ extern "C" {
|
||||
* by the peripheral, a flag load_pubkey that is used specify if the public key has to be populated
|
||||
*/
|
||||
typedef struct {
|
||||
mbedtls_ecp_group_id grp_id;
|
||||
uint8_t efuse_block;
|
||||
mbedtls_ecp_group_id grp_id; /*!< MbedTLS ECP group identifier */
|
||||
uint8_t efuse_block; /*!< EFuse block id for ECDSA private key */
|
||||
#ifdef SOC_ECDSA_SUPPORT_EXPORT_PUBKEY
|
||||
bool load_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)
|
||||
|
||||
#ifdef SOC_ECDSA_SUPPORT_EXPORT_PUBKEY
|
||||
#if SOC_ECDSA_SUPPORT_EXPORT_PUBKEY || __DOXYGEN__
|
||||
|
||||
/**
|
||||
* @brief Populate the public key buffer of the mbedtls_ecp_keypair context.
|
||||
@ -45,9 +45,10 @@ typedef struct {
|
||||
* - -1 if invalid efuse block is specified
|
||||
*/
|
||||
int esp_ecdsa_load_pubkey(mbedtls_ecp_keypair *keypair, int efuse_blk);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
|
||||
#endif // SOC_ECDSA_SUPPORT_EXPORT_PUBKEY || __DOXYGEN__
|
||||
|
||||
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN || __DOXYGEN__
|
||||
|
||||
/**
|
||||
* @brief Initialize MPI to notify mbedtls_ecdsa_sign to use the private key in efuse
|
||||
@ -97,7 +98,8 @@ int esp_ecdsa_privkey_load_pk_context(mbedtls_pk_context *key_ctx, int efuse_blk
|
||||
* - -1 otherwise
|
||||
*/
|
||||
int esp_ecdsa_set_pk_context(mbedtls_pk_context *key_ctx, esp_ecdsa_pk_conf_t *conf);
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN || __DOXYGEN__
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1079,6 +1079,10 @@ config SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_EFUSE_ECDSA_USE_HARDWARE_K
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_SECURE_BOOT_V2_RSA
|
||||
bool
|
||||
default y
|
||||
|
@ -441,6 +441,7 @@
|
||||
#define SOC_EFUSE_SOFT_DIS_JTAG 1
|
||||
#define SOC_EFUSE_DIS_ICACHE 1
|
||||
#define SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK 1 // XTS-AES and ECDSA key purposes not supported for this block
|
||||
#define SOC_EFUSE_ECDSA_USE_HARDWARE_K 1 // Force use hardware TRNG supplied K for ECDSA
|
||||
|
||||
/*-------------------------- Secure Boot CAPS----------------------------*/
|
||||
#define SOC_SECURE_BOOT_V2_RSA 1
|
||||
|
@ -209,6 +209,7 @@ conditional_include_dict = {'SOC_BT_SUPPORTED':BT_DOCS,
|
||||
'SOC_RISCV_COPROC_SUPPORTED':RISCV_COPROC_DOCS,
|
||||
'SOC_LP_CORE_SUPPORTED':LP_CORE_DOCS,
|
||||
'SOC_DIG_SIGN_SUPPORTED':['api-reference/peripherals/ds.rst'],
|
||||
'SOC_ECDSA_SUPPORTED':['api-reference/peripherals/ecdsa.rst'],
|
||||
'SOC_HMAC_SUPPORTED':['api-reference/peripherals/hmac.rst'],
|
||||
'SOC_ASYNC_MEMCPY_SUPPORTED':['api-reference/system/async_memcpy.rst'],
|
||||
'CONFIG_IDF_TARGET_ARCH_XTENSA':XTENSA_DOCS,
|
||||
|
@ -260,6 +260,7 @@ INPUT = \
|
||||
$(PROJECT_PATH)/components/lwip/include/apps/esp_sntp.h \
|
||||
$(PROJECT_PATH)/components/lwip/include/apps/ping/ping_sock.h \
|
||||
$(PROJECT_PATH)/components/mbedtls/esp_crt_bundle/include/esp_crt_bundle.h \
|
||||
$(PROJECT_PATH)/components/mbedtls/port/include/ecdsa/ecdsa_alt.h \
|
||||
$(PROJECT_PATH)/components/mqtt/esp-mqtt/include/mqtt_client.h \
|
||||
$(PROJECT_PATH)/components/nvs_flash/include/nvs_flash.h \
|
||||
$(PROJECT_PATH)/components/nvs_flash/include/nvs.h \
|
||||
|
82
docs/en/api-reference/peripherals/ecdsa.rst
Normal file
82
docs/en/api-reference/peripherals/ecdsa.rst
Normal file
@ -0,0 +1,82 @@
|
||||
Elliptic Curve Digital Signature Algorithm (ECDSA)
|
||||
==================================================
|
||||
|
||||
The Elliptic Curve Digital Signature Algorithm (ECDSA) offers a variant of the Digital Signature Algorithm (DSA) which uses elliptic-curve cryptography.
|
||||
|
||||
{IDF_TARGET_NAME}'s ECDSA peripheral provides a secure and efficient environment for computing ECDSA signatures. It offers fast computations while ensuring the confidentiality of the signing process to prevent information leakage. ECDSA private key used in the signing process is accessible only to the hardware peripheral, and it is not readable by software.
|
||||
|
||||
ECDSA peripheral can help to establish **Secure Device Identity** for TLS mutual authentication and similar use-cases.
|
||||
|
||||
Supported Features
|
||||
------------------
|
||||
|
||||
- ECDSA digital signature generation and verification
|
||||
- Two different elliptic curves, namely P-192 and P-256 (FIPS 186-3 specification)
|
||||
- Two hash algorithms for message hash in the ECDSA operation, namely SHA-224 and SHA-256 (FIPS PUB 180-4 specification)
|
||||
|
||||
|
||||
ECDSA on {IDF_TARGET_NAME}
|
||||
--------------------------
|
||||
|
||||
On {IDF_TARGET_NAME}, the ECDSA module works with a secret key burnt into an eFuse block. This eFuse key is made completely inaccessible (default mode) for any resources outside the cryptographic modules, thus avoiding key leakage.
|
||||
|
||||
ECDSA key can be programmed externally through ``espefuse.py`` script using:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
espefuse.py burn_key <BLOCK_NUM> </path/to/ecdsa_private_key.pem> ECDSA_KEY
|
||||
|
||||
.. only:: SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK
|
||||
|
||||
.. note::
|
||||
|
||||
Five physical eFuse blocks can be used as keys for the ECDSA module: block 4 ~ block 8. E.g., for block 4 (which is the first key block) , the argument should be ``BLOCK_KEY0``.
|
||||
|
||||
.. only:: not SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK
|
||||
|
||||
.. note::
|
||||
|
||||
Six physical eFuse blocks can be used as keys for the ECDSA module: block 4 ~ block 9. E.g., for block 4 (which is the first key block) , the argument should be ``BLOCK_KEY0``.
|
||||
|
||||
|
||||
Alternatively the ECDSA key can also be programmed through the application running on the target.
|
||||
|
||||
Following code snippet uses :cpp:func:`esp_efuse_write_key` to set physical key block 0 in the eFuse with key purpose as :cpp:enumerator:`esp_efuse_purpose_t::ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY`:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#include "esp_efuse.h"
|
||||
|
||||
const uint8_t key_data[32] = { ... };
|
||||
|
||||
esp_err_t status = esp_efuse_write_key(EFUSE_BLK_KEY0,
|
||||
ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY,
|
||||
key_data, sizeof(key_data));
|
||||
|
||||
if (status == ESP_OK) {
|
||||
// written key
|
||||
} else {
|
||||
// writing key failed, maybe written already
|
||||
}
|
||||
|
||||
|
||||
Dependency on TRNG
|
||||
------------------
|
||||
|
||||
ECDSA peripheral relies on the hardware True Random Number Generator (TRNG) for its internal entropy requirement. During ECDSA signature creation, the algorithm requires a random integer to be generated as specified in the `RFC 6090 <https://tools.ietf.org/html/rfc6090>`_ section 5.3.2.
|
||||
|
||||
Please ensure that hardware :doc:`RNG <../system/random>` is enabled before starting ECDSA computations (primarily signing) in the application.
|
||||
|
||||
Application Outline
|
||||
-------------------
|
||||
|
||||
Please refer to the :ref:`ecdsa-peri-with-esp-tls` guide for details on how-to use ECDSA peripheral for establishing a mutually authenticated TLS connection.
|
||||
|
||||
The ECDSA peripheral in mbedTLS stack is integrated by overriding the ECDSA sign and verify APIs. Please note that, the ECDSA peripheral does not support all curves or hash algorithms and hence for cases where the requirements do not meet the hardware, implementation falls back to the software.
|
||||
|
||||
For a particular TLS context, additional APIs have been supplied to populate certain fields (e.g., private key ctx) to differentiate routing to hardware. ESP-TLS layer integrates these APIs internally and hence no additional work is required at the application layer. However, for custom use-cases please refer to API details below.
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include-build-file:: inc/ecdsa_alt.inc
|
@ -12,6 +12,7 @@ Peripherals API
|
||||
:SOC_ANA_CMPR_SUPPORTED: ana_cmpr
|
||||
clk_tree
|
||||
:SOC_DAC_SUPPORTED: dac
|
||||
:SOC_ECDSA_SUPPORTED: ecdsa
|
||||
:SOC_ETM_SUPPORTED: etm
|
||||
gpio
|
||||
gptimer
|
||||
|
@ -203,6 +203,8 @@ The following table shows a typical comparison between WolfSSL and MbedTLS when
|
||||
|
||||
.. only:: SOC_ECDSA_SUPPORTED
|
||||
|
||||
.. _ecdsa-peri-with-esp-tls:
|
||||
|
||||
ECDSA Peripheral with ESP-TLS
|
||||
-----------------------------
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
Random Number Generation
|
||||
========================
|
||||
|
||||
{IDF_TARGET_RF_NAME: default="Wi-Fi or Bluetooth", esp32s2="Wi-Fi"}
|
||||
{IDF_TARGET_RF_NAME: default="Wi-Fi or Bluetooth", esp32s2="Wi-Fi", esp32h2="Bluetooth or 802.15.4 Thread/Zigbee", esp32c6="Wi-Fi or Bluetooth or 802.15.4 Thread/Zigbee"}
|
||||
{IDF_TARGET_RF_IS: default="are", esp32s2="is"}
|
||||
{IDF_TARGET_BOOTLOADER_RANDOM_INCOMPATIBLE: default="", esp32="I2S, "}
|
||||
|
||||
|
@ -1,6 +1,10 @@
|
||||
Security
|
||||
========
|
||||
|
||||
{IDF_TARGET_CIPHER_SCHEME:default="RSA", esp32h2="RSA or ECDSA", esp32p4="RSA or ECDSA"}
|
||||
|
||||
{IDF_TARGET_SIG_PERI:default="DS", esp32h2="DS or ECDSA", esp32p4="DS or ECDSA"}
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
This guide provides an overview of the overall security features available in various Espressif solutions. It is highly recommended to consider this guide while designing the products with the Espressif platform and the ESP-IDF software stack from the **security** perspective.
|
||||
@ -73,9 +77,19 @@ Flash Encryption Best Practices
|
||||
|
||||
The Digital Signature peripheral in {IDF_TARGET_NAME} produces hardware-accelerated RSA digital signatures with the assistance of HMAC, without the RSA private key being accessible by software. This allows the private key to be kept secured on the device without anyone other than the device hardware being able to access it.
|
||||
|
||||
This peripheral can help to establish the **Secure Device Identity** to the remote endpoint, e.g., in the case of TLS mutual authentication based on the RSA cipher scheme.
|
||||
.. only:: SOC_ECDSA_SUPPORTED
|
||||
|
||||
Please refer to the :doc:`../api-reference/peripherals/ds` for detailed documentation.
|
||||
{IDF_TARGET_NAME} also supportes ECDSA peripheral for generating hardware-accelerated ECDSA digital signatures. ECDSA private key can be directly programmed in an eFuse block and marked as read protected from the software.
|
||||
|
||||
{IDF_TARGET_SIG_PERI} peripheral can help to establish the **Secure Device Identity** to the remote endpoint, e.g., in the case of TLS mutual authentication based on the {IDF_TARGET_CIPHER_SCHEME} cipher scheme.
|
||||
|
||||
.. only:: not SOC_ECDSA_SUPPORTED
|
||||
|
||||
Please refer to the :doc:`../api-reference/peripherals/ds` for detailed documentation.
|
||||
|
||||
.. only:: SOC_ECDSA_SUPPORTED
|
||||
|
||||
Please refer to the :doc:`../api-reference/peripherals/ecdsa` and :doc:`../api-reference/peripherals/ds` guides for detailed documentation.
|
||||
|
||||
.. only:: SOC_MEMPROT_SUPPORTED or SOC_CPU_IDRAM_SPLIT_USING_PMP
|
||||
|
||||
|
1
docs/zh_CN/api-reference/peripherals/ecdsa.rst
Normal file
1
docs/zh_CN/api-reference/peripherals/ecdsa.rst
Normal file
@ -0,0 +1 @@
|
||||
.. include:: ../../../en/api-reference/peripherals/ecdsa.rst
|
@ -12,6 +12,7 @@
|
||||
:SOC_ANA_CMPR_SUPPORTED: ana_cmpr
|
||||
clk_tree
|
||||
:SOC_DAC_SUPPORTED: dac
|
||||
:SOC_ECDSA_SUPPORTED: ecdsa
|
||||
:SOC_ETM_SUPPORTED: etm
|
||||
gpio
|
||||
gptimer
|
||||
|
@ -203,6 +203,8 @@ MbedTLS 与 WolfSSL 对比
|
||||
|
||||
.. only:: SOC_ECDSA_SUPPORTED
|
||||
|
||||
.. _ecdsa-peri-with-esp-tls:
|
||||
|
||||
在 ESP-TLS 中使用 ECDSA 外设
|
||||
-----------------------------
|
||||
|
||||
|
Reference in New Issue
Block a user