mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
feat(mbedtls): Introduce ESP-HMAC PSA opaque driver
This commit is contained in:
@@ -353,12 +353,13 @@ endif()
|
||||
if(CONFIG_SOC_SHA_SUPPORTED)
|
||||
if(CONFIG_MBEDTLS_HARDWARE_SHA)
|
||||
target_compile_definitions(tfpsacrypto PRIVATE ESP_SHA_DRIVER_ENABLED)
|
||||
target_compile_definitions(tfpsacrypto PRIVATE ESP_HMAC_TRANSPARENT_DRIVER_ENABLED)
|
||||
target_sources(tfpsacrypto PRIVATE
|
||||
"${COMPONENT_DIR}/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c"
|
||||
"${COMPONENT_DIR}/port/psa_driver/esp_sha/${SHA_PERIPHERAL_TYPE}/psa_crypto_driver_esp_sha256.c"
|
||||
"${COMPONENT_DIR}/port/psa_driver/esp_sha/${SHA_PERIPHERAL_TYPE}/psa_crypto_driver_esp_sha512.c"
|
||||
"${COMPONENT_DIR}/port/sha/esp_sha.c"
|
||||
"${COMPONENT_DIR}/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac.c"
|
||||
"${COMPONENT_DIR}/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c"
|
||||
)
|
||||
endif()
|
||||
target_sources(tfpsacrypto PRIVATE
|
||||
@@ -374,6 +375,14 @@ if(CONFIG_MBEDTLS_ROM_MD5)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_HMAC_SUPPORTED)
|
||||
target_compile_definitions(tfpsacrypto PRIVATE ESP_HMAC_OPAQUE_DRIVER_ENABLED)
|
||||
target_sources(tfpsacrypto PRIVATE
|
||||
"${COMPONENT_DIR}/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c"
|
||||
)
|
||||
target_link_libraries(tfpsacrypto PRIVATE idf::efuse)
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_DIG_SIGN_SUPPORTED)
|
||||
target_sources(tfpsacrypto PRIVATE
|
||||
"${COMPONENT_DIR}/port/esp_ds/esp_rsa_sign_alt.c"
|
||||
|
||||
@@ -97,6 +97,7 @@ endif()
|
||||
# SHA implementation
|
||||
if(CONFIG_SOC_SHA_SUPPORTED)
|
||||
target_compile_definitions(tfpsacrypto PRIVATE ESP_SHA_DRIVER_ENABLED)
|
||||
target_compile_definitions(tfpsacrypto PRIVATE ESP_HMAC_TRANSPARENT_DRIVER_ENABLED)
|
||||
target_sources(tfpsacrypto PRIVATE
|
||||
"${COMPONENT_DIR}/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c"
|
||||
"${COMPONENT_DIR}/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha1.c"
|
||||
@@ -104,7 +105,7 @@ if(CONFIG_SOC_SHA_SUPPORTED)
|
||||
"${COMPONENT_DIR}/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha512.c"
|
||||
"${COMPONENT_DIR}/port/sha/core/sha.c"
|
||||
"${COMPONENT_DIR}/port/sha/esp_sha.c"
|
||||
"${COMPONENT_DIR}/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac.c"
|
||||
"${COMPONENT_DIR}/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
Submodule components/mbedtls/mbedtls updated: 5baeb30f6f...582ff48203
@@ -194,6 +194,8 @@
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_SHA_1
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_SHA_224
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_SHA_256
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_HMAC
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC
|
||||
#if SOC_SHA_SUPPORT_SHA512
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_SHA_384
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_SHA_512
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_driver_esp_hmac_opaque.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_chip.h"
|
||||
#include "hal/hmac_types.h"
|
||||
#include "esp_hmac.h"
|
||||
|
||||
static bool validate_hmac_opaque_key_attributes(const esp_hmac_opaque_key_t *opaque_key)
|
||||
{
|
||||
// efuse_block is uint8_t, so it's always >= 0 (EFUSE_BLK0)
|
||||
if (opaque_key->efuse_block < EFUSE_BLK_MAX && esp_efuse_get_key_purpose(opaque_key->efuse_block) == ESP_EFUSE_KEY_PURPOSE_HMAC_UP) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
psa_status_t esp_hmac_import_key_opaque(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *data,
|
||||
size_t data_length,
|
||||
uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
size_t *key_buffer_length,
|
||||
size_t *bits)
|
||||
{
|
||||
if (!attributes || !data || !key_buffer || !key_buffer_length || !bits) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (key_buffer_size < sizeof(esp_hmac_opaque_key_t) || data_length < sizeof(esp_hmac_opaque_key_t)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
const esp_hmac_opaque_key_t *opaque_key = (const esp_hmac_opaque_key_t *) data;
|
||||
bool valid = validate_hmac_opaque_key_attributes(opaque_key);
|
||||
if (!valid) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
memcpy(key_buffer, opaque_key, sizeof(esp_hmac_opaque_key_t));
|
||||
*key_buffer_length = sizeof(esp_hmac_opaque_key_t);
|
||||
*bits = psa_get_key_bits(attributes);
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t esp_hmac_abort_opaque(esp_hmac_opaque_operation_t *esp_hmac_ctx)
|
||||
{
|
||||
if (!esp_hmac_ctx) {
|
||||
mbedtls_platform_zeroize(esp_hmac_ctx, sizeof(esp_hmac_opaque_operation_t));
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t esp_hmac_setup_opaque(
|
||||
esp_hmac_opaque_operation_t *esp_hmac_ctx,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
if (!esp_hmac_ctx || !attributes || !key_buffer || !key_buffer_size || !alg) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (key_buffer_size < sizeof(esp_hmac_opaque_key_t)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (!PSA_ALG_IS_HMAC(alg)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
psa_algorithm_t hash_alg = PSA_ALG_GET_HASH(alg);
|
||||
|
||||
if (hash_alg != PSA_ALG_SHA_256) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
memset(esp_hmac_ctx, 0, sizeof(esp_hmac_opaque_operation_t));
|
||||
|
||||
const esp_hmac_opaque_key_t *opaque_key = (const esp_hmac_opaque_key_t *) key_buffer;
|
||||
|
||||
if (!validate_hmac_opaque_key_attributes(opaque_key)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
esp_hmac_ctx->opaque_key = opaque_key;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
static hmac_key_id_t translate_efuse_block_to_hmac_key_id(uint8_t efuse_block)
|
||||
{
|
||||
return (hmac_key_id_t) (efuse_block - EFUSE_BLK_KEY0);
|
||||
}
|
||||
|
||||
psa_status_t esp_hmac_update_opaque(esp_hmac_opaque_operation_t *esp_hmac_ctx, const uint8_t *data, size_t data_length)
|
||||
{
|
||||
if (!esp_hmac_ctx || !data || data_length == 0) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
hmac_key_id_t hmac_key_id = HMAC_KEY_MAX;
|
||||
|
||||
#if SOC_KEY_MANAGER_HMAC_KEY_DEPLOY
|
||||
if (esp_hmac_ctx->opaque_key->use_km_key) {
|
||||
hmac_key_id = HMAC_KEY_KM;
|
||||
} else
|
||||
#endif /* SOC_KEY_MANAGER_HMAC_KEY_DEPLOY */
|
||||
{
|
||||
hmac_key_id = translate_efuse_block_to_hmac_key_id(esp_hmac_ctx->opaque_key->efuse_block);
|
||||
}
|
||||
|
||||
esp_err_t hmac_ret = esp_hmac_calculate(hmac_key_id, data, data_length, esp_hmac_ctx->hmac);
|
||||
if (hmac_ret == ESP_ERR_INVALID_ARG) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
} else if (hmac_ret == ESP_FAIL) {
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
} else if (hmac_ret == ESP_OK) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
}
|
||||
|
||||
psa_status_t esp_hmac_finish_opaque(
|
||||
esp_hmac_opaque_operation_t *esp_hmac_ctx,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length)
|
||||
{
|
||||
if (!esp_hmac_ctx || !mac || !mac_length) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (mac_size < ESP_HMAC_RESULT_SIZE) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
memcpy(mac, esp_hmac_ctx->hmac, ESP_HMAC_RESULT_SIZE);
|
||||
*mac_length = ESP_HMAC_RESULT_SIZE;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t esp_hmac_compute_opaque(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length)
|
||||
{
|
||||
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
esp_hmac_opaque_operation_t esp_hmac_ctx = {0};
|
||||
|
||||
status = esp_hmac_setup_opaque(&esp_hmac_ctx, attributes, key_buffer, key_buffer_size, alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = esp_hmac_update_opaque(&esp_hmac_ctx, input, input_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = esp_hmac_finish_opaque(&esp_hmac_ctx, mac, mac_size, mac_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t esp_hmac_verify_finish_opaque(
|
||||
esp_hmac_opaque_operation_t *esp_hmac_ctx,
|
||||
const uint8_t *mac,
|
||||
size_t mac_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
uint8_t actual_mac[ESP_HMAC_RESULT_SIZE];
|
||||
size_t actual_mac_length = 0;
|
||||
|
||||
status = esp_hmac_finish_opaque(esp_hmac_ctx, actual_mac, sizeof(actual_mac), &actual_mac_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (memcmp(mac, actual_mac, mac_length) != 0) {
|
||||
return PSA_ERROR_INVALID_SIGNATURE;
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the size of the ESP HMAC opaque key
|
||||
*
|
||||
* @param key_type Key type
|
||||
* @param key_bits Key bits
|
||||
* @return size_t Size of the ESP HMAC opaque key
|
||||
*/
|
||||
size_t esp_hmac_opaque_size_function(
|
||||
psa_key_type_t key_type,
|
||||
size_t key_bits)
|
||||
{
|
||||
(void)key_type;
|
||||
(void)key_bits;
|
||||
|
||||
// Opaque keys always use the same size structure
|
||||
return sizeof(esp_hmac_opaque_key_t);
|
||||
}
|
||||
+50
-36
@@ -6,11 +6,10 @@
|
||||
|
||||
#include <string.h>
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_driver_esp_hmac.h"
|
||||
#include "psa_crypto_driver_esp_hmac_contexts.h"
|
||||
#include "psa_crypto_driver_esp_hmac_transparent.h"
|
||||
#include "psa_crypto_driver_esp_sha.h"
|
||||
|
||||
|
||||
psa_status_t esp_hmac_abort(esp_hmac_operation_t *esp_hmac_ctx)
|
||||
psa_status_t esp_hmac_abort_transparent(esp_hmac_transparent_operation_t *esp_hmac_ctx)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
@@ -19,11 +18,11 @@ psa_status_t esp_hmac_abort(esp_hmac_operation_t *esp_hmac_ctx)
|
||||
return status;
|
||||
}
|
||||
|
||||
mbedtls_platform_zeroize(esp_hmac_ctx, sizeof(esp_hmac_operation_t));
|
||||
mbedtls_platform_zeroize(esp_hmac_ctx, sizeof(esp_hmac_transparent_operation_t));
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t esp_hmac_setup(esp_hmac_operation_t *esp_hmac_ctx,
|
||||
psa_status_t esp_hmac_setup_transparent(esp_hmac_transparent_operation_t *esp_hmac_ctx,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
@@ -40,7 +39,12 @@ psa_status_t esp_hmac_setup(esp_hmac_operation_t *esp_hmac_ctx,
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
memset(esp_hmac_ctx, 0, sizeof(esp_hmac_operation_t));
|
||||
memset(esp_hmac_ctx, 0, sizeof(esp_hmac_transparent_operation_t));
|
||||
|
||||
status = esp_sha_hash_setup(&esp_hmac_ctx->esp_sha_ctx, hash_alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Sanity checks on block_size, to guarantee that there won't be a buffer
|
||||
* overflow below. This should never trigger if the hash algorithm
|
||||
@@ -48,19 +52,21 @@ psa_status_t esp_hmac_setup(esp_hmac_operation_t *esp_hmac_ctx,
|
||||
/* The size check against the ipad buffer also covers opad since both
|
||||
* have the same size (PSA_HMAC_MAX_HASH_BLOCK_SIZE). */
|
||||
if ((block_size > sizeof(ipad)) || (block_size < hash_size)) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (key_buffer_size > block_size) {
|
||||
status = esp_sha_hash_compute(hash_alg, key_buffer, key_buffer_size,
|
||||
ipad, sizeof(ipad), &key_buffer_size);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
goto error;
|
||||
}
|
||||
/* After hashing, key_buffer_size is set to the hash size, which
|
||||
* should be <= block_size. Verify this for static analysis. */
|
||||
if (key_buffer_size > block_size) {
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
/* A 0-length key is not commonly used in HMAC when used as a MAC,
|
||||
@@ -70,7 +76,8 @@ psa_status_t esp_hmac_setup(esp_hmac_operation_t *esp_hmac_ctx,
|
||||
else if (key_buffer_size != 0) {
|
||||
/* Additional safety check: ensure key fits in ipad buffer */
|
||||
if (key_buffer_size > sizeof(ipad)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
goto error;
|
||||
}
|
||||
memcpy(ipad, key_buffer, key_buffer_size);
|
||||
}
|
||||
@@ -110,28 +117,29 @@ psa_status_t esp_hmac_setup(esp_hmac_operation_t *esp_hmac_ctx,
|
||||
memset(esp_hmac_ctx->opad + key_buffer_size, 0x5C, fill_size);
|
||||
}
|
||||
|
||||
status = esp_sha_hash_setup(&esp_hmac_ctx->esp_sha_ctx, hash_alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, ipad, block_size);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
goto error;
|
||||
}
|
||||
|
||||
esp_hmac_ctx->alg = alg;
|
||||
return status;
|
||||
|
||||
error:
|
||||
esp_hmac_abort_transparent(esp_hmac_ctx);
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t esp_hmac_update(esp_hmac_operation_t *esp_hmac_ctx, const uint8_t *data, size_t data_length)
|
||||
psa_status_t esp_hmac_update_transparent(esp_hmac_transparent_operation_t *esp_hmac_ctx, const uint8_t *data, size_t data_length)
|
||||
{
|
||||
if (esp_hmac_ctx == NULL || data == NULL) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
return esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, data, data_length);
|
||||
}
|
||||
|
||||
psa_status_t esp_hmac_finish(
|
||||
esp_hmac_operation_t *esp_hmac_ctx,
|
||||
psa_status_t esp_hmac_finish_transparent(
|
||||
esp_hmac_transparent_operation_t *esp_hmac_ctx,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length)
|
||||
@@ -143,6 +151,10 @@ psa_status_t esp_hmac_finish(
|
||||
size_t hash_size = 0;
|
||||
size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
|
||||
|
||||
if (esp_hmac_ctx == NULL || mac == NULL || mac_length == NULL) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
status = esp_sha_hash_finish(&esp_hmac_ctx->esp_sha_ctx, tmp, sizeof(tmp), &hash_size);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
@@ -169,16 +181,19 @@ psa_status_t esp_hmac_finish(
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memcpy(mac, tmp, mac_size);
|
||||
|
||||
*mac_length = mac_size;
|
||||
if (mac_size < hash_size) {
|
||||
status = PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
goto exit;
|
||||
}
|
||||
memcpy(mac, tmp, hash_size);
|
||||
*mac_length = hash_size;
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize(tmp, hash_size);
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t esp_hmac_compute(
|
||||
psa_status_t esp_hmac_compute_transparent(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
@@ -190,9 +205,9 @@ psa_status_t esp_hmac_compute(
|
||||
size_t *mac_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
esp_hmac_operation_t esp_hmac_ctx = {0};
|
||||
esp_hmac_transparent_operation_t esp_hmac_ctx = {0};
|
||||
|
||||
status = esp_hmac_setup(&esp_hmac_ctx,
|
||||
status = esp_hmac_setup_transparent(&esp_hmac_ctx,
|
||||
attributes, key_buffer, key_buffer_size,
|
||||
alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
@@ -200,27 +215,27 @@ psa_status_t esp_hmac_compute(
|
||||
}
|
||||
|
||||
if (input_length > 0) {
|
||||
status = esp_hmac_update(&esp_hmac_ctx, input, input_length);
|
||||
status = esp_hmac_update_transparent(&esp_hmac_ctx, input, input_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
size_t actual_mac_length = 0;
|
||||
status = esp_hmac_finish(&esp_hmac_ctx, mac, mac_size, &actual_mac_length);
|
||||
status = esp_hmac_finish_transparent(&esp_hmac_ctx, mac, mac_size, &actual_mac_length);
|
||||
if (status == PSA_SUCCESS) {
|
||||
*mac_length = actual_mac_length;
|
||||
}
|
||||
|
||||
exit:
|
||||
esp_hmac_abort(&esp_hmac_ctx);
|
||||
esp_hmac_abort_transparent(&esp_hmac_ctx);
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
psa_status_t esp_hmac_verify_finish(
|
||||
esp_hmac_operation_t *esp_hmac_ctx,
|
||||
psa_status_t esp_hmac_verify_finish_transparent(
|
||||
esp_hmac_transparent_operation_t *esp_hmac_ctx,
|
||||
const uint8_t *mac,
|
||||
size_t mac_length)
|
||||
{
|
||||
@@ -237,14 +252,13 @@ psa_status_t esp_hmac_verify_finish(
|
||||
|
||||
size_t actual_mac_length = 0;
|
||||
|
||||
status = esp_hmac_finish(esp_hmac_ctx, actual_mac, sizeof(actual_mac), &actual_mac_length);
|
||||
status = esp_hmac_finish_transparent(esp_hmac_ctx, actual_mac, sizeof(actual_mac), &actual_mac_length);
|
||||
if (status == PSA_SUCCESS) {
|
||||
if (memcmp(actual_mac, mac, mac_length) == 0) {
|
||||
return PSA_SUCCESS;
|
||||
} else {
|
||||
return PSA_ERROR_INVALID_SIGNATURE;
|
||||
if (memcmp(actual_mac, mac, mac_length) != 0) {
|
||||
status = PSA_ERROR_INVALID_SIGNATURE;
|
||||
}
|
||||
}
|
||||
|
||||
mbedtls_platform_zeroize(actual_mac, sizeof(actual_mac));
|
||||
return status;
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(ESP_SHA_DRIVER_ENABLED)
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_driver_esp_hmac_contexts.h"
|
||||
|
||||
psa_status_t esp_hmac_compute(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length);
|
||||
|
||||
psa_status_t esp_hmac_abort(esp_hmac_operation_t *esp_hmac_ctx);
|
||||
|
||||
psa_status_t esp_hmac_setup(esp_hmac_operation_t *esp_hmac_ctx,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg);
|
||||
|
||||
psa_status_t esp_hmac_update(esp_hmac_operation_t *esp_hmac_ctx,
|
||||
const uint8_t *data,
|
||||
size_t data_length);
|
||||
|
||||
psa_status_t esp_hmac_finish(esp_hmac_operation_t *esp_hmac_ctx,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length);
|
||||
|
||||
psa_status_t esp_hmac_verify_finish(esp_hmac_operation_t *esp_hmac_ctx,
|
||||
const uint8_t *mac,
|
||||
size_t mac_length);
|
||||
|
||||
#endif /* ESP_SHA_DRIVER_ENABLED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if defined(ESP_HMAC_OPAQUE_DRIVER_ENABLED)
|
||||
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_driver_esp_hmac_opaque_contexts.h"
|
||||
|
||||
/**
|
||||
* @brief ESP HMAC opaque PSA driver location
|
||||
*
|
||||
* Vendor-specific location for ESP hardware HMAC keys.
|
||||
* Bits 8-31 are location, using vendor flag (0x800000) + ESP vendor ID.
|
||||
*/
|
||||
#define PSA_KEY_LOCATION_ESP_HMAC ((psa_key_location_t) 0x800002)
|
||||
|
||||
/**
|
||||
* @brief Construct a lifetime for ESP HMAC keys with default persistence
|
||||
*/
|
||||
#define PSA_KEY_LIFETIME_ESP_HMAC \
|
||||
PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( \
|
||||
PSA_KEY_PERSISTENCE_DEFAULT, \
|
||||
PSA_KEY_LOCATION_ESP_HMAC)
|
||||
|
||||
/**
|
||||
* @brief Construct a volatile lifetime for ESP HMAC keys
|
||||
*/
|
||||
#define PSA_KEY_LIFETIME_ESP_HMAC_VOLATILE \
|
||||
PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( \
|
||||
PSA_KEY_PERSISTENCE_VOLATILE, \
|
||||
PSA_KEY_LOCATION_ESP_HMAC)
|
||||
|
||||
/**
|
||||
* @brief Import an ESP HMAC key reference (not actual key material)
|
||||
*
|
||||
* This function imports an opaque reference to a key stored in eFuse or Key Manager.
|
||||
* The import data should contain the esp_hmac_opaque_key_t structure.
|
||||
*
|
||||
* @param attributes Key attributes
|
||||
* @param data Import data (esp_hmac_opaque_key_t)
|
||||
* @param data_length Length of import data
|
||||
* @param key_buffer Output buffer for opaque key
|
||||
* @param key_buffer_size Size of output buffer
|
||||
* @param key_buffer_length Actual key buffer length
|
||||
* @param bits Key size in bits
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t esp_hmac_import_key_opaque(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *data,
|
||||
size_t data_length,
|
||||
uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
size_t *key_buffer_length,
|
||||
size_t *bits);
|
||||
|
||||
size_t esp_hmac_opaque_size_function(psa_key_type_t key_type, size_t key_bits);
|
||||
|
||||
psa_status_t esp_hmac_compute_opaque(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length);
|
||||
|
||||
psa_status_t esp_hmac_abort_opaque(esp_hmac_opaque_operation_t *esp_hmac_ctx);
|
||||
|
||||
psa_status_t esp_hmac_setup_opaque(esp_hmac_opaque_operation_t *esp_hmac_ctx,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg);
|
||||
|
||||
psa_status_t esp_hmac_update_opaque(esp_hmac_opaque_operation_t *esp_hmac_ctx,
|
||||
const uint8_t *data,
|
||||
size_t data_length);
|
||||
|
||||
psa_status_t esp_hmac_finish_opaque(esp_hmac_opaque_operation_t *esp_hmac_ctx,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length);
|
||||
|
||||
psa_status_t esp_hmac_verify_finish_opaque(esp_hmac_opaque_operation_t *esp_hmac_ctx,
|
||||
const uint8_t *mac,
|
||||
size_t mac_length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ESP_HMAC_OPAQUE_DRIVER_ENABLED */
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "soc/soc_caps.h"
|
||||
#include "psa/crypto_driver_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Size of HMAC result in bytes (the opaque driver only supports SHA-256 based HMAC)
|
||||
*/
|
||||
#define ESP_HMAC_RESULT_SIZE PSA_HASH_LENGTH(PSA_ALG_HMAC(PSA_ALG_SHA_256))
|
||||
|
||||
/**
|
||||
* @brief Structure to store opaque HMAC key.
|
||||
*/
|
||||
typedef struct {
|
||||
bool use_km_key; /**< Use key deployed in the key manager */
|
||||
uint8_t efuse_block; /**< eFuse block id for HMAC key */
|
||||
} esp_hmac_opaque_key_t;
|
||||
|
||||
/**
|
||||
* @brief Structure to store opaque HMAC operation context.
|
||||
*/
|
||||
typedef struct {
|
||||
const esp_hmac_opaque_key_t *opaque_key; /**< Pointer to the opaque key structure */
|
||||
uint8_t hmac[ESP_HMAC_RESULT_SIZE]; /**< Buffer to store the HMAC result */
|
||||
} esp_hmac_opaque_operation_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if defined(ESP_HMAC_TRANSPARENT_DRIVER_ENABLED)
|
||||
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_driver_esp_hmac_transparent_contexts.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
psa_status_t esp_hmac_compute_transparent(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length);
|
||||
|
||||
psa_status_t esp_hmac_abort_transparent(esp_hmac_transparent_operation_t *esp_hmac_ctx);
|
||||
|
||||
psa_status_t esp_hmac_setup_transparent(esp_hmac_transparent_operation_t *esp_hmac_ctx,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg);
|
||||
|
||||
psa_status_t esp_hmac_update_transparent(esp_hmac_transparent_operation_t *esp_hmac_ctx,
|
||||
const uint8_t *data,
|
||||
size_t data_length);
|
||||
|
||||
psa_status_t esp_hmac_finish_transparent(esp_hmac_transparent_operation_t *esp_hmac_ctx,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length);
|
||||
|
||||
psa_status_t esp_hmac_verify_finish_transparent(esp_hmac_transparent_operation_t *esp_hmac_ctx,
|
||||
const uint8_t *mac,
|
||||
size_t mac_length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ESP_HMAC_TRANSPARENT_DRIVER_ENABLED */
|
||||
+8
-8
@@ -6,22 +6,22 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "soc/soc_caps.h"
|
||||
#include "psa/crypto_driver_common.h"
|
||||
#include "psa_crypto_driver_esp_sha_contexts.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(ESP_SHA_DRIVER_ENABLED)
|
||||
|
||||
#include "psa_crypto_driver_esp_sha_contexts.h"
|
||||
#include "psa_crypto_driver_esp_sha.h"
|
||||
|
||||
#if defined(ESP_HMAC_TRANSPARENT_DRIVER_ENABLED)
|
||||
typedef struct {
|
||||
uint8_t opad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
|
||||
psa_algorithm_t alg;
|
||||
esp_sha_hash_operation_t esp_sha_ctx;
|
||||
} esp_hmac_operation_t;
|
||||
|
||||
#endif /* ESP_SHA_DRIVER_ENABLED */
|
||||
} esp_hmac_transparent_operation_t;
|
||||
#endif /* ESP_HMAC_TRANSPARENT_DRIVER_ENABLED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -8,9 +8,13 @@
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "unity.h"
|
||||
static const uint8_t key_128[] = {
|
||||
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
||||
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
||||
#include "esp_log.h"
|
||||
|
||||
static const uint8_t key_256[] = {
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
|
||||
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
||||
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
|
||||
};
|
||||
|
||||
static const uint8_t test_data[] = {
|
||||
@@ -20,44 +24,164 @@ static const uint8_t test_data[] = {
|
||||
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51
|
||||
};
|
||||
|
||||
static const uint8_t expected_hmac_128[] = {
|
||||
0x00, 0x7a, 0x5a, 0xd6, 0x54, 0x96, 0x5b, 0xcd,
|
||||
0x30, 0xc1, 0x60, 0x62, 0xec, 0xac, 0x75, 0xfb,
|
||||
0x87, 0x71, 0x0e, 0x13
|
||||
static const uint8_t expected_hmac_sha1[] = {
|
||||
0xb7, 0xb4, 0x9b, 0xc1, 0x8a, 0x88, 0x43, 0xa2,
|
||||
0xbb, 0x34, 0xdf, 0x27, 0xfe, 0x6c, 0x9b, 0x1b,
|
||||
0xbf, 0x4b, 0x57, 0xb5,
|
||||
};
|
||||
|
||||
static const uint8_t expected_hmac_sha256[] = {
|
||||
0xc4, 0x45, 0xa1, 0xfc, 0x3f, 0x7e, 0x1b, 0xfc,
|
||||
0x4a, 0x33, 0x19, 0xfc, 0x68, 0xa5, 0x8e, 0xf1,
|
||||
0x81, 0x0f, 0x99, 0x70, 0x32, 0x06, 0x2c, 0xcb,
|
||||
0x50, 0xd7, 0x15, 0x78, 0x82, 0x10, 0xbe, 0xc6,
|
||||
};
|
||||
|
||||
// Helper function to set up key attributes for HMAC
|
||||
static void setup_hmac_key_attributes(psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
psa_key_lifetime_t lifetime)
|
||||
{
|
||||
psa_set_key_usage_flags(attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
|
||||
psa_set_key_algorithm(attributes, alg);
|
||||
psa_set_key_type(attributes, PSA_KEY_TYPE_HMAC);
|
||||
psa_set_key_bits(attributes, 256);
|
||||
psa_set_key_lifetime(attributes, lifetime);
|
||||
}
|
||||
|
||||
// Helper function to perform HMAC compute and verify (single-shot)
|
||||
static void test_hmac_compute_and_verify(psa_key_id_t key_id,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *data,
|
||||
size_t data_len,
|
||||
const uint8_t *expected_mac,
|
||||
size_t expected_mac_len)
|
||||
{
|
||||
psa_status_t status;
|
||||
size_t hmac_length = PSA_HASH_LENGTH(alg);
|
||||
uint8_t *hmac = malloc(hmac_length);
|
||||
TEST_ASSERT_NOT_NULL(hmac);
|
||||
|
||||
size_t mac_length = 0;
|
||||
status = psa_mac_compute(key_id, alg, data, data_len,
|
||||
hmac, hmac_length, &mac_length);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
status = psa_mac_verify(key_id, alg, data, data_len,
|
||||
expected_mac, expected_mac_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
free(hmac);
|
||||
}
|
||||
|
||||
// Helper function to perform HMAC multipart sign operation
|
||||
static void test_hmac_multipart_sign(psa_mac_operation_t *op,
|
||||
psa_key_id_t key_id,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *data,
|
||||
size_t data_len,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_len)
|
||||
{
|
||||
psa_status_t status;
|
||||
|
||||
status = psa_mac_sign_setup(op, key_id, alg);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
status = psa_mac_update(op, data, data_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
status = psa_mac_sign_finish(op, mac, mac_size, mac_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
}
|
||||
|
||||
// Helper function to perform HMAC multipart verify operation
|
||||
static void test_hmac_multipart_verify(psa_mac_operation_t *op,
|
||||
psa_key_id_t key_id,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *data,
|
||||
size_t data_len,
|
||||
const uint8_t *mac,
|
||||
size_t mac_len)
|
||||
{
|
||||
psa_status_t status;
|
||||
|
||||
status = psa_mac_verify_setup(op, key_id, alg);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
status = psa_mac_update(op, data, data_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
status = psa_mac_verify_finish(op, mac, mac_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
}
|
||||
|
||||
TEST_CASE("PSA HMAC SHA-1 test", "[psa_hmac]")
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_1);
|
||||
|
||||
// Initialize PSA Crypto
|
||||
status = PSA_SUCCESS;
|
||||
// TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
setup_hmac_key_attributes(&attributes, alg, PSA_KEY_LIFETIME_VOLATILE);
|
||||
|
||||
// Set up key attributes
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(PSA_ALG_SHA_1));
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
|
||||
psa_set_key_bits(&attributes, 128);
|
||||
|
||||
uint8_t *hmac = malloc(PSA_HASH_LENGTH(PSA_ALG_SHA_1));
|
||||
TEST_ASSERT_NOT_NULL(hmac);
|
||||
|
||||
status = psa_import_key(&attributes, key_128, sizeof(key_128), &key_id);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
size_t mac_length = 0;
|
||||
status = psa_mac_compute(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_1),
|
||||
test_data, sizeof(test_data),
|
||||
hmac, PSA_HASH_LENGTH(PSA_ALG_SHA_1), &mac_length);
|
||||
status = psa_import_key(&attributes, key_256, sizeof(key_256), &key_id);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
status = psa_mac_verify(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_1),
|
||||
test_data, sizeof(test_data),
|
||||
expected_hmac_128, sizeof(expected_hmac_128));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
test_hmac_compute_and_verify(key_id, alg, test_data, sizeof(test_data),
|
||||
expected_hmac_sha1, sizeof(expected_hmac_sha1));
|
||||
|
||||
psa_destroy_key(key_id);
|
||||
psa_reset_key_attributes(&attributes);
|
||||
}
|
||||
|
||||
TEST_CASE("PSA HMAC SHA-256 test", "[psa_hmac]")
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
|
||||
|
||||
setup_hmac_key_attributes(&attributes, alg, PSA_KEY_LIFETIME_VOLATILE);
|
||||
|
||||
status = psa_import_key(&attributes, key_256, sizeof(key_256), &key_id);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
test_hmac_compute_and_verify(key_id, alg, test_data, sizeof(test_data),
|
||||
expected_hmac_sha256, sizeof(expected_hmac_sha256));
|
||||
|
||||
psa_destroy_key(key_id);
|
||||
psa_reset_key_attributes(&attributes);
|
||||
}
|
||||
|
||||
TEST_CASE("PSA HMAC SHA-256 multipart test", "[psa_hmac]")
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
|
||||
size_t hmac_length = PSA_HASH_LENGTH(alg);
|
||||
size_t mac_len = 0;
|
||||
|
||||
setup_hmac_key_attributes(&attributes, alg, PSA_KEY_LIFETIME_VOLATILE);
|
||||
|
||||
uint8_t *hmac = malloc(hmac_length);
|
||||
TEST_ASSERT_NOT_NULL(hmac);
|
||||
|
||||
status = psa_import_key(&attributes, key_256, sizeof(key_256), &key_id);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
psa_mac_operation_t op = PSA_MAC_OPERATION_INIT;
|
||||
|
||||
test_hmac_multipart_sign(&op, key_id, alg, test_data, sizeof(test_data),
|
||||
hmac, hmac_length, &mac_len);
|
||||
|
||||
test_hmac_multipart_verify(&op, key_id, alg, test_data, sizeof(test_data),
|
||||
expected_hmac_sha256, sizeof(expected_hmac_sha256));
|
||||
|
||||
psa_reset_key_attributes(&attributes);
|
||||
psa_mac_abort(&op);
|
||||
psa_destroy_key(key_id);
|
||||
free(hmac);
|
||||
}
|
||||
|
||||
@@ -227,7 +227,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 \
|
||||
@@ -293,6 +292,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 \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user