feat(mbedtls): Introduce ESP-HMAC PSA opaque driver

This commit is contained in:
harshal.patil
2026-01-27 08:18:59 +05:30
parent 53072bfa9d
commit ae459b5204
15 changed files with 729 additions and 141 deletions

View File

@@ -232,7 +232,6 @@ INPUT = \
$(PROJECT_PATH)/components/esp_ringbuf/include/freertos/ringbuf.h \
$(PROJECT_PATH)/components/esp_rom/include/esp_rom_sys.h \
$(PROJECT_PATH)/components/esp_security/include/esp_ds.h \
$(PROJECT_PATH)/components/esp_security/include/esp_hmac.h \
$(PROJECT_PATH)/components/esp_system/include/esp_expression_with_stack.h \
$(PROJECT_PATH)/components/esp_system/include/esp_freertos_hooks.h \
$(PROJECT_PATH)/components/esp_system/include/esp_ipc_isr.h \
@@ -297,6 +296,7 @@ INPUT = \
$(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/psa_driver/include/psa_crypto_driver_esp_ecdsa_contexts.h \
$(PROJECT_PATH)/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque_contexts.h \
$(PROJECT_PATH)/components/nvs_flash/include/nvs_flash.h \
$(PROJECT_PATH)/components/nvs_flash/include/nvs.h \
$(PROJECT_PATH)/components/nvs_flash/include/nvs_bootloader.h \

View File

@@ -71,7 +71,7 @@ Key purpose value: 8
In this case, the HMAC is given out to the software, e.g., to authenticate a message.
The API to calculate the HMAC is :cpp:func:`esp_hmac_calculate`. The input arguments for the function are the message, message length, and the eFuse key block ID which contains the secret and has the efuse key purpose set to Upstream mode.
The API to calculate the HMAC is :cpp:func:`psa_mac_compute` with an opaque PSA key with the eFuse key block ID which contains the secret and has the efuse key purpose set to Upstream mode.
HMAC for Digital Signature
^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -160,20 +160,53 @@ We use ``esp_efuse_write_key`` to set physical key block 4 in the eFuse for the
// writing key failed, maybe written already
}
Now we can use the saved key to calculate an HMAC for software usage.
Now we can use the saved key to calculate an HMAC for software usage using the PSA Crypto API.
.. code-block:: c
#include "esp_hmac.h"
#include "psa/crypto.h"
#include "psa_crypto_driver_esp_hmac_opaque.h"
uint8_t hmac[32];
size_t hmac_length = 0;
const char *message = "Hello, HMAC!";
const size_t msg_len = 12;
esp_err_t result = esp_hmac_calculate(HMAC_KEY4, message, msg_len, hmac);
// Setup key attributes for ESP-HMAC opaque driver
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(PSA_ALG_SHA_256));
psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
psa_set_key_bits(&attributes, 256);
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_HMAC_VOLATILE);
if (result == ESP_OK) {
// Create opaque key reference
esp_hmac_opaque_key_t opaque_key = {
.use_km_key = false,
.efuse_block = EFUSE_BLK_KEY4,
};
// Import the opaque key
psa_key_id_t key_id = 0;
psa_status_t status = psa_import_key(&attributes, (uint8_t *)&opaque_key,
sizeof(opaque_key), &key_id);
if (status != PSA_SUCCESS) {
// Failed to import key
psa_reset_key_attributes(&attributes);
return;
}
// Compute HMAC
status = psa_mac_compute(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256),
(uint8_t *)message, msg_len,
hmac, sizeof(hmac), &hmac_length);
// Clean up
psa_destroy_key(key_id);
psa_reset_key_attributes(&attributes);
if (status == PSA_SUCCESS) {
// HMAC written to hmac now
} else {
// failure calculating HMAC
@@ -182,4 +215,4 @@ Now we can use the saved key to calculate an HMAC for software usage.
API Reference
-------------
.. include-build-file:: inc/esp_hmac.inc
.. include-build-file:: inc/psa_crypto_driver_esp_hmac_opaque_contexts.inc

View File

@@ -71,7 +71,7 @@ HMAC 支持软件使用
在此情况下HMAC 支持软件使用,如验证消息真实性等。
API :cpp:func:`esp_hmac_calculate` 用于计算 HMAC。输入参数包括消息、消息长度以及包含密钥的 eFuse 密钥块 ID且该密钥块的 eFuse 密钥功能设置为上行模式。
API :cpp:func:`psa_mac_compute` 用于计算 HMAC。输入参数包括消息、消息长度以及包含密钥的 eFuse 密钥块 ID且该密钥块的 eFuse 密钥功能设置为上行模式。
HMAC 用作数字签名 (DS) 的密钥
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -164,16 +164,49 @@ HMAC 的第三种应用场景是将其作为密钥,启用软禁用的 JTAG 接
.. code-block:: c
#include "esp_hmac.h"
#include "psa/crypto.h"
#include "psa_crypto_driver_esp_hmac_opaque.h"
uint8_t hmac[32];
size_t hmac_length = 0;
const char *message = "Hello, HMAC!";
const size_t msg_len = 12;
esp_err_t result = esp_hmac_calculate(HMAC_KEY4, message, msg_len, hmac);
// 为 ESP-HMAC 不透明驱动设置密钥属性
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(PSA_ALG_SHA_256));
psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
psa_set_key_bits(&attributes, 256);
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_HMAC_VOLATILE);
if (result == ESP_OK) {
// 创建不透明密钥引用
esp_hmac_opaque_key_t opaque_key = {
.use_km_key = false,
.efuse_block = EFUSE_BLK_KEY4,
};
// 导入不透明密钥
psa_key_id_t key_id = 0;
psa_status_t status = psa_import_key(&attributes, (uint8_t *)&opaque_key,
sizeof(opaque_key), &key_id);
if (status != PSA_SUCCESS) {
// 导入密钥失败
psa_reset_key_attributes(&attributes);
return;
}
// 计算 HMAC
status = psa_mac_compute(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256),
(uint8_t *)message, msg_len,
hmac, sizeof(hmac), &hmac_length);
// 清理
psa_destroy_key(key_id);
psa_reset_key_attributes(&attributes);
if (status == PSA_SUCCESS) {
// HMAC 已写入 hmac 数组
} else {
// 计算 HMAC 失败
@@ -182,4 +215,4 @@ HMAC 的第三种应用场景是将其作为密钥,启用软禁用的 JTAG 接
API 参考
-------------
.. include-build-file:: inc/esp_hmac.inc
.. include-build-file:: inc/psa_crypto_driver_esp_hmac_opaque_contexts.inc