From 0ccfa4b0c2fd83e66b24c9fabb9562f1581be470 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Fri, 3 Nov 2023 15:48:00 +0530 Subject: [PATCH 1/5] fix(esp32h2): program use_hardware_k efuse bit for ECDSA key purpose In ESP32-H2, the ECDSA peripheral by default uses the TRNG (hardware) generated k value but it can be overridden to software supplied k. This can happen through by overriding the `ECDSA_SOFTWARE_SET_K` bit in the configuration register. Even though the HAL API is not exposed for this but still it could be achieved by direct register programming. And for this scenario, if sufficiently random k is not supplied by the software then it could posses a security risk. In this change, we are unconditionally programming the efuse `ESP_EFUSE_ECDSA_FORCE_USE_HARDWARE_K` bit during startup security checks itself. Additionally, same is ensured in the `esp_efuse_write_key` API as well. This always enforces the hardware k mode in the ECDSA peripheral and ensures strongest possible security. --- .../keys/with_key_purposes/esp_efuse_api_key.c | 8 +++++++- components/esp_system/startup.c | 10 ++++++++++ components/soc/esp32h2/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32h2/include/soc/soc_caps.h | 1 + 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c b/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c index da1afb7a6cc..f41b092c457 100644 --- a/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c +++ b/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c @@ -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 */ @@ -312,6 +312,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(); diff --git a/components/esp_system/startup.c b/components/esp_system/startup.c index 7c7207dad30..f78433f9928 100644 --- a/components/esp_system/startup.c +++ b/components/esp_system/startup.c @@ -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" @@ -364,6 +365,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"); diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index fef4f8e043f..a8c58f2a84d 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -1011,6 +1011,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 diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 082de55e50a..5030b94456b 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -418,6 +418,7 @@ #define SOC_EFUSE_SOFT_DIS_JTAG 1 #define SOC_EFUSE_DIS_ICACHE 1 #define SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK 1 // AES-XTS 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 From 2cd1635b862c9186702317fca8e7861d335ea7f9 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Fri, 3 Nov 2023 15:51:05 +0530 Subject: [PATCH 2/5] fix(ecdsa): remove unused k_mode from the ECDSA HAL/LL API For ESP32-H2 case, the hardware k mode is always enforced through efuse settings (done in startup code). For ESP32-P4 case, the software k mode is not supported in the peripheral itself and code was redundant. --- components/hal/ecdsa_hal.c | 7 +----- components/hal/esp32h2/include/hal/ecdsa_ll.h | 23 ------------------- components/hal/include/hal/ecdsa_hal.h | 4 +--- components/hal/include/hal/ecdsa_types.h | 8 ------- components/mbedtls/port/ecdsa/ecdsa_alt.c | 4 +--- 5 files changed, 3 insertions(+), 43 deletions(-) diff --git a/components/hal/ecdsa_hal.c b/components/hal/ecdsa_hal.c index 3d8e8696e57..53632c8f694 100644 --- a/components/hal/ecdsa_hal.c +++ b/components/hal/ecdsa_hal.c @@ -18,21 +18,16 @@ static void configure_ecdsa_periph(ecdsa_hal_config_t *conf) ecdsa_ll_set_mode(conf->mode); ecdsa_ll_set_curve(conf->curve); - 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"); } diff --git a/components/hal/esp32h2/include/hal/ecdsa_ll.h b/components/hal/esp32h2/include/hal/ecdsa_ll.h index a6931b741a7..88b657b710c 100644 --- a/components/hal/esp32h2/include/hal/ecdsa_ll.h +++ b/components/hal/esp32h2/include/hal/ecdsa_ll.h @@ -22,7 +22,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; @@ -170,26 +169,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) * @@ -315,7 +294,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; @@ -353,7 +331,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; diff --git a/components/hal/include/hal/ecdsa_hal.h b/components/hal/include/hal/ecdsa_hal.h index 02bad6092bb..ebc5e692ca7 100644 --- a/components/hal/include/hal/ecdsa_hal.h +++ b/components/hal/include/hal/ecdsa_hal.h @@ -25,7 +25,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) */ } ecdsa_hal_config_t; @@ -34,13 +33,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); /** diff --git a/components/hal/include/hal/ecdsa_types.h b/components/hal/include/hal/ecdsa_types.h index fdb2f3d3cf0..a296f665b6b 100644 --- a/components/hal/include/hal/ecdsa_types.h +++ b/components/hal/include/hal/ecdsa_types.h @@ -25,14 +25,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 */ diff --git a/components/mbedtls/port/ecdsa/ecdsa_alt.c b/components/mbedtls/port/ecdsa/ecdsa_alt.c index 617c79879fb..54bf44cbe83 100644 --- a/components/mbedtls/port/ecdsa/ecdsa_alt.c +++ b/components/mbedtls/port/ecdsa/ecdsa_alt.c @@ -139,12 +139,11 @@ 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), }; - 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(); @@ -364,7 +363,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, }; From d9abb44049372f86feb1f4cebbc78dbc229ae7b9 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Tue, 7 Nov 2023 18:25:12 +0530 Subject: [PATCH 3/5] docs: add ECDSA peripheral chapter for H2/P4 - Add ECDSA peripheral chapter and instructions to program efuse key block - Update security guide for ECDSA peripheral mention for device identity - Link with ESP-TLS guide about using ECDSA peripheral in TLS connection --- components/efuse/include/esp_efuse.h | 16 +++- docs/conf_common.py | 1 + docs/doxygen/Doxyfile | 1 + docs/en/api-reference/peripherals/ecdsa.rst | 74 +++++++++++++++++++ docs/en/api-reference/peripherals/index.rst | 1 + docs/en/api-reference/protocols/esp_tls.rst | 2 + docs/en/security/security.rst | 18 ++++- .../zh_CN/api-reference/peripherals/ecdsa.rst | 1 + .../zh_CN/api-reference/peripherals/index.rst | 1 + 9 files changed, 111 insertions(+), 4 deletions(-) create mode 100644 docs/en/api-reference/peripherals/ecdsa.rst create mode 100644 docs/zh_CN/api-reference/peripherals/ecdsa.rst diff --git a/components/efuse/include/esp_efuse.h b/components/efuse/include/esp_efuse.h index 80db72a608b..fa075f91ace 100644 --- a/components/efuse/include/esp_efuse.h +++ b/components/efuse/include/esp_efuse.h @@ -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). diff --git a/docs/conf_common.py b/docs/conf_common.py index ad9484cd090..51adfad4be2 100644 --- a/docs/conf_common.py +++ b/docs/conf_common.py @@ -196,6 +196,7 @@ 'SOC_ULP_FSM_SUPPORTED':ULP_FSM_DOCS, 'SOC_RISCV_COPROC_SUPPORTED':RISCV_COPROC_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, diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 4f70bd75d2c..8f31558ee4c 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -238,6 +238,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 \ diff --git a/docs/en/api-reference/peripherals/ecdsa.rst b/docs/en/api-reference/peripherals/ecdsa.rst new file mode 100644 index 00000000000..1210694d9d5 --- /dev/null +++ b/docs/en/api-reference/peripherals/ecdsa.rst @@ -0,0 +1,74 @@ +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 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 + } + +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 curvers 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 diff --git a/docs/en/api-reference/peripherals/index.rst b/docs/en/api-reference/peripherals/index.rst index 922de1e92c3..85bfeee0cd2 100644 --- a/docs/en/api-reference/peripherals/index.rst +++ b/docs/en/api-reference/peripherals/index.rst @@ -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 diff --git a/docs/en/api-reference/protocols/esp_tls.rst b/docs/en/api-reference/protocols/esp_tls.rst index b0302aafd92..f1448ff979e 100644 --- a/docs/en/api-reference/protocols/esp_tls.rst +++ b/docs/en/api-reference/protocols/esp_tls.rst @@ -194,6 +194,8 @@ SSL/TLS libraries and with all respective configurations set to default. .. only:: SOC_ECDSA_SUPPORTED + .. _ecdsa-peri-with-esp-tls: + ECDSA Peripheral with ESP-TLS ----------------------------- diff --git a/docs/en/security/security.rst b/docs/en/security/security.rst index a6f6992a962..67451434b47 100644 --- a/docs/en/security/security.rst +++ b/docs/en/security/security.rst @@ -1,6 +1,10 @@ Security ======== +{IDF_TARGET_CIPHER_SCHEME:default="RSA", esp32h2="RSA or ECDSA"} + +{IDF_TARGET_SIG_PERI:default="DS", esp32h2="DS or ECDSA"} + This guide provides an overview of the overall security features available in Espressif solutions. It is highly recommended to consider this guide while designing the products with Espressif platform and ESP-IDF software stack from the **"security"** perspective. Goals @@ -71,9 +75,19 @@ Flash Encryption Best Practices Digital Signature Peripheral in {IDF_TARGET_NAME} produces hardware accelerated RSA digital signatures (with 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 RSA cipher scheme. + .. only:: SOC_ECDSA_SUPPORTED + + {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:`DS Peripheral Guide <../api-reference/peripherals/ds>` for detailed documentation. + 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 diff --git a/docs/zh_CN/api-reference/peripherals/ecdsa.rst b/docs/zh_CN/api-reference/peripherals/ecdsa.rst new file mode 100644 index 00000000000..5a65a8a8bff --- /dev/null +++ b/docs/zh_CN/api-reference/peripherals/ecdsa.rst @@ -0,0 +1 @@ +.. include:: ../../../en/api-reference/peripherals/ecdsa.rst diff --git a/docs/zh_CN/api-reference/peripherals/index.rst b/docs/zh_CN/api-reference/peripherals/index.rst index 916e504a9f7..3efe27f78fc 100644 --- a/docs/zh_CN/api-reference/peripherals/index.rst +++ b/docs/zh_CN/api-reference/peripherals/index.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 From bb1376ff5d9d37cf3b1a3a5e1f0cb4e9644b596e Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Wed, 8 Nov 2023 13:45:43 +0530 Subject: [PATCH 4/5] fix(api-docs): include in the ECDSA APIs for doxygen build --- components/mbedtls/port/include/ecdsa/ecdsa_alt.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/components/mbedtls/port/include/ecdsa/ecdsa_alt.h b/components/mbedtls/port/include/ecdsa/ecdsa_alt.h index 0326795f8d7..f4b7af6a03c 100644 --- a/components/mbedtls/port/include/ecdsa/ecdsa_alt.h +++ b/components/mbedtls/port/include/ecdsa/ecdsa_alt.h @@ -14,7 +14,7 @@ extern "C" { #endif -#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN +#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN || __DOXYGEN__ /** * @brief Initialize MPI to notify mbedtls_ecdsa_sign to use the private key in efuse @@ -46,7 +46,8 @@ int esp_ecdsa_privkey_load_mpi(mbedtls_mpi *key, int efuse_blk); * - -1 otherwise */ int esp_ecdsa_privkey_load_pk_context(mbedtls_pk_context *key_ctx, int efuse_blk); -#endif + +#endif // CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN || __DOXYGEN__ #ifdef __cplusplus } From 78453c891861faa5f2a4bc8a3195642f429199bd Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Fri, 10 Nov 2023 14:38:44 +0530 Subject: [PATCH 5/5] docs(ecdsa): add a note about TRNG dependency for ECDSA peripheral --- docs/en/api-reference/peripherals/ecdsa.rst | 10 +++++++++- docs/en/api-reference/system/random.rst | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/en/api-reference/peripherals/ecdsa.rst b/docs/en/api-reference/peripherals/ecdsa.rst index 1210694d9d5..d6e19cf5bcc 100644 --- a/docs/en/api-reference/peripherals/ecdsa.rst +++ b/docs/en/api-reference/peripherals/ecdsa.rst @@ -59,12 +59,20 @@ Following code snippet uses :cpp:func:`esp_efuse_write_key` to set physical key // 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 `_ 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 curvers or hash algorithms and hence for cases where the requirements do not meet the hardware, implementation falls back to the software. +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. diff --git a/docs/en/api-reference/system/random.rst b/docs/en/api-reference/system/random.rst index da4cb1e3216..cfe6566f966 100644 --- a/docs/en/api-reference/system/random.rst +++ b/docs/en/api-reference/system/random.rst @@ -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, "}