椭圆曲线数字签名算法 (ECDSA)
椭圆曲线数字签名算法 (ECDSA) 是数字签名算法 (DSA) 基于椭圆曲线密码学的变体。
ESP32-P4 的 ECDSA 外设为计算 ECDSA 签名提供了一个安全高效的环境,不仅能确保签名过程的机密性,防止信息泄露,也提供了快速的计算。在签名过程中使用的 ECDSA 私钥只能由硬件外设访问,软件无法读取。
ECDSA 外设可以为 TLS 双向身份验证等用例建立 安全设备身份认证。
支持的特性
ECDSA 数字签名生成和验证
三种不同的椭圆曲线,P-192,P-256 和 P-384(FIPS 186-3 规范)
ECDSA 操作中用于散列消息的三种哈希算法,SHA-224, SHA-256 和 SHA-384(FIPS PUB 180-4 规范)
ESP32-P4 上的 ECDSA
在 ESP32-P4 上,ECDSA 模块使用烧录到 eFuse 块中的密钥。密码模块外的任何资源都不可访问此密钥(默认模式),从而避免密钥泄露。
ECDSA 密钥存储
ECDSA 私钥存储在 eFuse 密钥块中。所需的密钥块数量取决于曲线大小:
P-256 曲线:需要一个 eFuse 密钥块(256 位)
P-384 曲线:需要两个 eFuse 密钥块(总共 512 位)
对于需要两个密钥块的曲线(如 P-384),配置以下字段:
将
esp_tls_cfg_t::ecdsa_key_efuse_blk设置为低块号将
esp_tls_cfg_t::ecdsa_key_efuse_blk_high设置为高块号
对于单块曲线(如 P-256),只需设置 esp_tls_cfg_t::ecdsa_key_efuse_blk,将 esp_tls_cfg_t::ecdsa_key_efuse_blk_high 保持为 0 或不赋值。
ECDSA 密钥可以通过 idf.py 脚本在外部编程。以下是关于编程 ECDSA 密钥的示例:
idf.py efuse-burn-key <BLOCK_NUM> </path/to/ecdsa_private_key.pem> ECDSA_KEY
备注
六个物理 eFuse 块可作为 ECDSA 模块的密钥:块 4 ~ 块 9。例如,对于块 4(第一个密钥块),参数为 BLOCK_KEY0。
另外,ECDSA 密钥也可以通过在目标上运行的应用程序进行编程。
以下代码片段使用 esp_efuse_write_key() 将 eFuse 中的物理密钥块 0 的密钥目的设置为 esp_efuse_purpose_t::ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY:
#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
}
生成确定性签名
ESP32-P4 的 ECDSA 外设还支持使用确定性推导参数 K 来生成确定性签名,详见 RFC 6979 第 3.2 节。
生成非确定性签名
对 TRNG 的依赖
ECDSA 外设依靠硬件真随机数生成器 (TRNG) 来满足其内部熵要求,从而生成非确定性签名。在创建 ECDSA 签名时,算法需要生成一个随机整数,在 RFC 6090 第 5.3.2 节有说明。
在应用程序中启动 ECDSA 计算(主要是签名)之前,请确保硬件 RNG 已经启用。
应用程序概述
有关如何使用 ECDSA 外设建立 TLS 双向身份验证连接的详细信息,请参阅 在 ESP-TLS 中使用 ECDSA 外设 指南。
通过覆盖 ECDSA 签名以及验证 API,可以集成 Mbed TLS 堆栈中的 ECDSA 外设。请注意,ECDSA 外设并不支持所有曲线或哈希算法。因此,在不满足硬件要求时,实现会退回到软件。
对于特定的 TLS 上下文,可用额外的 API 来填充某些字段(例如私钥 ctx),以区分路由到硬件的路径。ESP-TLS 层在内部集成了这些 API,因此在应用程序层不需要额外的操作。对于自定义用例,请参阅以下 API 详细信息。
API 参考
Header File
components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_ecdsa_contexts.h
This header file can be included with:
#include "psa_crypto_driver_esp_ecdsa_contexts.h"
This header file is a part of the API provided by the
mbedtlscomponent. To declare that your component depends onmbedtls, add the following to your CMakeLists.txt:REQUIRES mbedtls
or
PRIV_REQUIRES mbedtls
Structures
-
struct esp_ecdsa_opaque_key_t
Structure to store opaque key metadata.
Public Members
-
esp_ecdsa_curve_t curve
ECDSA curve
-
bool use_km_key
Use key deployed in the key manager
-
uint8_t efuse_block
eFuse block id for ECDSA private key
-
esp_ecdsa_curve_t curve
Macros
-
MAX_ECDSA_COMPONENT_LEN
-
MAX_ECDSA_SHA_LEN
-
ECDSA_SHA_LEN
-
ECDSA_SHA_LEN_P384