mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
Merge branch 'fix/align_sw_psa_drivers_and_hw_esp_psa_drivers_v6.1' into 'release/v6.1'
Align s/w and h/w PSA drivers (v6.1) See merge request espressif/esp-idf!49704
This commit is contained in:
Submodule components/mbedtls/mbedtls updated: 6cc42afad3...a2b32072ea
@@ -34,12 +34,18 @@ static psa_status_t esp_aes_cipher_setup(
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Cross-check the attributes against the buffer size; per-target HW
|
||||
* key-size support is enforced by esp_aes_setkey below. */
|
||||
if (psa_get_key_bits(attributes) != key_buffer_size * 8) {
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
switch (alg) {
|
||||
case PSA_ALG_ECB_NO_PADDING:
|
||||
case PSA_ALG_CBC_NO_PADDING:
|
||||
case PSA_ALG_CBC_PKCS7:
|
||||
case PSA_ALG_CTR:
|
||||
case PSA_ALG_XTS:
|
||||
case PSA_ALG_CFB:
|
||||
case PSA_ALG_OFB:
|
||||
break;
|
||||
@@ -56,17 +62,17 @@ static psa_status_t esp_aes_cipher_setup(
|
||||
|
||||
esp_aes_init(ctx);
|
||||
|
||||
status = mbedtls_to_psa_error(esp_aes_setkey(ctx, key_buffer, key_buffer_size * 8));
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
free(ctx);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
esp_aes_driver_ctx->aes_alg = alg;
|
||||
esp_aes_driver_ctx->mode = mode;
|
||||
esp_aes_driver_ctx->esp_aes_ctx = (void *) ctx;
|
||||
esp_aes_driver_ctx->block_length = (PSA_ALG_IS_STREAM_CIPHER(alg) ? 1 : PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES));
|
||||
|
||||
status = mbedtls_to_psa_error(esp_aes_setkey(ctx, key_buffer, key_buffer_size * 8));
|
||||
if (status != PSA_SUCCESS) {
|
||||
esp_aes_cipher_abort(esp_aes_driver_ctx);
|
||||
return status;
|
||||
}
|
||||
|
||||
exit:
|
||||
return status;
|
||||
}
|
||||
@@ -98,6 +104,14 @@ psa_status_t esp_aes_cipher_set_iv(
|
||||
const uint8_t *iv,
|
||||
size_t iv_length)
|
||||
{
|
||||
if (esp_aes_driver_ctx == NULL || esp_aes_driver_ctx->esp_aes_ctx == NULL) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
if (iv == NULL && iv_length > 0) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (iv_length != PSA_CIPHER_IV_LENGTH(PSA_KEY_TYPE_AES, esp_aes_driver_ctx->aes_alg)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
@@ -268,6 +282,19 @@ psa_status_t esp_aes_cipher_update(
|
||||
{
|
||||
int ret = -1;
|
||||
size_t expected_output_size;
|
||||
|
||||
if (output_length == NULL) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if ((input == NULL && input_length > 0) ||
|
||||
(output == NULL && output_size > 0)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (esp_aes_driver_ctx == NULL || esp_aes_driver_ctx->esp_aes_ctx == NULL) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
*output_length = 0;
|
||||
|
||||
if (!PSA_ALG_IS_STREAM_CIPHER(esp_aes_driver_ctx->aes_alg)) {
|
||||
@@ -378,34 +405,39 @@ static void add_pkcs_padding(unsigned char *output, size_t output_len,
|
||||
}
|
||||
}
|
||||
|
||||
static int get_pkcs_padding(unsigned char *input, size_t input_len, size_t *data_len)
|
||||
/* Reports PKCS7 padding validity through *invalid_padding (a constant-time
|
||||
* condition) instead of the return value, so esp_aes_cipher_finish can fold it
|
||||
* into the result branchlessly and avoid a padding-oracle branch */
|
||||
static void get_pkcs_padding(unsigned char *input, size_t input_len, size_t *data_len,
|
||||
mbedtls_ct_condition_t *invalid_padding)
|
||||
{
|
||||
size_t i, pad_idx;
|
||||
unsigned char padding_len;
|
||||
|
||||
if (NULL == input || NULL == data_len) {
|
||||
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
padding_len = input[input_len - 1];
|
||||
if (padding_len == 0 || padding_len > input_len) {
|
||||
return MBEDTLS_ERR_CIPHER_INVALID_PADDING;
|
||||
}
|
||||
*data_len = input_len - padding_len;
|
||||
|
||||
mbedtls_ct_condition_t bad = mbedtls_ct_uint_gt(padding_len, input_len);
|
||||
bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0));
|
||||
|
||||
/* Clamp padding_len to [0, input_len] before the math so out-of-range
|
||||
* values do not produce a size_t underflow. The bad flag already records
|
||||
* whether the original value was invalid. */
|
||||
size_t safe_padding_len = mbedtls_ct_size_if(mbedtls_ct_uint_gt((size_t)padding_len, input_len),
|
||||
input_len, (size_t)padding_len);
|
||||
pad_idx = input_len - safe_padding_len;
|
||||
|
||||
/* The number of bytes checked must be independent of padding_len,
|
||||
* so pick input_len, which is usually 8 or 16 (one block) */
|
||||
pad_idx = input_len - padding_len;
|
||||
for (i = 0; i < input_len; i++) {
|
||||
mbedtls_ct_condition_t in_padding = mbedtls_ct_uint_ge(i, pad_idx);
|
||||
mbedtls_ct_condition_t different = mbedtls_ct_uint_ne(input[i], padding_len);
|
||||
bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool_and(in_padding, different));
|
||||
}
|
||||
|
||||
return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING);
|
||||
/* Gate *data_len on the bad flag so it does not leak padding validity. */
|
||||
*data_len = mbedtls_ct_if(bad, 0, pad_idx);
|
||||
|
||||
*invalid_padding = bad;
|
||||
}
|
||||
|
||||
psa_status_t esp_aes_cipher_finish(
|
||||
@@ -415,9 +447,20 @@ psa_status_t esp_aes_cipher_finish(
|
||||
size_t *output_length)
|
||||
{
|
||||
int ret = -1;
|
||||
esp_aes_context *ctx = (esp_aes_context *) esp_aes_driver_ctx->esp_aes_ctx;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
uint8_t temp_output_buffer[ESP_MBEDTLS_AES_MAX_BLOCK_LENGTH];
|
||||
uint8_t temp_output_buffer[ESP_MBEDTLS_AES_MAX_BLOCK_LENGTH] = { 0 };
|
||||
mbedtls_ct_condition_t invalid_padding = mbedtls_ct_bool(0);
|
||||
|
||||
if (esp_aes_driver_ctx == NULL || esp_aes_driver_ctx->esp_aes_ctx == NULL) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
esp_aes_context *ctx = (esp_aes_context *) esp_aes_driver_ctx->esp_aes_ctx;
|
||||
|
||||
*output_length = 0;
|
||||
|
||||
if (output_size > sizeof(temp_output_buffer)) {
|
||||
output_size = sizeof(temp_output_buffer);
|
||||
}
|
||||
|
||||
if (esp_aes_driver_ctx->unprocessed_len != 0) {
|
||||
if (esp_aes_driver_ctx->aes_alg == PSA_ALG_ECB_NO_PADDING ||
|
||||
@@ -427,7 +470,6 @@ psa_status_t esp_aes_cipher_finish(
|
||||
}
|
||||
}
|
||||
|
||||
*output_length = 0;
|
||||
switch (esp_aes_driver_ctx->aes_alg) {
|
||||
case PSA_ALG_ECB_NO_PADDING:
|
||||
case PSA_ALG_CTR:
|
||||
@@ -443,15 +485,10 @@ psa_status_t esp_aes_cipher_finish(
|
||||
* Otherwise, we pad the partial block. */
|
||||
add_pkcs_padding(esp_aes_driver_ctx->unprocessed_data, esp_aes_driver_ctx->block_length, esp_aes_driver_ctx->unprocessed_len);
|
||||
} else if (esp_aes_driver_ctx->unprocessed_len != esp_aes_driver_ctx->block_length) {
|
||||
/*
|
||||
* For decrypt operations, expect a full block,
|
||||
* or an empty block if no padding
|
||||
*/
|
||||
if (esp_aes_driver_ctx->unprocessed_len == 0) {
|
||||
status = PSA_SUCCESS;
|
||||
break;
|
||||
}
|
||||
return mbedtls_to_psa_error(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED);
|
||||
/* PKCS7 decrypt requires at least one full ciphertext block
|
||||
* (the trailing block always contains padding). */
|
||||
status = mbedtls_to_psa_error(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED);
|
||||
goto exit;
|
||||
}
|
||||
ret = esp_aes_crypt_cbc(ctx, esp_aes_driver_ctx->mode,
|
||||
esp_aes_driver_ctx->block_length,
|
||||
@@ -459,14 +496,13 @@ psa_status_t esp_aes_cipher_finish(
|
||||
esp_aes_driver_ctx->unprocessed_data,
|
||||
temp_output_buffer);
|
||||
if (ret != 0) {
|
||||
return mbedtls_to_psa_error(ret);
|
||||
status = mbedtls_to_psa_error(ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (esp_aes_driver_ctx->mode == PSA_CRYPTO_DRIVER_DECRYPT) {
|
||||
ret = get_pkcs_padding(temp_output_buffer, esp_aes_driver_ctx->block_length, output_length);
|
||||
if (ret != 0) {
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
get_pkcs_padding(temp_output_buffer, esp_aes_driver_ctx->block_length,
|
||||
output_length, &invalid_padding);
|
||||
} else {
|
||||
*output_length = esp_aes_driver_ctx->block_length;
|
||||
}
|
||||
@@ -481,9 +517,11 @@ psa_status_t esp_aes_cipher_finish(
|
||||
}
|
||||
} else if (esp_aes_driver_ctx->unprocessed_len != esp_aes_driver_ctx->block_length) {
|
||||
if (esp_aes_driver_ctx->unprocessed_len == 0) {
|
||||
return PSA_SUCCESS;
|
||||
status = PSA_SUCCESS;
|
||||
goto exit;
|
||||
}
|
||||
return mbedtls_to_psa_error(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED);
|
||||
status = mbedtls_to_psa_error(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = esp_aes_crypt_cbc(ctx, esp_aes_driver_ctx->mode,
|
||||
@@ -492,7 +530,8 @@ psa_status_t esp_aes_cipher_finish(
|
||||
esp_aes_driver_ctx->unprocessed_data,
|
||||
temp_output_buffer);
|
||||
if (ret != 0) {
|
||||
return mbedtls_to_psa_error(ret);
|
||||
status = mbedtls_to_psa_error(ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
*output_length = esp_aes_driver_ctx->block_length;
|
||||
@@ -503,14 +542,17 @@ psa_status_t esp_aes_cipher_finish(
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (*output_length == 0) {
|
||||
; /* Nothing to copy. Note that output may be NULL in this case. */
|
||||
} else if (output_size >= *output_length) {
|
||||
memcpy(output, temp_output_buffer, *output_length);
|
||||
} else {
|
||||
status = PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
if (output_size != 0) {
|
||||
memcpy(output, temp_output_buffer, output_size);
|
||||
}
|
||||
|
||||
status = mbedtls_ct_error_if_else_0(invalid_padding,
|
||||
PSA_ERROR_INVALID_PADDING);
|
||||
mbedtls_ct_condition_t buffer_too_small = mbedtls_ct_uint_lt(output_size, *output_length);
|
||||
status = mbedtls_ct_error_if(buffer_too_small,
|
||||
PSA_ERROR_BUFFER_TOO_SMALL,
|
||||
status);
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize(temp_output_buffer, sizeof(temp_output_buffer));
|
||||
return status;
|
||||
@@ -519,12 +561,15 @@ exit:
|
||||
psa_status_t esp_aes_cipher_abort(
|
||||
esp_aes_operation_t *esp_aes_driver_ctx)
|
||||
{
|
||||
esp_aes_context *ctx = (esp_aes_context *) esp_aes_driver_ctx->esp_aes_ctx;
|
||||
if (ctx == NULL) {
|
||||
if (esp_aes_driver_ctx == NULL) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
esp_aes_free(ctx);
|
||||
free(ctx);
|
||||
esp_aes_context *ctx = (esp_aes_context *) esp_aes_driver_ctx->esp_aes_ctx;
|
||||
if (ctx != NULL) {
|
||||
esp_aes_free(ctx);
|
||||
free(ctx);
|
||||
}
|
||||
mbedtls_platform_zeroize(esp_aes_driver_ctx, sizeof(*esp_aes_driver_ctx));
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -631,15 +676,15 @@ psa_status_t esp_aes_cipher_decrypt(
|
||||
status = esp_aes_cipher_finish(&esp_aes_driver_ctx,
|
||||
mbedtls_buffer_offset(output, accumulated_length),
|
||||
output_size - accumulated_length, &olength);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Failed to finish: %ld", status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
*output_length = accumulated_length + olength;
|
||||
|
||||
exit:
|
||||
esp_aes_cipher_abort(&esp_aes_driver_ctx);
|
||||
{
|
||||
psa_status_t abort_status = esp_aes_cipher_abort(&esp_aes_driver_ctx);
|
||||
if (abort_status != PSA_SUCCESS) {
|
||||
status = abort_status;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <string.h>
|
||||
#include "esp_log.h"
|
||||
#include "psa_crypto_core.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "aes/esp_aes_gcm.h"
|
||||
#include "psa_crypto_driver_esp_aes_gcm.h"
|
||||
#include "../include/psa_crypto_driver_esp_aes_contexts.h"
|
||||
@@ -31,8 +32,16 @@ static psa_status_t esp_crypto_aes_gcm_setup(
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Get the tag length from the algorithm */
|
||||
/* Get the tag length from the algorithm and reject GCM-disallowed values
|
||||
* (GCM permits only {4, 8, 12, 13, 14, 15, 16}). */
|
||||
tag_length = PSA_ALG_AEAD_GET_TAG_LENGTH(alg);
|
||||
switch (tag_length) {
|
||||
case 4: case 8: case 12: case 13: case 14: case 15: case 16:
|
||||
break;
|
||||
default:
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (psa_get_key_type(attributes) != PSA_KEY_TYPE_AES) {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
@@ -46,16 +55,14 @@ static psa_status_t esp_crypto_aes_gcm_setup(
|
||||
}
|
||||
|
||||
esp_aes_gcm_init(ctx);
|
||||
esp_aes_gcm_driver_ctx->esp_aes_gcm_ctx = (void *) ctx;
|
||||
|
||||
status = mbedtls_to_psa_error(esp_aes_gcm_setkey(ctx, 2, key_buffer, key_buffer_size * 8));
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
esp_aes_gcm_free(ctx);
|
||||
free(ctx);
|
||||
(void)esp_crypto_aes_gcm_abort(esp_aes_gcm_driver_ctx);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
esp_aes_gcm_driver_ctx->esp_aes_gcm_ctx = (void *) ctx;
|
||||
esp_aes_gcm_driver_ctx->mode = mode;
|
||||
esp_aes_gcm_driver_ctx->tag_length = tag_length;
|
||||
|
||||
@@ -90,6 +97,9 @@ psa_status_t esp_crypto_aes_gcm_set_nonce(
|
||||
const uint8_t *nonce,
|
||||
size_t nonce_length)
|
||||
{
|
||||
if (esp_aes_gcm_driver_ctx == NULL || esp_aes_gcm_driver_ctx->esp_aes_gcm_ctx == NULL) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
esp_gcm_context *ctx = (esp_gcm_context *) esp_aes_gcm_driver_ctx->esp_aes_gcm_ctx;
|
||||
return mbedtls_to_psa_error(esp_aes_gcm_starts(ctx, esp_aes_gcm_driver_ctx->mode, nonce, nonce_length));
|
||||
}
|
||||
@@ -99,6 +109,9 @@ psa_status_t esp_crypto_aes_gcm_update_ad(
|
||||
const uint8_t *aad,
|
||||
size_t aad_length)
|
||||
{
|
||||
if (esp_aes_gcm_driver_ctx == NULL || esp_aes_gcm_driver_ctx->esp_aes_gcm_ctx == NULL) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
esp_gcm_context *ctx = (esp_gcm_context *) esp_aes_gcm_driver_ctx->esp_aes_gcm_ctx;
|
||||
return mbedtls_to_psa_error(esp_aes_gcm_update_ad(ctx, aad, aad_length));
|
||||
}
|
||||
@@ -114,6 +127,9 @@ psa_status_t esp_crypto_aes_gcm_update(
|
||||
size_t update_output_length = input_length;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (esp_aes_gcm_driver_ctx == NULL || esp_aes_gcm_driver_ctx->esp_aes_gcm_ctx == NULL) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
esp_gcm_context *ctx = (esp_gcm_context *) esp_aes_gcm_driver_ctx->esp_aes_gcm_ctx;
|
||||
status = mbedtls_to_psa_error(esp_aes_gcm_update(ctx, input, input_length, output, output_size, &update_output_length));
|
||||
if (status == PSA_SUCCESS) {
|
||||
@@ -133,6 +149,11 @@ psa_status_t esp_crypto_aes_gcm_finish(
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t finish_output_size = 0;
|
||||
|
||||
if (esp_aes_gcm_driver_ctx == NULL || esp_aes_gcm_driver_ctx->esp_aes_gcm_ctx == NULL) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
size_t requested_tag_length = esp_aes_gcm_driver_ctx->tag_length;
|
||||
|
||||
if (tag_size < requested_tag_length) {
|
||||
@@ -157,17 +178,22 @@ psa_status_t esp_crypto_aes_gcm_finish(
|
||||
/* Copy only the requested tag length */
|
||||
memcpy(tag, full_tag, requested_tag_length);
|
||||
}
|
||||
mbedtls_platform_zeroize(full_tag, sizeof(full_tag));
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t esp_crypto_aes_gcm_abort(esp_aes_gcm_operation_t *esp_aes_gcm_driver_ctx)
|
||||
{
|
||||
if (esp_aes_gcm_driver_ctx == NULL) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
esp_gcm_context *ctx = (esp_gcm_context *) esp_aes_gcm_driver_ctx->esp_aes_gcm_ctx;
|
||||
if (ctx == NULL) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
esp_aes_gcm_free(ctx);
|
||||
free(ctx);
|
||||
mbedtls_platform_zeroize(esp_aes_gcm_driver_ctx, sizeof(*esp_aes_gcm_driver_ctx));
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -219,6 +245,7 @@ psa_status_t esp_crypto_aes_gcm_encrypt(
|
||||
memcpy(tag, full_tag, tag_length);
|
||||
*ciphertext_length = plaintext_length + tag_length;
|
||||
}
|
||||
mbedtls_platform_zeroize(full_tag, sizeof(full_tag));
|
||||
|
||||
exit:
|
||||
esp_crypto_aes_gcm_abort(&esp_aes_gcm_driver_ctx);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "mbedtls/bignum.h"
|
||||
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "esp_assert.h"
|
||||
#include "esp_fault.h"
|
||||
#include "esp_crypto_lock.h"
|
||||
@@ -453,6 +454,14 @@ psa_status_t esp_ecdsa_transparent_verify_hash_start(
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* HW only implements SECP_R1; reject any other ECC family up front so
|
||||
* we never derive the curve from key_bits alone. */
|
||||
psa_key_type_t key_type = psa_get_key_type(attributes);
|
||||
if (!PSA_KEY_TYPE_IS_ECC(key_type) ||
|
||||
PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) != PSA_ECC_FAMILY_SECP_R1) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
size_t key_len = PSA_BITS_TO_BYTES(psa_get_key_bits(attributes));
|
||||
esp_ecdsa_curve_t curve = psa_bits_to_ecdsa_curve(key_len);
|
||||
if (curve == ESP_ECDSA_CURVE_MAX) {
|
||||
@@ -529,6 +538,17 @@ psa_status_t esp_ecdsa_transparent_verify_hash_start(
|
||||
change_endianess(public_key_buffer + 1 + key_len, point.y, key_len);
|
||||
point.len = key_len;
|
||||
|
||||
/* Reject the identity (point at infinity, all-zero coords) explicitly —
|
||||
* esp_ecc_point_verify may not catch it on all peripherals. */
|
||||
bool qx_zero = true, qy_zero = true;
|
||||
for (size_t i = 0; i < key_len; i++) {
|
||||
qx_zero = qx_zero && (point.x[i] == 0);
|
||||
qy_zero = qy_zero && (point.y[i] == 0);
|
||||
}
|
||||
if (qx_zero && qy_zero) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (!esp_ecc_point_verify(&point)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
@@ -580,7 +600,7 @@ psa_status_t esp_ecdsa_transparent_verify_hash_complete(esp_ecdsa_transparent_ve
|
||||
psa_status_t esp_ecdsa_transparent_verify_hash_abort(esp_ecdsa_transparent_verify_hash_operation_t *operation)
|
||||
{
|
||||
if (operation) {
|
||||
memset(operation, 0, sizeof(esp_ecdsa_transparent_verify_hash_operation_t));
|
||||
mbedtls_platform_zeroize(operation, sizeof(esp_ecdsa_transparent_verify_hash_operation_t));
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
@@ -600,16 +620,12 @@ psa_status_t esp_ecdsa_transparent_verify_hash(
|
||||
esp_ecdsa_transparent_verify_hash_operation_t operation;
|
||||
|
||||
status = esp_ecdsa_transparent_verify_hash_start(&operation, attributes, key_buffer, key_buffer_size, alg, hash, hash_length, signature, signature_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
if (status == PSA_SUCCESS) {
|
||||
status = esp_ecdsa_transparent_verify_hash_complete(&operation);
|
||||
}
|
||||
|
||||
status = esp_ecdsa_transparent_verify_hash_complete(&operation);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return esp_ecdsa_transparent_verify_hash_abort(&operation);
|
||||
esp_ecdsa_transparent_verify_hash_abort(&operation);
|
||||
return status;
|
||||
}
|
||||
#endif /* SOC_ECDSA_SUPPORTED */
|
||||
|
||||
@@ -710,6 +726,12 @@ static psa_status_t esp_ecdsa_validate_efuse_block(esp_ecdsa_curve_t curve, int
|
||||
*/
|
||||
static psa_status_t validate_ecdsa_opaque_key_attributes(const psa_key_attributes_t *attributes, const esp_ecdsa_opaque_key_t *opaque_key)
|
||||
{
|
||||
psa_key_type_t key_type = psa_get_key_type(attributes);
|
||||
if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ||
|
||||
PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) != PSA_ECC_FAMILY_SECP_R1) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
esp_ecdsa_curve_t expected_curve = psa_bits_to_ecdsa_curve(PSA_BITS_TO_BYTES(psa_get_key_bits(attributes)));
|
||||
|
||||
if (expected_curve == ESP_ECDSA_CURVE_MAX || expected_curve != opaque_key->curve) {
|
||||
@@ -742,6 +764,11 @@ static psa_status_t validate_ecdsa_opaque_key_attributes(const psa_key_attribute
|
||||
*/
|
||||
static psa_status_t validate_storage_curve(const psa_key_attributes_t *attributes, esp_ecdsa_curve_t stored_curve)
|
||||
{
|
||||
psa_key_type_t key_type = psa_get_key_type(attributes);
|
||||
if (!PSA_KEY_TYPE_IS_ECC(key_type) ||
|
||||
PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) != PSA_ECC_FAMILY_SECP_R1) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
esp_ecdsa_curve_t expected_curve = psa_bits_to_ecdsa_curve(PSA_BITS_TO_BYTES(psa_get_key_bits(attributes)));
|
||||
if (expected_curve == ESP_ECDSA_CURVE_MAX || expected_curve != stored_curve) {
|
||||
ESP_LOGE(TAG, "Invalid curve expected");
|
||||
@@ -1033,6 +1060,12 @@ psa_status_t esp_ecdsa_opaque_sign_hash_complete(
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Without HW/SW deterministic-ECDSA support, do not silently downgrade
|
||||
* a deterministic-alg request to randomized. */
|
||||
if (PSA_ALG_ECDSA_IS_DETERMINISTIC(operation->alg)) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
#endif /* CONFIG_MBEDTLS_ECDSA_DETERMINISTIC && SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE */
|
||||
|
||||
uint8_t zeroes[MAX_ECDSA_COMPONENT_LEN] = {0};
|
||||
@@ -1069,6 +1102,11 @@ psa_status_t esp_ecdsa_opaque_sign_hash_complete(
|
||||
ecdsa_curve_t hal_curve = esp_ecdsa_curve_to_hal_curve(curve);
|
||||
if (hal_curve == (ecdsa_curve_t)-1) {
|
||||
esp_ecdsa_release_hardware();
|
||||
#if SOC_KEY_MANAGER_SUPPORTED
|
||||
if (key_recovery_info) {
|
||||
esp_key_mgr_deactivate_key(key_recovery_info->key_type);
|
||||
}
|
||||
#endif /* SOC_KEY_MANAGER_SUPPORTED */
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
@@ -1156,7 +1194,7 @@ psa_status_t esp_ecdsa_opaque_sign_hash_complete(
|
||||
psa_status_t esp_ecdsa_opaque_sign_hash_abort(esp_ecdsa_opaque_sign_hash_operation_t *operation)
|
||||
{
|
||||
if (operation) {
|
||||
memset(operation, 0, sizeof(esp_ecdsa_opaque_sign_hash_operation_t));
|
||||
mbedtls_platform_zeroize(operation, sizeof(esp_ecdsa_opaque_sign_hash_operation_t));
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
@@ -1184,12 +1222,9 @@ psa_status_t esp_ecdsa_opaque_sign_hash(
|
||||
}
|
||||
|
||||
status = esp_ecdsa_opaque_sign_hash_complete(&operation, signature, signature_size, signature_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
esp_ecdsa_opaque_sign_hash_abort(&operation);
|
||||
return status;
|
||||
}
|
||||
|
||||
return esp_ecdsa_opaque_sign_hash_abort(&operation);
|
||||
esp_ecdsa_opaque_sign_hash_abort(&operation);
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t esp_ecdsa_opaque_export_public_key(
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_driver_esp_cmac.h"
|
||||
#include "psa_crypto_driver_esp_cmac_contexts.h"
|
||||
@@ -66,20 +67,19 @@ static inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x)
|
||||
|
||||
psa_status_t esp_cmac_abort(esp_cmac_operation_t *esp_cmac_ctx)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
status = psa_destroy_key(esp_cmac_ctx->key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
if (esp_cmac_ctx == NULL) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
status = esp_aes_cipher_abort(&esp_cmac_ctx->esp_aes_ctx);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
if (esp_cmac_ctx->alg == 0) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
(void)psa_destroy_key(esp_cmac_ctx->key_id);
|
||||
(void)esp_aes_cipher_abort(&esp_cmac_ctx->esp_aes_ctx);
|
||||
|
||||
mbedtls_platform_zeroize(esp_cmac_ctx, sizeof(esp_cmac_operation_t));
|
||||
return status;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t esp_cmac_setup(esp_cmac_operation_t *esp_cmac_ctx,
|
||||
@@ -89,10 +89,27 @@ psa_status_t esp_cmac_setup(esp_cmac_operation_t *esp_cmac_ctx,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
if (esp_cmac_ctx == NULL) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (esp_cmac_ctx->alg != 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
if (PSA_ALG_FULL_LENGTH_MAC(alg) != PSA_ALG_CMAC) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
if (psa_get_key_type(attributes) != PSA_KEY_TYPE_AES) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
memset(esp_cmac_ctx, 0, sizeof(*esp_cmac_ctx));
|
||||
|
||||
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
esp_cmac_ctx->alg = alg;
|
||||
|
||||
psa_key_type_t key_type = psa_get_key_type(attributes);
|
||||
size_t key_bits = psa_get_key_bits(attributes);
|
||||
psa_algorithm_t cmac_aes_key_alg = PSA_ALG_ECB_NO_PADDING;
|
||||
@@ -105,24 +122,21 @@ psa_status_t esp_cmac_setup(esp_cmac_operation_t *esp_cmac_ctx,
|
||||
/* Import key for cipher operations */
|
||||
status = psa_import_key(&key_attributes, key_buffer, key_buffer_size, &esp_cmac_ctx->key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
goto error;
|
||||
}
|
||||
|
||||
status = esp_aes_cipher_encrypt_setup(&esp_cmac_ctx->esp_aes_ctx, &key_attributes, key_buffer, key_buffer_size, cmac_aes_key_alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
psa_destroy_key(esp_cmac_ctx->key_id);
|
||||
goto exit;
|
||||
goto error;
|
||||
}
|
||||
|
||||
psa_reset_key_attributes(&key_attributes);
|
||||
esp_cmac_ctx->alg = alg;
|
||||
esp_cmac_ctx->unprocessed_len = 0;
|
||||
esp_cmac_ctx->cipher_block_length = PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type);
|
||||
mbedtls_platform_zeroize(esp_cmac_ctx->state, sizeof(esp_cmac_ctx->state));
|
||||
mbedtls_platform_zeroize(esp_cmac_ctx->unprocessed_block, sizeof(esp_cmac_ctx->unprocessed_block));
|
||||
|
||||
exit:
|
||||
psa_reset_key_attributes(&key_attributes);
|
||||
return PSA_SUCCESS;
|
||||
|
||||
error:
|
||||
psa_reset_key_attributes(&key_attributes);
|
||||
esp_cmac_abort(esp_cmac_ctx);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -140,9 +154,18 @@ psa_status_t esp_cmac_update(esp_cmac_operation_t *esp_cmac_ctx, const uint8_t *
|
||||
size_t n, j, olen, block_size;
|
||||
unsigned char *state;
|
||||
|
||||
if (esp_cmac_ctx == NULL || data == NULL) {
|
||||
if (esp_cmac_ctx == NULL) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (data == NULL && data_length != 0) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (esp_cmac_ctx->alg == 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
if (data_length == 0) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
state = esp_cmac_ctx->state;
|
||||
block_size = esp_cmac_ctx->cipher_block_length;
|
||||
@@ -294,12 +317,18 @@ psa_status_t esp_cmac_finish(
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (esp_cmac_ctx->alg == 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
state = esp_cmac_ctx->state;
|
||||
block_size = esp_cmac_ctx->cipher_block_length;
|
||||
|
||||
mbedtls_platform_zeroize(K1, sizeof(K1));
|
||||
mbedtls_platform_zeroize(K2, sizeof(K2));
|
||||
cmac_generate_subkeys(&esp_cmac_ctx->esp_aes_ctx, block_size, K1, K2);
|
||||
if ((status = cmac_generate_subkeys(&esp_cmac_ctx->esp_aes_ctx, block_size, K1, K2)) != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
last_block = esp_cmac_ctx->unprocessed_block;
|
||||
|
||||
@@ -324,10 +353,9 @@ psa_status_t esp_cmac_finish(
|
||||
exit:
|
||||
mbedtls_platform_zeroize(K1, sizeof(K1));
|
||||
mbedtls_platform_zeroize(K2, sizeof(K2));
|
||||
mbedtls_platform_zeroize(M_last, sizeof(M_last));
|
||||
|
||||
esp_cmac_ctx->unprocessed_len = 0;
|
||||
mbedtls_platform_zeroize(esp_cmac_ctx->unprocessed_block, sizeof(esp_cmac_ctx->unprocessed_block));
|
||||
mbedtls_platform_zeroize(state, PSA_CMAC_MAX_BLOCK_SIZE);
|
||||
(void)esp_cmac_abort(esp_cmac_ctx);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -384,7 +412,11 @@ psa_status_t esp_cmac_verify_finish(
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (mac_length > sizeof(actual_mac)) {
|
||||
if (esp_cmac_ctx->alg == 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
if (mac_length == 0 || mac_length > sizeof(actual_mac)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
|
||||
@@ -237,6 +237,10 @@ psa_status_t esp_hmac_setup_opaque(
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (esp_hmac_ctx->alg != 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
if (key_buffer_size < sizeof(esp_hmac_efuse_key_storage_t)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
@@ -265,83 +269,120 @@ psa_status_t esp_hmac_setup_opaque(
|
||||
|
||||
memset(esp_hmac_ctx, 0, sizeof(esp_hmac_opaque_operation_t));
|
||||
|
||||
esp_hmac_ctx->alg = alg;
|
||||
esp_hmac_ctx->key_buffer = key_buffer;
|
||||
esp_hmac_ctx->is_persistent = is_persistent;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t esp_hmac_update_opaque(esp_hmac_opaque_operation_t *esp_hmac_ctx, const uint8_t *data, size_t data_length)
|
||||
#if SOC_KEY_MANAGER_SUPPORTED && !ESP_TEE_BUILD
|
||||
static psa_status_t esp_hmac_opaque_resolve_key(const esp_hmac_opaque_operation_t *ctx,
|
||||
hmac_key_id_t *hmac_key_id,
|
||||
const esp_key_mgr_key_recovery_info_t **kri)
|
||||
{
|
||||
if (!esp_hmac_ctx || !data || data_length == 0) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
const uint8_t *key_buffer = ctx->key_buffer;
|
||||
*kri = NULL;
|
||||
|
||||
if (hmac_storage_get_key_source(key_buffer) == ESP_HMAC_KEY_SOURCE_KEY_MGR) {
|
||||
*kri = ctx->is_persistent
|
||||
? &((const esp_hmac_km_key_storage_t *)key_buffer)->key_recovery_info
|
||||
: ((const esp_hmac_volatile_key_storage_t *)key_buffer)->opaque_key.key_recovery_info;
|
||||
if (esp_key_mgr_activate_key((esp_key_mgr_key_recovery_info_t *)*kri) != ESP_OK) {
|
||||
*kri = NULL;
|
||||
ESP_LOGE("ESP_HMAC_OPAQUE", "Failed to activate key");
|
||||
return PSA_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
*hmac_key_id = HMAC_KEY_KM;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
*hmac_key_id = ctx->is_persistent
|
||||
? ((const esp_hmac_efuse_key_storage_t *)key_buffer)->efuse_key_id
|
||||
: ((const esp_hmac_volatile_key_storage_t *)key_buffer)->opaque_key.efuse_key_id;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
#else
|
||||
static psa_status_t esp_hmac_opaque_resolve_key(const esp_hmac_opaque_operation_t *ctx,
|
||||
hmac_key_id_t *hmac_key_id)
|
||||
{
|
||||
const uint8_t *key_buffer = ctx->key_buffer;
|
||||
*hmac_key_id = ctx->is_persistent
|
||||
? ((const esp_hmac_efuse_key_storage_t *)key_buffer)->efuse_key_id
|
||||
: ((const esp_hmac_volatile_key_storage_t *)key_buffer)->opaque_key.efuse_key_id;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
#endif /* SOC_KEY_MANAGER_SUPPORTED && !ESP_TEE_BUILD */
|
||||
|
||||
static psa_status_t esp_hmac_opaque_calculate(esp_hmac_opaque_operation_t *ctx,
|
||||
const uint8_t *data, size_t data_length)
|
||||
{
|
||||
hmac_key_id_t hmac_key_id = 0;
|
||||
psa_status_t status;
|
||||
|
||||
#if SOC_KEY_MANAGER_SUPPORTED && !ESP_TEE_BUILD
|
||||
const esp_key_mgr_key_recovery_info_t *key_recovery_info = NULL;
|
||||
const esp_key_mgr_key_recovery_info_t *kri = NULL;
|
||||
status = esp_hmac_opaque_resolve_key(ctx, &hmac_key_id, &kri);
|
||||
#else
|
||||
status = esp_hmac_opaque_resolve_key(ctx, &hmac_key_id);
|
||||
#endif /* SOC_KEY_MANAGER_SUPPORTED && !ESP_TEE_BUILD */
|
||||
|
||||
if (!esp_hmac_ctx->is_persistent) {
|
||||
const esp_hmac_volatile_key_storage_t *ptr_st =
|
||||
(const esp_hmac_volatile_key_storage_t *)esp_hmac_ctx->key_buffer;
|
||||
#if SOC_KEY_MANAGER_SUPPORTED && !ESP_TEE_BUILD
|
||||
esp_hmac_key_source_t key_source = hmac_storage_get_key_source(esp_hmac_ctx->key_buffer);
|
||||
if (key_source == ESP_HMAC_KEY_SOURCE_KEY_MGR) {
|
||||
key_recovery_info = ptr_st->opaque_key.key_recovery_info;
|
||||
esp_err_t err = esp_key_mgr_activate_key((esp_key_mgr_key_recovery_info_t *)key_recovery_info);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE("ESP_HMAC_OPAQUE", "Failed to activate key: 0x%x", err);
|
||||
return PSA_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
hmac_key_id = HMAC_KEY_KM;
|
||||
} else
|
||||
#endif /* SOC_KEY_MANAGER_SUPPORTED && !ESP_TEE_BUILD */
|
||||
{
|
||||
hmac_key_id = ptr_st->opaque_key.efuse_key_id;
|
||||
}
|
||||
} else {
|
||||
#if SOC_KEY_MANAGER_SUPPORTED && !ESP_TEE_BUILD
|
||||
esp_hmac_key_source_t key_source = hmac_storage_get_key_source(esp_hmac_ctx->key_buffer);
|
||||
if (key_source == ESP_HMAC_KEY_SOURCE_KEY_MGR) {
|
||||
const esp_hmac_km_key_storage_t *km_st =
|
||||
(const esp_hmac_km_key_storage_t *)esp_hmac_ctx->key_buffer;
|
||||
key_recovery_info = &km_st->key_recovery_info;
|
||||
esp_err_t err = esp_key_mgr_activate_key((esp_key_mgr_key_recovery_info_t *)key_recovery_info);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE("ESP_HMAC_OPAQUE", "Failed to activate key: 0x%x", err);
|
||||
return PSA_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
hmac_key_id = HMAC_KEY_KM;
|
||||
} else
|
||||
#endif /* SOC_KEY_MANAGER_SUPPORTED && !ESP_TEE_BUILD */
|
||||
{
|
||||
const esp_hmac_efuse_key_storage_t *efuse_st =
|
||||
(const esp_hmac_efuse_key_storage_t *)esp_hmac_ctx->key_buffer;
|
||||
hmac_key_id = efuse_st->efuse_key_id;
|
||||
}
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
esp_err_t hmac_ret = esp_hmac_calculate(hmac_key_id, data, data_length, esp_hmac_ctx->hmac);
|
||||
esp_err_t hmac_ret = esp_hmac_calculate(hmac_key_id, data, data_length, ctx->hmac);
|
||||
|
||||
#if SOC_KEY_MANAGER_SUPPORTED && !ESP_TEE_BUILD
|
||||
if (key_recovery_info) {
|
||||
esp_key_mgr_deactivate_key(key_recovery_info->key_type);
|
||||
if (kri) {
|
||||
esp_key_mgr_deactivate_key(kri->key_type);
|
||||
}
|
||||
#endif /* SOC_KEY_MANAGER_SUPPORTED && !ESP_TEE_BUILD */
|
||||
|
||||
if (hmac_ret == ESP_OK) {
|
||||
ctx->computed = true;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
mbedtls_platform_zeroize(ctx->hmac, sizeof(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_update_opaque(esp_hmac_opaque_operation_t *esp_hmac_ctx, const uint8_t *data, size_t data_length)
|
||||
{
|
||||
if (!esp_hmac_ctx) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (data == NULL && data_length != 0) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (esp_hmac_ctx->alg == 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
if (esp_hmac_ctx->computed) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
/*
|
||||
* A zero-length update is a valid no-op. The empty-message MAC is produced
|
||||
* lazily in finish: the one-shot HW HMAC cannot be fed incrementally, so we
|
||||
* must not commit a MAC until we know no further (non-empty) data follows.
|
||||
*/
|
||||
if (data_length == 0) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
return esp_hmac_opaque_calculate(esp_hmac_ctx, data, data_length);
|
||||
}
|
||||
|
||||
psa_status_t esp_hmac_finish_opaque(
|
||||
esp_hmac_opaque_operation_t *esp_hmac_ctx,
|
||||
uint8_t *mac,
|
||||
@@ -352,12 +393,34 @@ psa_status_t esp_hmac_finish_opaque(
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (mac_size < ESP_HMAC_RESULT_SIZE) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
if (esp_hmac_ctx->alg == 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
memcpy(mac, esp_hmac_ctx->hmac, ESP_HMAC_RESULT_SIZE);
|
||||
*mac_length = ESP_HMAC_RESULT_SIZE;
|
||||
if (mac_size == 0 || mac_size > ESP_HMAC_RESULT_SIZE) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* No update committed a MAC: the message is empty (e.g. psa_mac_compute()
|
||||
* over "" or setup->finish with no update). Compute HMAC(key, "") now.
|
||||
* esp_hmac_calculate() rejects a NULL pointer, so pass a valid zero-length
|
||||
* buffer rather than NULL.
|
||||
*/
|
||||
if (!esp_hmac_ctx->computed) {
|
||||
const uint8_t empty = 0;
|
||||
psa_status_t status = esp_hmac_opaque_calculate(esp_hmac_ctx, &empty, 0);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* PSA core passes the truncated length as mac_size; copy exactly that
|
||||
* many bytes to honour PSA_ALG_TRUNCATED_MAC. */
|
||||
memcpy(mac, esp_hmac_ctx->hmac, mac_size);
|
||||
*mac_length = mac_size;
|
||||
|
||||
mbedtls_platform_zeroize(esp_hmac_ctx->hmac, sizeof(esp_hmac_ctx->hmac));
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
@@ -379,20 +442,23 @@ psa_status_t esp_hmac_compute_opaque(
|
||||
|
||||
status = esp_hmac_setup_opaque(&esp_hmac_ctx, attributes, key_buffer, key_buffer_size, alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = esp_hmac_update_opaque(&esp_hmac_ctx, input, input_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = esp_hmac_finish_opaque(&esp_hmac_ctx, mac, mac_size, mac_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
size_t actual_mac_length = 0;
|
||||
status = esp_hmac_finish_opaque(&esp_hmac_ctx, mac, mac_size, &actual_mac_length);
|
||||
if (status == PSA_SUCCESS) {
|
||||
*mac_length = actual_mac_length;
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
exit:
|
||||
esp_hmac_abort_opaque(&esp_hmac_ctx);
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t esp_hmac_verify_finish_opaque(
|
||||
@@ -404,7 +470,19 @@ psa_status_t esp_hmac_verify_finish_opaque(
|
||||
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 (esp_hmac_ctx == NULL || mac == NULL) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (mac_length == 0 || mac_length > sizeof(actual_mac)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (esp_hmac_ctx->alg == 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
status = esp_hmac_finish_opaque(esp_hmac_ctx, actual_mac, mac_length, &actual_mac_length);
|
||||
if (status == PSA_SUCCESS) {
|
||||
if (mbedtls_ct_memcmp(mac, actual_mac, mac_length) != 0) {
|
||||
status = PSA_ERROR_INVALID_SIGNATURE;
|
||||
|
||||
@@ -15,20 +15,22 @@
|
||||
|
||||
psa_status_t esp_hmac_abort_transparent(esp_hmac_transparent_operation_t *esp_hmac_ctx)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
if (esp_hmac_ctx == NULL) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
if (esp_hmac_ctx->alg == 0) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
#if defined(ESP_MD5_DRIVER_ENABLED)
|
||||
psa_algorithm_t hash_alg = PSA_ALG_GET_HASH(esp_hmac_ctx->alg);
|
||||
if (hash_alg == PSA_ALG_MD5) {
|
||||
status = esp_md5_hash_abort(&esp_hmac_ctx->md5_ctx);
|
||||
(void)esp_md5_hash_abort(&esp_hmac_ctx->md5_ctx);
|
||||
} else
|
||||
#endif // defined(ESP_MD5_DRIVER_ENABLED)
|
||||
{
|
||||
status = esp_sha_hash_abort(&esp_hmac_ctx->esp_sha_ctx);
|
||||
}
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
(void)esp_sha_hash_abort(&esp_hmac_ctx->esp_sha_ctx);
|
||||
}
|
||||
|
||||
// Free dynamically allocated opad buffer
|
||||
@@ -39,7 +41,7 @@ psa_status_t esp_hmac_abort_transparent(esp_hmac_transparent_operation_t *esp_hm
|
||||
}
|
||||
|
||||
mbedtls_platform_zeroize(esp_hmac_ctx, sizeof(esp_hmac_transparent_operation_t));
|
||||
return status;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t esp_hmac_setup_transparent(esp_hmac_transparent_operation_t *esp_hmac_ctx,
|
||||
@@ -59,12 +61,26 @@ psa_status_t esp_hmac_setup_transparent(esp_hmac_transparent_operation_t *esp_hm
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (!PSA_ALG_IS_HMAC(alg)) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
if (psa_get_key_type(attributes) != PSA_KEY_TYPE_HMAC) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (esp_hmac_ctx->alg != 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
memset(esp_hmac_ctx, 0, sizeof(esp_hmac_transparent_operation_t));
|
||||
|
||||
esp_hmac_ctx->alg = alg;
|
||||
|
||||
// Allocate opad buffer dynamically
|
||||
esp_hmac_ctx->opad = (uint8_t *)malloc(PSA_HMAC_MAX_HASH_BLOCK_SIZE);
|
||||
if (esp_hmac_ctx->opad == NULL) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
memset(esp_hmac_ctx->opad, 0, PSA_HMAC_MAX_HASH_BLOCK_SIZE);
|
||||
|
||||
@@ -80,11 +96,9 @@ psa_status_t esp_hmac_setup_transparent(esp_hmac_transparent_operation_t *esp_hm
|
||||
#endif // SOC_SHA_SUPPORT_SHA512
|
||||
)) {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto error;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
esp_hmac_ctx->alg = alg;
|
||||
|
||||
/* Sanity checks on block_size, to guarantee that there won't be a buffer
|
||||
* overflow below. This should never trigger if the hash algorithm
|
||||
* is implemented correctly. */
|
||||
@@ -92,7 +106,7 @@ psa_status_t esp_hmac_setup_transparent(esp_hmac_transparent_operation_t *esp_hm
|
||||
* have the same size (PSA_HMAC_MAX_HASH_BLOCK_SIZE). */
|
||||
if ((block_size > sizeof(ipad)) || (block_size < hash_size)) {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto error;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (key_buffer_size > block_size) {
|
||||
@@ -107,13 +121,13 @@ psa_status_t esp_hmac_setup_transparent(esp_hmac_transparent_operation_t *esp_hm
|
||||
ipad, sizeof(ipad), &key_buffer_size);
|
||||
}
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto error;
|
||||
goto cleanup;
|
||||
}
|
||||
/* 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) {
|
||||
status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
goto error;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
/* A 0-length key is not commonly used in HMAC when used as a MAC,
|
||||
@@ -124,7 +138,7 @@ psa_status_t esp_hmac_setup_transparent(esp_hmac_transparent_operation_t *esp_hm
|
||||
/* Additional safety check: ensure key fits in ipad buffer */
|
||||
if (key_buffer_size > sizeof(ipad)) {
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
goto error;
|
||||
goto cleanup;
|
||||
}
|
||||
memcpy(ipad, key_buffer, key_buffer_size);
|
||||
}
|
||||
@@ -173,7 +187,7 @@ psa_status_t esp_hmac_setup_transparent(esp_hmac_transparent_operation_t *esp_hm
|
||||
status = esp_sha_hash_setup(&esp_hmac_ctx->esp_sha_ctx, hash_alg);
|
||||
}
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto error;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#if defined(ESP_MD5_DRIVER_ENABLED)
|
||||
@@ -185,22 +199,35 @@ psa_status_t esp_hmac_setup_transparent(esp_hmac_transparent_operation_t *esp_hm
|
||||
status = esp_sha_hash_update(&esp_hmac_ctx->esp_sha_ctx, ipad, block_size);
|
||||
}
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto error;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
return status;
|
||||
status = PSA_SUCCESS;
|
||||
|
||||
error:
|
||||
esp_hmac_abort_transparent(esp_hmac_ctx);
|
||||
cleanup:
|
||||
mbedtls_platform_zeroize(ipad, sizeof(ipad));
|
||||
if (status != PSA_SUCCESS) {
|
||||
esp_hmac_abort_transparent(esp_hmac_ctx);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
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) {
|
||||
if (esp_hmac_ctx == NULL) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (data == NULL && data_length != 0) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (esp_hmac_ctx->alg == 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
if (data_length == 0) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
#if defined(ESP_MD5_DRIVER_ENABLED)
|
||||
psa_algorithm_t hash_alg = PSA_ALG_GET_HASH(esp_hmac_ctx->alg);
|
||||
@@ -225,6 +252,10 @@ psa_status_t esp_hmac_finish_transparent(
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (esp_hmac_ctx->alg == 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
psa_algorithm_t hash_alg = PSA_ALG_GET_HASH(esp_hmac_ctx->alg);
|
||||
|
||||
uint8_t tmp[PSA_HASH_MAX_SIZE];
|
||||
@@ -240,10 +271,21 @@ psa_status_t esp_hmac_finish_transparent(
|
||||
status = esp_sha_hash_finish(&esp_hmac_ctx->esp_sha_ctx, tmp, sizeof(tmp), &hash_size);
|
||||
}
|
||||
if (status != PSA_SUCCESS) {
|
||||
(void)esp_hmac_abort_transparent(esp_hmac_ctx);
|
||||
return status;
|
||||
}
|
||||
/* From here on, tmp needs to be wiped. */
|
||||
|
||||
/* Inner hash finished — abort it before reusing for the outer hash. */
|
||||
#if defined(ESP_MD5_DRIVER_ENABLED)
|
||||
if (hash_alg == PSA_ALG_MD5) {
|
||||
(void)esp_md5_hash_abort(&esp_hmac_ctx->md5_ctx);
|
||||
} else
|
||||
#endif // defined(ESP_MD5_DRIVER_ENABLED)
|
||||
{
|
||||
(void)esp_sha_hash_abort(&esp_hmac_ctx->esp_sha_ctx);
|
||||
}
|
||||
|
||||
#if defined(ESP_MD5_DRIVER_ENABLED)
|
||||
if (hash_alg == PSA_ALG_MD5) {
|
||||
status = esp_md5_hash_setup(&esp_hmac_ctx->md5_ctx, hash_alg);
|
||||
@@ -301,6 +343,7 @@ psa_status_t esp_hmac_finish_transparent(
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize(tmp, hash_size);
|
||||
(void)esp_hmac_abort_transparent(esp_hmac_ctx);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -357,7 +400,11 @@ psa_status_t esp_hmac_verify_finish_transparent(
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (mac_length > sizeof(actual_mac)) {
|
||||
if (esp_hmac_ctx->alg == 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
if (mac_length == 0 || mac_length > sizeof(actual_mac)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "psa_crypto_driver_esp_md5.h"
|
||||
|
||||
psa_status_t esp_md5_hash_compute(psa_algorithm_t alg,
|
||||
@@ -20,50 +21,63 @@ psa_status_t esp_md5_hash_compute(psa_algorithm_t alg,
|
||||
if (input_length > 0 && input == NULL) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (alg != PSA_ALG_MD5) {
|
||||
return PSA_ALG_IS_HASH(alg) ? PSA_ERROR_NOT_SUPPORTED
|
||||
: PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (hash_size < PSA_HASH_LENGTH(PSA_ALG_MD5)) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
if (alg != PSA_ALG_MD5) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
md5_context_t operation = {0};
|
||||
esp_rom_md5_init(&operation);
|
||||
esp_rom_md5_update(&operation, input, input_length);
|
||||
esp_rom_md5_final(hash, &operation);
|
||||
md5_context_t ctx = {0};
|
||||
esp_rom_md5_init(&ctx);
|
||||
esp_rom_md5_update(&ctx, input, input_length);
|
||||
esp_rom_md5_final(hash, &ctx);
|
||||
*hash_length = PSA_HASH_LENGTH(PSA_ALG_MD5);
|
||||
mbedtls_platform_zeroize(&ctx, sizeof(ctx));
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t esp_md5_hash_setup(md5_context_t *operation,
|
||||
psa_status_t esp_md5_hash_setup(esp_md5_hash_operation_t *operation,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
if (operation == NULL) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (alg != PSA_ALG_MD5) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
return PSA_ALG_IS_HASH(alg) ? PSA_ERROR_NOT_SUPPORTED
|
||||
: PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
esp_rom_md5_init(operation);
|
||||
if (operation->is_active) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
esp_rom_md5_init(&operation->md5_ctx);
|
||||
operation->is_active = true;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t esp_md5_hash_update(
|
||||
md5_context_t *operation,
|
||||
esp_md5_hash_operation_t *operation,
|
||||
const uint8_t *input,
|
||||
size_t input_length )
|
||||
{
|
||||
if (operation == NULL) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (input_length > 0 && input == NULL) {
|
||||
if (input == NULL && input_length != 0) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
esp_rom_md5_update(operation, input, input_length);
|
||||
if (!operation->is_active) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
if (input_length == 0) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
esp_rom_md5_update(&operation->md5_ctx, input, input_length);
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t esp_md5_hash_finish(
|
||||
md5_context_t *operation,
|
||||
esp_md5_hash_operation_t *operation,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length)
|
||||
@@ -71,31 +85,40 @@ psa_status_t esp_md5_hash_finish(
|
||||
if (operation == NULL || hash == NULL || hash_length == NULL) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (!operation->is_active) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
if (hash_size < PSA_HASH_LENGTH(PSA_ALG_MD5)) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
esp_rom_md5_final(hash, operation);
|
||||
esp_rom_md5_final(hash, &operation->md5_ctx);
|
||||
*hash_length = PSA_HASH_LENGTH(PSA_ALG_MD5);
|
||||
mbedtls_platform_zeroize(operation, sizeof(*operation));
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t esp_md5_hash_abort(md5_context_t *operation)
|
||||
psa_status_t esp_md5_hash_abort(esp_md5_hash_operation_t *operation)
|
||||
{
|
||||
if (operation == NULL) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
memset(operation, 0, sizeof(*operation));
|
||||
mbedtls_platform_zeroize(operation, sizeof(*operation));
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t esp_md5_hash_clone(
|
||||
const md5_context_t *source_operation,
|
||||
md5_context_t *target_operation)
|
||||
const esp_md5_hash_operation_t *source_operation,
|
||||
esp_md5_hash_operation_t *target_operation)
|
||||
{
|
||||
if (source_operation == NULL || target_operation == NULL) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
memcpy(target_operation, source_operation, sizeof(md5_context_t));
|
||||
if (!source_operation->is_active) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
if (target_operation->is_active) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
memcpy(target_operation, source_operation, sizeof(esp_md5_hash_operation_t));
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -82,6 +82,8 @@ psa_status_t esp_rsa_ds_pad_v21_encode(psa_algorithm_t hash_alg,
|
||||
* @param output_max_len Maximum length of the output buffer
|
||||
* @param olen Pointer to the length of the output data
|
||||
* @param hash_alg Hash algorithm identifier
|
||||
* @param label OAEP label the ciphertext is bound to (may be NULL if label_length is 0)
|
||||
* @param label_length Length of the label in bytes
|
||||
* @return psa_status_t
|
||||
* PSA_ERROR_INVALID_ARGUMENT if arguments are invalid
|
||||
* PSA_SUCCESS on success
|
||||
@@ -91,7 +93,9 @@ psa_status_t esp_rsa_ds_pad_oaep_unpad(unsigned char *input,
|
||||
unsigned char *output,
|
||||
size_t output_max_len,
|
||||
size_t *olen,
|
||||
psa_algorithm_t hash_alg);
|
||||
psa_algorithm_t hash_alg,
|
||||
const uint8_t *label,
|
||||
size_t label_length);
|
||||
#endif /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "psa_crypto_driver_esp_opaque_common.h"
|
||||
#include "include/psa_crypto_driver_esp_rsa_ds_utilities.h"
|
||||
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_assert.h"
|
||||
@@ -412,6 +413,26 @@ psa_status_t esp_rsa_ds_opaque_sign_hash_start(
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
if (PSA_ALG_IS_RSA_PSS(alg)) {
|
||||
/* PSS encode is only compiled under TLS1.3; fail up front before any
|
||||
* peripheral lock / allocation. */
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
#endif /* !defined(CONFIG_MBEDTLS_SSL_PROTO_TLS1_3) */
|
||||
|
||||
/* Cross-check the supplied hash_length against PSA_ALG_GET_HASH(alg).
|
||||
* For PKCS1V15_SIGN_RAW the hash field is opaque-length data; skip. */
|
||||
{
|
||||
psa_algorithm_t hash_alg_check = PSA_ALG_SIGN_GET_HASH(alg);
|
||||
if (hash_alg_check != PSA_ALG_NONE) {
|
||||
size_t expected = PSA_HASH_LENGTH(hash_alg_check);
|
||||
if (expected == 0 || hash_length != expected) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
esp_rsa_ds_key_source_t key_source = ESP_RSA_DS_KEY_SOURCE_EFUSE;
|
||||
uint16_t rsa_length_bits = 0;
|
||||
const esp_ds_data_t *ds_data = NULL;
|
||||
@@ -454,12 +475,21 @@ psa_status_t esp_rsa_ds_opaque_sign_hash_start(
|
||||
|
||||
unsigned char *em = heap_caps_malloc_prefer(rsa_len_bytes, 1, MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
|
||||
if (em == NULL) {
|
||||
esp_rsa_ds_release_ds_lock();
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Derive PSS salt length from the alg: -1 (MBEDTLS_RSA_SALT_LEN_ANY) for
|
||||
* PSS_ANY_SALT, else the standard FIPS 186-4 fixed length. */
|
||||
int saltlen = -1;
|
||||
if (PSA_ALG_IS_RSA_PSS(alg) && !PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
|
||||
int klen = (int) rsa_len_bytes;
|
||||
int hlen = (int) hash_length;
|
||||
int room = klen - 2 - hlen;
|
||||
saltlen = (room < 0) ? 0 : ((room > hlen) ? hlen : room);
|
||||
}
|
||||
status = esp_rsa_ds_pad(
|
||||
padding, hash_alg, hash_length, hash, -1, em, rsa_len_bytes);
|
||||
padding, hash_alg, hash_length, hash, saltlen, em, rsa_len_bytes);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
@@ -500,10 +530,13 @@ psa_status_t esp_rsa_ds_opaque_sign_hash_start(
|
||||
|
||||
error:
|
||||
if (em) {
|
||||
memset(em, 0, rsa_len_bytes);
|
||||
mbedtls_platform_zeroize(em, rsa_len_bytes);
|
||||
heap_caps_free(em);
|
||||
em = NULL;
|
||||
}
|
||||
if (status != PSA_SUCCESS) {
|
||||
esp_rsa_ds_opaque_sign_hash_abort(operation);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -530,10 +563,12 @@ psa_status_t esp_rsa_ds_opaque_sign_hash_complete(
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
psa_status_t status;
|
||||
esp_err_t err = esp_ds_finish_sign((void *)operation->sig_buffer, operation->esp_rsa_ds_ctx);
|
||||
operation->esp_rsa_ds_ctx = NULL;
|
||||
if (err != ESP_OK) {
|
||||
return PSA_ERROR_GENERIC_ERROR;
|
||||
status = PSA_ERROR_GENERIC_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
unsigned int words_len = expected_signature_size / 4;
|
||||
@@ -544,16 +579,11 @@ psa_status_t esp_rsa_ds_opaque_sign_hash_complete(
|
||||
}
|
||||
|
||||
*signature_length = expected_signature_size;
|
||||
status = PSA_SUCCESS;
|
||||
|
||||
esp_rsa_ds_release_ds_lock();
|
||||
|
||||
if (operation->sig_buffer) {
|
||||
memset(operation->sig_buffer, 0, operation->sig_buffer_size);
|
||||
heap_caps_free(operation->sig_buffer);
|
||||
operation->sig_buffer = NULL;
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
cleanup:
|
||||
(void)esp_rsa_ds_opaque_sign_hash_abort(operation);
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t esp_rsa_ds_opaque_sign_hash_abort(
|
||||
@@ -583,7 +613,7 @@ psa_status_t esp_rsa_ds_opaque_sign_hash_abort(
|
||||
|
||||
// Free allocated memory if exists
|
||||
if (operation->sig_buffer) {
|
||||
memset(operation->sig_buffer, 0, operation->sig_buffer_size);
|
||||
mbedtls_platform_zeroize(operation->sig_buffer, operation->sig_buffer_size);
|
||||
heap_caps_free(operation->sig_buffer);
|
||||
operation->sig_buffer = NULL;
|
||||
}
|
||||
@@ -592,7 +622,7 @@ psa_status_t esp_rsa_ds_opaque_sign_hash_abort(
|
||||
esp_rsa_ds_release_ds_lock();
|
||||
|
||||
// Clear the operation structure
|
||||
memset(operation, 0, sizeof(esp_rsa_ds_opaque_sign_hash_operation_t));
|
||||
mbedtls_platform_zeroize(operation, sizeof(esp_rsa_ds_opaque_sign_hash_operation_t));
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
@@ -620,7 +650,6 @@ psa_status_t esp_rsa_ds_opaque_signature_sign_hash(
|
||||
hash_length
|
||||
);
|
||||
if (status != PSA_SUCCESS) {
|
||||
esp_rsa_ds_opaque_sign_hash_abort(&operation);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -764,10 +793,17 @@ psa_status_t esp_rsa_ds_opaque_asymmetric_decrypt(
|
||||
size_t input_length, const uint8_t *salt, size_t salt_length,
|
||||
uint8_t *output, size_t output_size, size_t *output_length)
|
||||
{
|
||||
(void)salt;
|
||||
(void)salt_length;
|
||||
|
||||
psa_status_t ret = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
esp_err_t err = ESP_FAIL;
|
||||
uint32_t *em_words = NULL;
|
||||
uint32_t *out_tmp = NULL;
|
||||
size_t data_len = 0;
|
||||
bool lock_held = false;
|
||||
esp_ds_context_t *ds_ctx = NULL;
|
||||
#if SOC_KEY_MANAGER_SUPPORTED
|
||||
bool is_km_key_active = false;
|
||||
esp_key_mgr_key_recovery_info_t *km_ri = NULL;
|
||||
#endif /* SOC_KEY_MANAGER_SUPPORTED */
|
||||
|
||||
if (!attributes || !key || !input || input_length < 1 || !output || !output_length) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
@@ -777,25 +813,37 @@ psa_status_t esp_rsa_ds_opaque_asymmetric_decrypt(
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* Decrypt requires a private key. The PSA core enforces this via key
|
||||
* usage, but check the type here as defense-in-depth. */
|
||||
if (!PSA_KEY_TYPE_IS_RSA(psa_get_key_type(attributes)) ||
|
||||
!PSA_KEY_TYPE_IS_KEY_PAIR(psa_get_key_type(attributes))) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* PKCS1V15_CRYPT has no label; reject any non-empty salt. */
|
||||
if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT && salt_length != 0) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (salt == NULL && salt_length != 0) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
bool is_persistent = esp_opaque_key_is_persistent(attributes);
|
||||
|
||||
esp_rsa_ds_key_source_t key_source = ESP_RSA_DS_KEY_SOURCE_EFUSE;
|
||||
uint16_t rsa_length_bits = 0;
|
||||
const esp_ds_data_t *ds_data = NULL;
|
||||
hmac_key_id_t hmac_key_id = 0;
|
||||
#if SOC_KEY_MANAGER_SUPPORTED
|
||||
esp_key_mgr_key_recovery_info_t *km_ri = NULL;
|
||||
#endif /* SOC_KEY_MANAGER_SUPPORTED */
|
||||
|
||||
psa_status_t status = esp_rsa_ds_extract_storage(
|
||||
ret = esp_rsa_ds_extract_storage(
|
||||
key, key_length, is_persistent,
|
||||
&key_source, &rsa_length_bits, &ds_data, &hmac_key_id
|
||||
#if SOC_KEY_MANAGER_SUPPORTED
|
||||
, &km_ri
|
||||
#endif /* SOC_KEY_MANAGER_SUPPORTED */
|
||||
);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
if (ret != PSA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (input_length != (rsa_length_bits / 8)) {
|
||||
@@ -812,13 +860,14 @@ psa_status_t esp_rsa_ds_opaque_asymmetric_decrypt(
|
||||
if (xSemaphoreTake(s_ds_lock, s_timeout_ms / portTICK_PERIOD_MS) != pdTRUE) {
|
||||
return PSA_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
lock_held = true;
|
||||
|
||||
size_t ilen = rsa_length_bits / 8;
|
||||
size_t data_len = ilen / 4;
|
||||
uint32_t *em_words = heap_caps_malloc_prefer(sizeof(uint32_t) * data_len, 1, MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
|
||||
data_len = ilen / 4;
|
||||
em_words = heap_caps_malloc_prefer(sizeof(uint32_t) * data_len, 1, MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
|
||||
if (em_words == NULL) {
|
||||
esp_rsa_ds_release_ds_lock();
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
ret = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < (data_len); i++) {
|
||||
@@ -826,60 +875,38 @@ psa_status_t esp_rsa_ds_opaque_asymmetric_decrypt(
|
||||
}
|
||||
|
||||
#if SOC_KEY_MANAGER_SUPPORTED
|
||||
bool is_km_key_active = false;
|
||||
if (key_source == ESP_RSA_DS_KEY_SOURCE_KEY_MGR) {
|
||||
err = esp_key_mgr_activate_key(km_ri);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to activate key: 0x%x", err);
|
||||
memset(em_words, 0, sizeof(uint32_t) * data_len);
|
||||
heap_caps_free(em_words);
|
||||
esp_rsa_ds_release_ds_lock();
|
||||
return PSA_ERROR_INVALID_HANDLE;
|
||||
ret = PSA_ERROR_INVALID_HANDLE;
|
||||
goto exit;
|
||||
}
|
||||
is_km_key_active = true;
|
||||
}
|
||||
#endif /* SOC_KEY_MANAGER_SUPPORTED */
|
||||
|
||||
esp_ds_context_t *ds_ctx = NULL;
|
||||
err = esp_ds_start_sign((const void *)em_words,
|
||||
ds_data,
|
||||
hmac_key_id,
|
||||
&ds_ctx);
|
||||
if (err != ESP_OK) {
|
||||
memset(em_words, 0, sizeof(uint32_t) * data_len);
|
||||
heap_caps_free(em_words);
|
||||
#if SOC_KEY_MANAGER_SUPPORTED
|
||||
if (is_km_key_active) {
|
||||
esp_key_mgr_deactivate_key(km_ri->key_type);
|
||||
}
|
||||
#endif /* SOC_KEY_MANAGER_SUPPORTED */
|
||||
esp_rsa_ds_release_ds_lock();
|
||||
return PSA_ERROR_GENERIC_ERROR;
|
||||
ret = PSA_ERROR_GENERIC_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
err = esp_ds_finish_sign((void *)em_words, ds_ctx);
|
||||
|
||||
#if SOC_KEY_MANAGER_SUPPORTED
|
||||
if (is_km_key_active) {
|
||||
esp_key_mgr_deactivate_key(km_ri->key_type);
|
||||
}
|
||||
#endif /* SOC_KEY_MANAGER_SUPPORTED */
|
||||
|
||||
ds_ctx = NULL;
|
||||
if (err != ESP_OK) {
|
||||
memset(em_words, 0, sizeof(uint32_t) * data_len);
|
||||
heap_caps_free(em_words);
|
||||
esp_rsa_ds_release_ds_lock();
|
||||
return PSA_ERROR_GENERIC_ERROR;
|
||||
ret = PSA_ERROR_GENERIC_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
esp_rsa_ds_release_ds_lock();
|
||||
|
||||
// Remove padding
|
||||
uint32_t *out_tmp = heap_caps_malloc_prefer(sizeof(uint32_t) * data_len, 1, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
|
||||
out_tmp = heap_caps_malloc_prefer(sizeof(uint32_t) * data_len, 1, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
|
||||
if (out_tmp == NULL) {
|
||||
memset(em_words, 0, sizeof(uint32_t) * data_len);
|
||||
heap_caps_free(em_words);
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
ret = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < (data_len); i++) {
|
||||
@@ -887,13 +914,12 @@ psa_status_t esp_rsa_ds_opaque_asymmetric_decrypt(
|
||||
}
|
||||
|
||||
size_t unpadded_len = 0;
|
||||
psa_status_t ret = PSA_ERROR_NOT_SUPPORTED;
|
||||
if (padding == ESP_RSA_DS_PADDING_PKCS_V15) {
|
||||
ret = esp_rsa_ds_pad_v15_unpad((unsigned char *)out_tmp, ilen, (unsigned char *)out_tmp, ilen, &unpadded_len);
|
||||
}
|
||||
#if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3
|
||||
else if (padding == ESP_RSA_DS_PADDING_OAEP) {
|
||||
ret = esp_rsa_ds_pad_oaep_unpad((unsigned char *)out_tmp, ilen, (unsigned char *)out_tmp, ilen, &unpadded_len, PSA_ALG_RSA_OAEP_GET_HASH(alg));
|
||||
ret = esp_rsa_ds_pad_oaep_unpad((unsigned char *)out_tmp, ilen, (unsigned char *)out_tmp, ilen, &unpadded_len, PSA_ALG_RSA_OAEP_GET_HASH(alg), salt, salt_length);
|
||||
}
|
||||
#endif /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
else {
|
||||
@@ -916,9 +942,21 @@ psa_status_t esp_rsa_ds_opaque_asymmetric_decrypt(
|
||||
ret = PSA_SUCCESS;
|
||||
|
||||
exit:
|
||||
memset(em_words, 0, sizeof(uint32_t) * data_len);
|
||||
memset(out_tmp, 0, sizeof(uint32_t) * data_len);
|
||||
heap_caps_free(em_words);
|
||||
heap_caps_free(out_tmp);
|
||||
#if SOC_KEY_MANAGER_SUPPORTED
|
||||
if (is_km_key_active && km_ri) {
|
||||
esp_key_mgr_deactivate_key(km_ri->key_type);
|
||||
}
|
||||
#endif /* SOC_KEY_MANAGER_SUPPORTED */
|
||||
if (em_words != NULL) {
|
||||
mbedtls_platform_zeroize(em_words, sizeof(uint32_t) * data_len);
|
||||
heap_caps_free(em_words);
|
||||
}
|
||||
if (out_tmp != NULL) {
|
||||
mbedtls_platform_zeroize(out_tmp, sizeof(uint32_t) * data_len);
|
||||
heap_caps_free(out_tmp);
|
||||
}
|
||||
if (lock_held) {
|
||||
esp_rsa_ds_release_ds_lock();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -43,13 +43,13 @@ static const oid_md_mapping_t oid_md_table[] = {
|
||||
{ PSA_ALG_NONE, NULL, 0 }
|
||||
};
|
||||
|
||||
static int esp_rsa_ds_get_oid_by_psa_alg(psa_algorithm_t md_alg, const char **oid, size_t *olen)
|
||||
static psa_status_t esp_rsa_ds_get_oid_by_psa_alg(psa_algorithm_t md_alg, const char **oid, size_t *olen)
|
||||
{
|
||||
for (size_t i = 0; oid_md_table[i].md_alg != PSA_ALG_NONE; i++) {
|
||||
if (oid_md_table[i].md_alg == md_alg) {
|
||||
*oid = oid_md_table[i].oid;
|
||||
*olen = oid_md_table[i].oid_len;
|
||||
return 0;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
}
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
@@ -379,14 +379,20 @@ psa_status_t esp_rsa_ds_pad_v21_encode(psa_algorithm_t hash_alg,
|
||||
|
||||
hlen = PSA_HASH_LENGTH(hash_alg);
|
||||
|
||||
/* Reject hash-less or unknown algorithms up front: hlen == 0 would
|
||||
* underflow min_slen below and wrap the olen bounds checks. */
|
||||
if (hlen == 0 || hlen > PSA_HASH_MAX_SIZE) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (saltlen == -1) {
|
||||
/* Calculate the largest possible salt length, up to the hash size.
|
||||
* Normally this is the hash length, which is the maximum salt length
|
||||
* according to FIPS 185-4 <EFBFBD>5.5 (e) and common practice. If there is not
|
||||
* according to FIPS 186-4 Section 5.5 (e) and common practice. If there is not
|
||||
* enough room, use the maximum salt length that fits. The constraint is
|
||||
* that the hash length plus the salt length plus 2 bytes must be at most
|
||||
* the key length. This complies with FIPS 186-4 <EFBFBD>5.5 (e) and RFC 8017
|
||||
* (PKCS#1 v2.2) <EFBFBD>9.1.1 step 3. */
|
||||
* the key length. This complies with FIPS 186-4 Section 5.5 (e) and RFC 8017
|
||||
* (PKCS#1 v2.2) Section 9.1.1 step 3. */
|
||||
min_slen = hlen - 2;
|
||||
if (olen < hlen + min_slen + 2) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
@@ -432,7 +438,6 @@ psa_status_t esp_rsa_ds_pad_v21_encode(psa_algorithm_t hash_alg,
|
||||
return ret;
|
||||
}
|
||||
|
||||
msb = dst_len * 8 - 1;
|
||||
sig[0] &= 0xFF >> (olen * 8 - msb);
|
||||
|
||||
p += hlen;
|
||||
@@ -445,7 +450,9 @@ psa_status_t esp_rsa_ds_pad_oaep_unpad(unsigned char *input,
|
||||
unsigned char *output,
|
||||
size_t output_max_len,
|
||||
size_t *olen,
|
||||
psa_algorithm_t hash_alg)
|
||||
psa_algorithm_t hash_alg,
|
||||
const uint8_t *label,
|
||||
size_t label_length)
|
||||
{
|
||||
/* This mirrors mbedtls_rsa_rsaes_oaep_decrypt() in upstream rsa.c.
|
||||
* Below the public-input sanity check, the unpadding scan operates
|
||||
@@ -512,6 +519,7 @@ psa_status_t esp_rsa_ds_pad_oaep_unpad(unsigned char *input,
|
||||
/* Single decision point on the accumulated bit. */
|
||||
if (bad != MBEDTLS_CT_FALSE) {
|
||||
*olen = 0;
|
||||
mbedtls_platform_zeroize(input, ilen);
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,12 +5,13 @@
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "mbedtls/esp_config.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "psa_crypto_driver_esp_sha.h"
|
||||
#include "../include/psa_crypto_driver_esp_sha1.h"
|
||||
#include "esp_sha_internal.h"
|
||||
@@ -368,21 +369,25 @@ psa_status_t esp_sha1_driver_compute(
|
||||
|
||||
int ret = esp_sha1_starts(ctx);
|
||||
if (ret != ESP_OK) {
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
goto hw_fail;
|
||||
}
|
||||
|
||||
ret = esp_sha1_update(ctx, input, input_length);
|
||||
if (ret != ESP_OK) {
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
goto hw_fail;
|
||||
}
|
||||
|
||||
ret = esp_sha1_finish(ctx, hash);
|
||||
if (ret != ESP_OK) {
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
goto hw_fail;
|
||||
}
|
||||
|
||||
*hash_length = PSA_HASH_LENGTH(PSA_ALG_SHA_1);
|
||||
return PSA_SUCCESS;
|
||||
|
||||
hw_fail:
|
||||
mbedtls_platform_zeroize(ctx, sizeof(*ctx));
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
}
|
||||
|
||||
psa_status_t esp_sha1_driver_update(
|
||||
@@ -426,7 +431,7 @@ psa_status_t esp_sha1_driver_abort(esp_sha1_context *ctx)
|
||||
if (!ctx) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
memset(ctx, 0, sizeof(esp_sha1_context));
|
||||
mbedtls_platform_zeroize(ctx, sizeof(esp_sha1_context));
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,12 +5,13 @@
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "mbedtls/esp_config.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "psa_crypto_driver_esp_sha.h"
|
||||
#include "../include/psa_crypto_driver_esp_sha256.h"
|
||||
#include "esp_sha_internal.h"
|
||||
@@ -190,20 +191,24 @@ psa_status_t esp_sha256_driver_compute(
|
||||
#endif // SOC_SHA_SUPPORT_SHA224
|
||||
int ret = esp_sha256_starts(ctx, mode);
|
||||
if (ret != ESP_OK) {
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
goto hw_fail;
|
||||
}
|
||||
|
||||
ret = esp_sha256_update(ctx, input, input_length);
|
||||
if (ret != ESP_OK) {
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
goto hw_fail;
|
||||
}
|
||||
|
||||
ret = esp_sha256_finish(ctx, hash);
|
||||
if (ret != ESP_OK) {
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
goto hw_fail;
|
||||
}
|
||||
*hash_length = PSA_HASH_LENGTH(alg);
|
||||
return PSA_SUCCESS;
|
||||
|
||||
hw_fail:
|
||||
mbedtls_platform_zeroize(ctx, sizeof(*ctx));
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
}
|
||||
|
||||
psa_status_t esp_sha256_driver_update(
|
||||
@@ -260,7 +265,7 @@ psa_status_t esp_sha256_driver_abort(esp_sha256_context *ctx)
|
||||
if (!ctx) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
memset(ctx, 0, sizeof(esp_sha256_context));
|
||||
mbedtls_platform_zeroize(ctx, sizeof(esp_sha256_context));
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,12 +5,13 @@
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "mbedtls/esp_config.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "psa_crypto_driver_esp_sha.h"
|
||||
#include "../include/psa_crypto_driver_esp_sha512.h"
|
||||
#include "esp_sha_internal.h"
|
||||
@@ -219,20 +220,24 @@ psa_status_t esp_sha512_driver_compute(
|
||||
#endif // SOC_SHA_SUPPORT_SHA384
|
||||
int ret = esp_sha512_starts(ctx, mode);
|
||||
if (ret != ESP_OK) {
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
goto hw_fail;
|
||||
}
|
||||
|
||||
ret = esp_sha512_update(ctx, input, input_length);
|
||||
if (ret != ESP_OK) {
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
goto hw_fail;
|
||||
}
|
||||
|
||||
ret = esp_sha512_finish(ctx, hash);
|
||||
if (ret != ESP_OK) {
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
goto hw_fail;
|
||||
}
|
||||
*hash_length = PSA_HASH_LENGTH(alg);
|
||||
return PSA_SUCCESS;
|
||||
|
||||
hw_fail:
|
||||
mbedtls_platform_zeroize(ctx, sizeof(*ctx));
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
}
|
||||
|
||||
psa_status_t esp_sha512_driver_update(
|
||||
@@ -286,7 +291,7 @@ psa_status_t esp_sha512_driver_abort(esp_sha512_context *ctx)
|
||||
if (!ctx) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
memset(ctx, 0, sizeof(esp_sha512_context));
|
||||
mbedtls_platform_zeroize(ctx, sizeof(esp_sha512_context));
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "../include/psa_crypto_driver_esp_sha1.h"
|
||||
#include "sha/sha_parallel_engine.h"
|
||||
#include "esp_err.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#ifndef GET_UINT32_BE
|
||||
#define GET_UINT32_BE(n,b,i) \
|
||||
@@ -77,32 +78,34 @@ int esp_sha1_starts(esp_sha1_context *ctx)
|
||||
|
||||
static void esp_sha1_software_process( esp_sha1_context *ctx, const unsigned char data[64] )
|
||||
{
|
||||
uint32_t temp, W[16], A, B, C, D, E;
|
||||
struct {
|
||||
uint32_t temp, W[16], A, B, C, D, E;
|
||||
} local;
|
||||
|
||||
GET_UINT32_BE( W[ 0], data, 0 );
|
||||
GET_UINT32_BE( W[ 1], data, 4 );
|
||||
GET_UINT32_BE( W[ 2], data, 8 );
|
||||
GET_UINT32_BE( W[ 3], data, 12 );
|
||||
GET_UINT32_BE( W[ 4], data, 16 );
|
||||
GET_UINT32_BE( W[ 5], data, 20 );
|
||||
GET_UINT32_BE( W[ 6], data, 24 );
|
||||
GET_UINT32_BE( W[ 7], data, 28 );
|
||||
GET_UINT32_BE( W[ 8], data, 32 );
|
||||
GET_UINT32_BE( W[ 9], data, 36 );
|
||||
GET_UINT32_BE( W[10], data, 40 );
|
||||
GET_UINT32_BE( W[11], data, 44 );
|
||||
GET_UINT32_BE( W[12], data, 48 );
|
||||
GET_UINT32_BE( W[13], data, 52 );
|
||||
GET_UINT32_BE( W[14], data, 56 );
|
||||
GET_UINT32_BE( W[15], data, 60 );
|
||||
GET_UINT32_BE( local.W[ 0], data, 0 );
|
||||
GET_UINT32_BE( local.W[ 1], data, 4 );
|
||||
GET_UINT32_BE( local.W[ 2], data, 8 );
|
||||
GET_UINT32_BE( local.W[ 3], data, 12 );
|
||||
GET_UINT32_BE( local.W[ 4], data, 16 );
|
||||
GET_UINT32_BE( local.W[ 5], data, 20 );
|
||||
GET_UINT32_BE( local.W[ 6], data, 24 );
|
||||
GET_UINT32_BE( local.W[ 7], data, 28 );
|
||||
GET_UINT32_BE( local.W[ 8], data, 32 );
|
||||
GET_UINT32_BE( local.W[ 9], data, 36 );
|
||||
GET_UINT32_BE( local.W[10], data, 40 );
|
||||
GET_UINT32_BE( local.W[11], data, 44 );
|
||||
GET_UINT32_BE( local.W[12], data, 48 );
|
||||
GET_UINT32_BE( local.W[13], data, 52 );
|
||||
GET_UINT32_BE( local.W[14], data, 56 );
|
||||
GET_UINT32_BE( local.W[15], data, 60 );
|
||||
|
||||
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
|
||||
|
||||
#define R(t) \
|
||||
( \
|
||||
temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \
|
||||
W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \
|
||||
( W[t & 0x0F] = S(temp,1) ) \
|
||||
local.temp = local.W[( t - 3 ) & 0x0F] ^ local.W[( t - 8 ) & 0x0F] ^ \
|
||||
local.W[( t - 14 ) & 0x0F] ^ local.W[ t & 0x0F], \
|
||||
( local.W[t & 0x0F] = S(local.temp,1) ) \
|
||||
)
|
||||
|
||||
#define P(a,b,c,d,e,x) \
|
||||
@@ -110,35 +113,35 @@ static void esp_sha1_software_process( esp_sha1_context *ctx, const unsigned cha
|
||||
e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
|
||||
}
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
E = ctx->state[4];
|
||||
local.A = ctx->state[0];
|
||||
local.B = ctx->state[1];
|
||||
local.C = ctx->state[2];
|
||||
local.D = ctx->state[3];
|
||||
local.E = ctx->state[4];
|
||||
|
||||
#define F(x,y,z) (z ^ (x & (y ^ z)))
|
||||
#define K 0x5A827999
|
||||
|
||||
P( A, B, C, D, E, W[0] );
|
||||
P( E, A, B, C, D, W[1] );
|
||||
P( D, E, A, B, C, W[2] );
|
||||
P( C, D, E, A, B, W[3] );
|
||||
P( B, C, D, E, A, W[4] );
|
||||
P( A, B, C, D, E, W[5] );
|
||||
P( E, A, B, C, D, W[6] );
|
||||
P( D, E, A, B, C, W[7] );
|
||||
P( C, D, E, A, B, W[8] );
|
||||
P( B, C, D, E, A, W[9] );
|
||||
P( A, B, C, D, E, W[10] );
|
||||
P( E, A, B, C, D, W[11] );
|
||||
P( D, E, A, B, C, W[12] );
|
||||
P( C, D, E, A, B, W[13] );
|
||||
P( B, C, D, E, A, W[14] );
|
||||
P( A, B, C, D, E, W[15] );
|
||||
P( E, A, B, C, D, R(16) );
|
||||
P( D, E, A, B, C, R(17) );
|
||||
P( C, D, E, A, B, R(18) );
|
||||
P( B, C, D, E, A, R(19) );
|
||||
P( local.A, local.B, local.C, local.D, local.E, local.W[0] );
|
||||
P( local.E, local.A, local.B, local.C, local.D, local.W[1] );
|
||||
P( local.D, local.E, local.A, local.B, local.C, local.W[2] );
|
||||
P( local.C, local.D, local.E, local.A, local.B, local.W[3] );
|
||||
P( local.B, local.C, local.D, local.E, local.A, local.W[4] );
|
||||
P( local.A, local.B, local.C, local.D, local.E, local.W[5] );
|
||||
P( local.E, local.A, local.B, local.C, local.D, local.W[6] );
|
||||
P( local.D, local.E, local.A, local.B, local.C, local.W[7] );
|
||||
P( local.C, local.D, local.E, local.A, local.B, local.W[8] );
|
||||
P( local.B, local.C, local.D, local.E, local.A, local.W[9] );
|
||||
P( local.A, local.B, local.C, local.D, local.E, local.W[10] );
|
||||
P( local.E, local.A, local.B, local.C, local.D, local.W[11] );
|
||||
P( local.D, local.E, local.A, local.B, local.C, local.W[12] );
|
||||
P( local.C, local.D, local.E, local.A, local.B, local.W[13] );
|
||||
P( local.B, local.C, local.D, local.E, local.A, local.W[14] );
|
||||
P( local.A, local.B, local.C, local.D, local.E, local.W[15] );
|
||||
P( local.E, local.A, local.B, local.C, local.D, R(16) );
|
||||
P( local.D, local.E, local.A, local.B, local.C, R(17) );
|
||||
P( local.C, local.D, local.E, local.A, local.B, R(18) );
|
||||
P( local.B, local.C, local.D, local.E, local.A, R(19) );
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
@@ -146,26 +149,26 @@ static void esp_sha1_software_process( esp_sha1_context *ctx, const unsigned cha
|
||||
#define F(x,y,z) (x ^ y ^ z)
|
||||
#define K 0x6ED9EBA1
|
||||
|
||||
P( A, B, C, D, E, R(20) );
|
||||
P( E, A, B, C, D, R(21) );
|
||||
P( D, E, A, B, C, R(22) );
|
||||
P( C, D, E, A, B, R(23) );
|
||||
P( B, C, D, E, A, R(24) );
|
||||
P( A, B, C, D, E, R(25) );
|
||||
P( E, A, B, C, D, R(26) );
|
||||
P( D, E, A, B, C, R(27) );
|
||||
P( C, D, E, A, B, R(28) );
|
||||
P( B, C, D, E, A, R(29) );
|
||||
P( A, B, C, D, E, R(30) );
|
||||
P( E, A, B, C, D, R(31) );
|
||||
P( D, E, A, B, C, R(32) );
|
||||
P( C, D, E, A, B, R(33) );
|
||||
P( B, C, D, E, A, R(34) );
|
||||
P( A, B, C, D, E, R(35) );
|
||||
P( E, A, B, C, D, R(36) );
|
||||
P( D, E, A, B, C, R(37) );
|
||||
P( C, D, E, A, B, R(38) );
|
||||
P( B, C, D, E, A, R(39) );
|
||||
P( local.A, local.B, local.C, local.D, local.E, R(20) );
|
||||
P( local.E, local.A, local.B, local.C, local.D, R(21) );
|
||||
P( local.D, local.E, local.A, local.B, local.C, R(22) );
|
||||
P( local.C, local.D, local.E, local.A, local.B, R(23) );
|
||||
P( local.B, local.C, local.D, local.E, local.A, R(24) );
|
||||
P( local.A, local.B, local.C, local.D, local.E, R(25) );
|
||||
P( local.E, local.A, local.B, local.C, local.D, R(26) );
|
||||
P( local.D, local.E, local.A, local.B, local.C, R(27) );
|
||||
P( local.C, local.D, local.E, local.A, local.B, R(28) );
|
||||
P( local.B, local.C, local.D, local.E, local.A, R(29) );
|
||||
P( local.A, local.B, local.C, local.D, local.E, R(30) );
|
||||
P( local.E, local.A, local.B, local.C, local.D, R(31) );
|
||||
P( local.D, local.E, local.A, local.B, local.C, R(32) );
|
||||
P( local.C, local.D, local.E, local.A, local.B, R(33) );
|
||||
P( local.B, local.C, local.D, local.E, local.A, R(34) );
|
||||
P( local.A, local.B, local.C, local.D, local.E, R(35) );
|
||||
P( local.E, local.A, local.B, local.C, local.D, R(36) );
|
||||
P( local.D, local.E, local.A, local.B, local.C, R(37) );
|
||||
P( local.C, local.D, local.E, local.A, local.B, R(38) );
|
||||
P( local.B, local.C, local.D, local.E, local.A, R(39) );
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
@@ -173,26 +176,26 @@ static void esp_sha1_software_process( esp_sha1_context *ctx, const unsigned cha
|
||||
#define F(x,y,z) ((x & y) | (z & (x | y)))
|
||||
#define K 0x8F1BBCDC
|
||||
|
||||
P( A, B, C, D, E, R(40) );
|
||||
P( E, A, B, C, D, R(41) );
|
||||
P( D, E, A, B, C, R(42) );
|
||||
P( C, D, E, A, B, R(43) );
|
||||
P( B, C, D, E, A, R(44) );
|
||||
P( A, B, C, D, E, R(45) );
|
||||
P( E, A, B, C, D, R(46) );
|
||||
P( D, E, A, B, C, R(47) );
|
||||
P( C, D, E, A, B, R(48) );
|
||||
P( B, C, D, E, A, R(49) );
|
||||
P( A, B, C, D, E, R(50) );
|
||||
P( E, A, B, C, D, R(51) );
|
||||
P( D, E, A, B, C, R(52) );
|
||||
P( C, D, E, A, B, R(53) );
|
||||
P( B, C, D, E, A, R(54) );
|
||||
P( A, B, C, D, E, R(55) );
|
||||
P( E, A, B, C, D, R(56) );
|
||||
P( D, E, A, B, C, R(57) );
|
||||
P( C, D, E, A, B, R(58) );
|
||||
P( B, C, D, E, A, R(59) );
|
||||
P( local.A, local.B, local.C, local.D, local.E, R(40) );
|
||||
P( local.E, local.A, local.B, local.C, local.D, R(41) );
|
||||
P( local.D, local.E, local.A, local.B, local.C, R(42) );
|
||||
P( local.C, local.D, local.E, local.A, local.B, R(43) );
|
||||
P( local.B, local.C, local.D, local.E, local.A, R(44) );
|
||||
P( local.A, local.B, local.C, local.D, local.E, R(45) );
|
||||
P( local.E, local.A, local.B, local.C, local.D, R(46) );
|
||||
P( local.D, local.E, local.A, local.B, local.C, R(47) );
|
||||
P( local.C, local.D, local.E, local.A, local.B, R(48) );
|
||||
P( local.B, local.C, local.D, local.E, local.A, R(49) );
|
||||
P( local.A, local.B, local.C, local.D, local.E, R(50) );
|
||||
P( local.E, local.A, local.B, local.C, local.D, R(51) );
|
||||
P( local.D, local.E, local.A, local.B, local.C, R(52) );
|
||||
P( local.C, local.D, local.E, local.A, local.B, R(53) );
|
||||
P( local.B, local.C, local.D, local.E, local.A, R(54) );
|
||||
P( local.A, local.B, local.C, local.D, local.E, R(55) );
|
||||
P( local.E, local.A, local.B, local.C, local.D, R(56) );
|
||||
P( local.D, local.E, local.A, local.B, local.C, R(57) );
|
||||
P( local.C, local.D, local.E, local.A, local.B, R(58) );
|
||||
P( local.B, local.C, local.D, local.E, local.A, R(59) );
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
@@ -200,35 +203,38 @@ static void esp_sha1_software_process( esp_sha1_context *ctx, const unsigned cha
|
||||
#define F(x,y,z) (x ^ y ^ z)
|
||||
#define K 0xCA62C1D6
|
||||
|
||||
P( A, B, C, D, E, R(60) );
|
||||
P( E, A, B, C, D, R(61) );
|
||||
P( D, E, A, B, C, R(62) );
|
||||
P( C, D, E, A, B, R(63) );
|
||||
P( B, C, D, E, A, R(64) );
|
||||
P( A, B, C, D, E, R(65) );
|
||||
P( E, A, B, C, D, R(66) );
|
||||
P( D, E, A, B, C, R(67) );
|
||||
P( C, D, E, A, B, R(68) );
|
||||
P( B, C, D, E, A, R(69) );
|
||||
P( A, B, C, D, E, R(70) );
|
||||
P( E, A, B, C, D, R(71) );
|
||||
P( D, E, A, B, C, R(72) );
|
||||
P( C, D, E, A, B, R(73) );
|
||||
P( B, C, D, E, A, R(74) );
|
||||
P( A, B, C, D, E, R(75) );
|
||||
P( E, A, B, C, D, R(76) );
|
||||
P( D, E, A, B, C, R(77) );
|
||||
P( C, D, E, A, B, R(78) );
|
||||
P( B, C, D, E, A, R(79) );
|
||||
P( local.A, local.B, local.C, local.D, local.E, R(60) );
|
||||
P( local.E, local.A, local.B, local.C, local.D, R(61) );
|
||||
P( local.D, local.E, local.A, local.B, local.C, R(62) );
|
||||
P( local.C, local.D, local.E, local.A, local.B, R(63) );
|
||||
P( local.B, local.C, local.D, local.E, local.A, R(64) );
|
||||
P( local.A, local.B, local.C, local.D, local.E, R(65) );
|
||||
P( local.E, local.A, local.B, local.C, local.D, R(66) );
|
||||
P( local.D, local.E, local.A, local.B, local.C, R(67) );
|
||||
P( local.C, local.D, local.E, local.A, local.B, R(68) );
|
||||
P( local.B, local.C, local.D, local.E, local.A, R(69) );
|
||||
P( local.A, local.B, local.C, local.D, local.E, R(70) );
|
||||
P( local.E, local.A, local.B, local.C, local.D, R(71) );
|
||||
P( local.D, local.E, local.A, local.B, local.C, R(72) );
|
||||
P( local.C, local.D, local.E, local.A, local.B, R(73) );
|
||||
P( local.B, local.C, local.D, local.E, local.A, R(74) );
|
||||
P( local.A, local.B, local.C, local.D, local.E, R(75) );
|
||||
P( local.E, local.A, local.B, local.C, local.D, R(76) );
|
||||
P( local.D, local.E, local.A, local.B, local.C, R(77) );
|
||||
P( local.C, local.D, local.E, local.A, local.B, R(78) );
|
||||
P( local.B, local.C, local.D, local.E, local.A, R(79) );
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
ctx->state[4] += E;
|
||||
ctx->state[0] += local.A;
|
||||
ctx->state[1] += local.B;
|
||||
ctx->state[2] += local.C;
|
||||
ctx->state[3] += local.D;
|
||||
ctx->state[4] += local.E;
|
||||
|
||||
/* Zeroise buffers and variables to clear sensitive data from memory. */
|
||||
mbedtls_platform_zeroize(&local, sizeof(local));
|
||||
}
|
||||
|
||||
static int esp_internal_sha1_parallel_engine_process( esp_sha1_context *ctx, const unsigned char data[64], bool read_digest )
|
||||
@@ -409,6 +415,8 @@ psa_status_t esp_sha1_driver_finish(
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t esp_sha1_driver_abort(esp_sha1_context *ctx);
|
||||
|
||||
psa_status_t esp_sha1_driver_compute(
|
||||
esp_sha1_context *ctx,
|
||||
const uint8_t *input,
|
||||
@@ -423,21 +431,25 @@ psa_status_t esp_sha1_driver_compute(
|
||||
|
||||
int ret = esp_sha1_starts(ctx);
|
||||
if (ret != ESP_OK) {
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
goto hw_fail;
|
||||
}
|
||||
|
||||
ret = esp_sha1_update(ctx, input, input_length);
|
||||
if (ret != ESP_OK) {
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
goto hw_fail;
|
||||
}
|
||||
|
||||
ret = esp_sha1_finish(ctx, hash);
|
||||
if (ret != ESP_OK) {
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
goto hw_fail;
|
||||
}
|
||||
|
||||
*hash_length = PSA_HASH_LENGTH(PSA_ALG_SHA_1);
|
||||
return PSA_SUCCESS;
|
||||
|
||||
hw_fail:
|
||||
esp_sha1_driver_abort(ctx);
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
}
|
||||
|
||||
psa_status_t esp_sha1_driver_abort(esp_sha1_context *ctx)
|
||||
@@ -452,6 +464,6 @@ psa_status_t esp_sha1_driver_abort(esp_sha1_context *ctx)
|
||||
ctx->operation_mode = ESP_SHA_MODE_SOFTWARE;
|
||||
}
|
||||
#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_1
|
||||
memset(ctx, 0, sizeof(esp_sha1_context));
|
||||
mbedtls_platform_zeroize(ctx, sizeof(esp_sha1_context));
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "sha/sha_parallel_engine.h"
|
||||
#include "esp_err.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (big endian)
|
||||
@@ -122,71 +123,76 @@ static const uint32_t K[] = {
|
||||
|
||||
#define R(t) \
|
||||
( \
|
||||
W[t] = S1(W[t - 2]) + W[t - 7] + \
|
||||
S0(W[t - 15]) + W[t - 16] \
|
||||
local.W[t] = S1(local.W[t - 2]) + local.W[t - 7] + \
|
||||
S0(local.W[t - 15]) + local.W[t - 16] \
|
||||
)
|
||||
|
||||
#define P(a,b,c,d,e,f,g,h,x,K) \
|
||||
{ \
|
||||
temp1 = h + S3(e) + F1(e,f,g) + K + x; \
|
||||
temp2 = S2(a) + F0(a,b,c); \
|
||||
d += temp1; h = temp1 + temp2; \
|
||||
local.temp1 = h + S3(e) + F1(e,f,g) + (K) + (x); \
|
||||
local.temp2 = S2(a) + F0(a,b,c); \
|
||||
d += local.temp1; h = local.temp1 + local.temp2; \
|
||||
}
|
||||
|
||||
static void esp_sha256_software_process(esp_sha256_context *ctx, const unsigned char data[64])
|
||||
{
|
||||
uint32_t temp1, temp2, W[64] = {0};
|
||||
uint32_t A[8] = {0};
|
||||
struct {
|
||||
uint32_t temp1, temp2, W[64];
|
||||
uint32_t A[8];
|
||||
} local;
|
||||
unsigned int i = 0;
|
||||
|
||||
for ( i = 0; i < 8; i++ ) {
|
||||
A[i] = ctx->state[i];
|
||||
local.A[i] = ctx->state[i];
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SHA256_SMALLER)
|
||||
for ( i = 0; i < 64; i++ ) {
|
||||
if ( i < 16 ) {
|
||||
GET_UINT32_BE( W[i], data, 4 * i );
|
||||
GET_UINT32_BE( local.W[i], data, 4 * i );
|
||||
} else {
|
||||
R( i );
|
||||
}
|
||||
|
||||
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
|
||||
P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
|
||||
|
||||
temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
|
||||
A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
|
||||
local.temp1 = local.A[7]; local.A[7] = local.A[6]; local.A[6] = local.A[5]; local.A[5] = local.A[4]; local.A[4] = local.A[3];
|
||||
local.A[3] = local.A[2]; local.A[2] = local.A[1]; local.A[1] = local.A[0]; local.A[0] = local.temp1;
|
||||
}
|
||||
#else /* MBEDTLS_SHA256_SMALLER */
|
||||
for ( i = 0; i < 16; i++ ) {
|
||||
GET_UINT32_BE( W[i], data, 4 * i );
|
||||
GET_UINT32_BE( local.W[i], data, 4 * i );
|
||||
}
|
||||
|
||||
for ( i = 0; i < 16; i += 8 ) {
|
||||
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i + 0], K[i + 0] );
|
||||
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i + 1], K[i + 1] );
|
||||
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i + 2], K[i + 2] );
|
||||
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i + 3], K[i + 3] );
|
||||
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i + 4], K[i + 4] );
|
||||
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i + 5], K[i + 5] );
|
||||
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i + 6], K[i + 6] );
|
||||
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i + 7], K[i + 7] );
|
||||
P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], local.W[i + 0], K[i + 0] );
|
||||
P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], local.W[i + 1], K[i + 1] );
|
||||
P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], local.W[i + 2], K[i + 2] );
|
||||
P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], local.W[i + 3], K[i + 3] );
|
||||
P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], local.W[i + 4], K[i + 4] );
|
||||
P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], local.W[i + 5], K[i + 5] );
|
||||
P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], local.W[i + 6], K[i + 6] );
|
||||
P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], local.W[i + 7], K[i + 7] );
|
||||
}
|
||||
|
||||
for ( i = 16; i < 64; i += 8 ) {
|
||||
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i + 0), K[i + 0] );
|
||||
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i + 1), K[i + 1] );
|
||||
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i + 2), K[i + 2] );
|
||||
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i + 3), K[i + 3] );
|
||||
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i + 4), K[i + 4] );
|
||||
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i + 5), K[i + 5] );
|
||||
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i + 6), K[i + 6] );
|
||||
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i + 7), K[i + 7] );
|
||||
P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], R(i + 0), K[i + 0] );
|
||||
P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], R(i + 1), K[i + 1] );
|
||||
P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], R(i + 2), K[i + 2] );
|
||||
P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], R(i + 3), K[i + 3] );
|
||||
P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], R(i + 4), K[i + 4] );
|
||||
P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], R(i + 5), K[i + 5] );
|
||||
P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], R(i + 6), K[i + 6] );
|
||||
P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], R(i + 7), K[i + 7] );
|
||||
}
|
||||
#endif /* MBEDTLS_SHA256_SMALLER */
|
||||
|
||||
for ( i = 0; i < 8; i++ ) {
|
||||
ctx->state[i] += A[i];
|
||||
ctx->state[i] += local.A[i];
|
||||
}
|
||||
|
||||
/* Zeroise buffers and variables to clear sensitive data from memory. */
|
||||
mbedtls_platform_zeroize(&local, sizeof(local));
|
||||
}
|
||||
static int esp_internal_sha256_parallel_engine_process(esp_sha256_context *ctx, const unsigned char data[64], bool read_digest)
|
||||
{
|
||||
@@ -319,7 +325,18 @@ static int esp_sha256_finish(esp_sha256_context *ctx, unsigned char *output)
|
||||
PUT_UINT32_BE( ctx->state[4], output, 16 );
|
||||
PUT_UINT32_BE( ctx->state[5], output, 20 );
|
||||
PUT_UINT32_BE( ctx->state[6], output, 24 );
|
||||
|
||||
#if SOC_SHA_SUPPORT_SHA224
|
||||
/* SHA-224 output is 28 bytes (7 state words); only SHA-256 emits the 8th
|
||||
* word. Writing state[7] for SHA-224 overflows a contract-valid 28-byte
|
||||
* output buffer by 4 bytes. Mirrors the mbedtls reference !is224 guard and
|
||||
* the esp_sha512_finish SHA2_512 guard in this same engine. */
|
||||
if ( ctx->mode != SHA2_224 ) {
|
||||
PUT_UINT32_BE( ctx->state[7], output, 28 );
|
||||
}
|
||||
#else
|
||||
PUT_UINT32_BE( ctx->state[7], output, 28 );
|
||||
#endif /* SOC_SHA_SUPPORT_SHA224 */
|
||||
|
||||
|
||||
out:
|
||||
@@ -346,6 +363,8 @@ psa_status_t esp_sha256_driver_update(
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t esp_sha256_driver_abort(esp_sha256_context *ctx);
|
||||
|
||||
psa_status_t esp_sha256_driver_compute(
|
||||
esp_sha256_context *ctx,
|
||||
psa_algorithm_t alg,
|
||||
@@ -375,20 +394,24 @@ psa_status_t esp_sha256_driver_compute(
|
||||
#endif // SOC_SHA_SUPPORT_SHA224
|
||||
int ret = esp_sha256_starts(ctx, mode);
|
||||
if (ret != ESP_OK) {
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
goto hw_fail;
|
||||
}
|
||||
|
||||
ret = esp_sha256_update(ctx, input, input_length);
|
||||
if (ret != ESP_OK) {
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
goto hw_fail;
|
||||
}
|
||||
|
||||
ret = esp_sha256_finish(ctx, hash);
|
||||
if (ret != ESP_OK) {
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
goto hw_fail;
|
||||
}
|
||||
*hash_length = PSA_HASH_LENGTH(alg);
|
||||
return PSA_SUCCESS;
|
||||
|
||||
hw_fail:
|
||||
esp_sha256_driver_abort(ctx);
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
}
|
||||
|
||||
psa_status_t esp_sha256_driver_finish(
|
||||
@@ -430,6 +453,6 @@ psa_status_t esp_sha256_driver_abort(esp_sha256_context *ctx)
|
||||
esp_sha_unlock_engine(SHA2_256);
|
||||
ctx->operation_mode = ESP_SHA_MODE_SOFTWARE;
|
||||
}
|
||||
memset(ctx, 0, sizeof(esp_sha256_context));
|
||||
mbedtls_platform_zeroize(ctx, sizeof(esp_sha256_context));
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "sha/sha_parallel_engine.h"
|
||||
#include "esp_err.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#if defined(_MSC_VER) || defined(__WATCOMC__)
|
||||
#define UL64(x) x##ui64
|
||||
@@ -145,8 +146,10 @@ static const uint64_t K[80] = {
|
||||
static void esp_sha512_software_process(esp_sha512_context *ctx, const unsigned char data[128])
|
||||
{
|
||||
int i;
|
||||
uint64_t temp1, temp2, W[80];
|
||||
uint64_t A, B, C, D, E, F, G, H;
|
||||
struct {
|
||||
uint64_t temp1, temp2, W[80];
|
||||
uint64_t A[8];
|
||||
} local;
|
||||
|
||||
#define SHR(x,n) (x >> n)
|
||||
#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
|
||||
@@ -162,49 +165,42 @@ static void esp_sha512_software_process(esp_sha512_context *ctx, const unsigned
|
||||
|
||||
#define P(a,b,c,d,e,f,g,h,x,K) \
|
||||
{ \
|
||||
temp1 = h + S3(e) + F1(e,f,g) + K + x; \
|
||||
temp2 = S2(a) + F0(a,b,c); \
|
||||
d += temp1; h = temp1 + temp2; \
|
||||
local.temp1 = h + S3(e) + F1(e,f,g) + (K) + (x); \
|
||||
local.temp2 = S2(a) + F0(a,b,c); \
|
||||
d += local.temp1; h = local.temp1 + local.temp2; \
|
||||
}
|
||||
|
||||
for ( i = 0; i < 16; i++ ) {
|
||||
GET_UINT64_BE( W[i], data, i << 3 );
|
||||
GET_UINT64_BE( local.W[i], data, i << 3 );
|
||||
}
|
||||
|
||||
for ( ; i < 80; i++ ) {
|
||||
W[i] = S1(W[i - 2]) + W[i - 7] +
|
||||
S0(W[i - 15]) + W[i - 16];
|
||||
local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
|
||||
S0(local.W[i - 15]) + local.W[i - 16];
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
local.A[i] = ctx->state[i];
|
||||
}
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
E = ctx->state[4];
|
||||
F = ctx->state[5];
|
||||
G = ctx->state[6];
|
||||
H = ctx->state[7];
|
||||
i = 0;
|
||||
|
||||
do {
|
||||
P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
|
||||
P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
|
||||
P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
|
||||
P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
|
||||
P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
|
||||
P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
|
||||
P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
|
||||
P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
|
||||
P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], local.W[i], K[i] ); i++;
|
||||
P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], local.W[i], K[i] ); i++;
|
||||
P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], local.W[i], K[i] ); i++;
|
||||
P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], local.W[i], K[i] ); i++;
|
||||
P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], local.W[i], K[i] ); i++;
|
||||
P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], local.W[i], K[i] ); i++;
|
||||
P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], local.W[i], K[i] ); i++;
|
||||
P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], local.W[i], K[i] ); i++;
|
||||
} while ( i < 80 );
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
ctx->state[4] += E;
|
||||
ctx->state[5] += F;
|
||||
ctx->state[6] += G;
|
||||
ctx->state[7] += H;
|
||||
for (i = 0; i < 8; i++) {
|
||||
ctx->state[i] += local.A[i];
|
||||
}
|
||||
|
||||
mbedtls_platform_zeroize(&local, sizeof(local));
|
||||
}
|
||||
|
||||
static int esp_internal_sha512_parallel_engine_process( esp_sha512_context *ctx, const unsigned char data[128], bool read_digest )
|
||||
@@ -237,6 +233,7 @@ int esp_internal_sha512_process( esp_sha512_context *ctx, const unsigned char da
|
||||
{
|
||||
return esp_internal_sha512_parallel_engine_process(ctx, data, true);
|
||||
}
|
||||
|
||||
static int esp_sha512_update(esp_sha512_context *ctx, const unsigned char *input,
|
||||
size_t ilen)
|
||||
{
|
||||
@@ -349,6 +346,8 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
psa_status_t esp_sha512_driver_abort(esp_sha512_context *ctx);
|
||||
|
||||
psa_status_t esp_sha512_driver_compute(
|
||||
esp_sha512_context *ctx,
|
||||
psa_algorithm_t alg,
|
||||
@@ -370,20 +369,24 @@ psa_status_t esp_sha512_driver_compute(
|
||||
int mode = (alg == PSA_ALG_SHA_384) ? SHA2_384 : SHA2_512;
|
||||
int ret = esp_sha512_starts(ctx, mode);
|
||||
if (ret != ESP_OK) {
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
goto hw_fail;
|
||||
}
|
||||
|
||||
ret = esp_sha512_update(ctx, input, input_length);
|
||||
if (ret != ESP_OK) {
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
goto hw_fail;
|
||||
}
|
||||
|
||||
ret = esp_sha512_finish(ctx, hash);
|
||||
if (ret != ESP_OK) {
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
goto hw_fail;
|
||||
}
|
||||
*hash_length = PSA_HASH_LENGTH(alg);
|
||||
return PSA_SUCCESS;
|
||||
|
||||
hw_fail:
|
||||
esp_sha512_driver_abort(ctx);
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
}
|
||||
|
||||
psa_status_t esp_sha512_driver_update(
|
||||
@@ -442,7 +445,7 @@ psa_status_t esp_sha512_driver_abort(esp_sha512_context *ctx)
|
||||
esp_sha_unlock_engine(sha_type(ctx));
|
||||
ctx->operation_mode = ESP_SHA_MODE_SOFTWARE;
|
||||
}
|
||||
memset(ctx, 0, sizeof(esp_sha512_context));
|
||||
mbedtls_platform_zeroize(ctx, sizeof(esp_sha512_context));
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "mbedtls/esp_config.h"
|
||||
#include "psa_crypto_driver_esp_sha.h"
|
||||
@@ -46,8 +47,11 @@ static int esp_sha_driver_check_supported_algorithm(psa_algorithm_t alg) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static int esp_sha_validate_args(psa_algorithm_t alg, const uint8_t *input, size_t input_length, uint8_t *hash, size_t hash_size) {
|
||||
if (!hash) {
|
||||
static int esp_sha_validate_args(psa_algorithm_t alg, const uint8_t *input, size_t input_length, uint8_t *hash, size_t hash_size, const size_t *hash_length) {
|
||||
if (!hash || !hash_length) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (input == NULL && input_length != 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
@@ -72,7 +76,7 @@ psa_status_t esp_sha_hash_compute(
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
ret = esp_sha_validate_args(alg, input, input_length, hash, hash_size);
|
||||
ret = esp_sha_validate_args(alg, input, input_length, hash, hash_size, hash_length);
|
||||
if (ret == ESP_ERR_INVALID_ARG) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
} else if (ret == ESP_ERR_INVALID_SIZE) {
|
||||
@@ -87,7 +91,7 @@ psa_status_t esp_sha_hash_compute(
|
||||
case PSA_ALG_SHA_1:
|
||||
esp_sha1_context sha1_ctx = {0};
|
||||
ret = esp_sha1_driver_compute(&sha1_ctx, input, input_length, hash, hash_size, &hash_length_calculated);
|
||||
memset(&sha1_ctx, 0, sizeof(sha1_ctx));
|
||||
mbedtls_platform_zeroize(&sha1_ctx, sizeof(sha1_ctx));
|
||||
*hash_length = hash_length_calculated;
|
||||
break;
|
||||
#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_1
|
||||
@@ -98,7 +102,7 @@ psa_status_t esp_sha_hash_compute(
|
||||
case PSA_ALG_SHA_256:
|
||||
esp_sha256_context sha256_ctx = {0};
|
||||
ret = esp_sha256_driver_compute(&sha256_ctx, alg, input, input_length, hash, hash_size, &hash_length_calculated);
|
||||
memset(&sha256_ctx, 0, sizeof(sha256_ctx));
|
||||
mbedtls_platform_zeroize(&sha256_ctx, sizeof(sha256_ctx));
|
||||
*hash_length = hash_length_calculated;
|
||||
break;
|
||||
#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_256
|
||||
@@ -109,7 +113,7 @@ psa_status_t esp_sha_hash_compute(
|
||||
case PSA_ALG_SHA_512:
|
||||
esp_sha512_context sha512_ctx = {0};
|
||||
ret = esp_sha512_driver_compute(&sha512_ctx, alg, input, input_length, hash, hash_size, &hash_length_calculated);
|
||||
memset(&sha512_ctx, 0, sizeof(sha512_ctx));
|
||||
mbedtls_platform_zeroize(&sha512_ctx, sizeof(sha512_ctx));
|
||||
*hash_length = hash_length_calculated;
|
||||
break;
|
||||
#endif // defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384)
|
||||
@@ -128,6 +132,9 @@ psa_status_t esp_sha_hash_setup(esp_sha_hash_operation_t *operation, psa_algorit
|
||||
if (!operation) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (operation->sha_ctx != NULL) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1
|
||||
if (alg == PSA_ALG_SHA_1) {
|
||||
esp_sha1_context *sha1_ctx = heap_caps_malloc(sizeof(esp_sha1_context), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
@@ -137,7 +144,12 @@ psa_status_t esp_sha_hash_setup(esp_sha_hash_operation_t *operation, psa_algorit
|
||||
memset(sha1_ctx, 0, sizeof(esp_sha1_context));
|
||||
operation->sha_ctx = sha1_ctx;
|
||||
operation->sha_type = ESP_SHA_OPERATION_TYPE_SHA1;
|
||||
return esp_sha1_starts(sha1_ctx);
|
||||
int ret = esp_sha1_starts(sha1_ctx);
|
||||
if (ret != ESP_OK) {
|
||||
esp_sha_hash_abort(operation);
|
||||
return PSA_ERROR_HARDWARE_FAILURE;
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
} else
|
||||
#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_1
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224)
|
||||
@@ -151,8 +163,8 @@ psa_status_t esp_sha_hash_setup(esp_sha_hash_operation_t *operation, psa_algorit
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
memset(sha256_ctx, 0, sizeof(esp_sha256_context));
|
||||
operation->sha_ctx = sha256_ctx;
|
||||
int mode;
|
||||
operation->sha_ctx = sha256_ctx;
|
||||
#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_224
|
||||
operation->sha_type = (alg == PSA_ALG_SHA_224) ? ESP_SHA_OPERATION_TYPE_SHA224 : ESP_SHA_OPERATION_TYPE_SHA256;
|
||||
mode = (alg == PSA_ALG_SHA_224) ? SHA2_224 : SHA2_256;
|
||||
@@ -160,7 +172,12 @@ psa_status_t esp_sha_hash_setup(esp_sha_hash_operation_t *operation, psa_algorit
|
||||
operation->sha_type = ESP_SHA_OPERATION_TYPE_SHA256;
|
||||
mode = SHA2_256;
|
||||
#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_224
|
||||
return esp_sha256_starts(sha256_ctx, mode);
|
||||
int ret = esp_sha256_starts(sha256_ctx, mode);
|
||||
if (ret != PSA_SUCCESS) {
|
||||
esp_sha_hash_abort(operation);
|
||||
return ret;
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
} else
|
||||
#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_256 || MBEDTLS_PSA_ACCEL_ALG_SHA_224
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384)
|
||||
@@ -174,17 +191,25 @@ psa_status_t esp_sha_hash_setup(esp_sha_hash_operation_t *operation, psa_algorit
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
memset(sha512_ctx, 0, sizeof(esp_sha512_context));
|
||||
operation->sha_ctx = sha512_ctx;
|
||||
int mode = SHA2_512;
|
||||
operation->sha_ctx = sha512_ctx;
|
||||
operation->sha_type = ESP_SHA_OPERATION_TYPE_SHA512;
|
||||
#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_384
|
||||
operation->sha_type = (alg == PSA_ALG_SHA_384) ? ESP_SHA_OPERATION_TYPE_SHA384 : ESP_SHA_OPERATION_TYPE_SHA512;
|
||||
mode = (alg == PSA_ALG_SHA_384) ? SHA2_384 : SHA2_512;
|
||||
#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_384
|
||||
return esp_sha512_starts(sha512_ctx, mode);
|
||||
int ret = esp_sha512_starts(sha512_ctx, mode);
|
||||
if (ret != PSA_SUCCESS) {
|
||||
esp_sha_hash_abort(operation);
|
||||
return ret;
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
#endif // defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384)
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
if (PSA_ALG_IS_HASH(alg)) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
psa_status_t esp_sha_hash_update(
|
||||
@@ -192,9 +217,18 @@ psa_status_t esp_sha_hash_update(
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
if (!operation || !operation->sha_ctx || !input) {
|
||||
if (!operation) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (operation->sha_ctx == NULL) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
if (input == NULL && input_length != 0) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (input_length == 0) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1
|
||||
if (operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA1) {
|
||||
esp_sha1_context *ctx = (esp_sha1_context *)operation->sha_ctx;
|
||||
@@ -213,7 +247,7 @@ psa_status_t esp_sha_hash_update(
|
||||
return esp_sha512_driver_update(ctx, input, input_length);
|
||||
}
|
||||
#endif // (defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512))
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
psa_status_t esp_sha_hash_finish(
|
||||
@@ -226,135 +260,163 @@ psa_status_t esp_sha_hash_finish(
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (operation->sha_ctx == NULL) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
/* Defense in depth: gate buffer sizing in the dispatcher so we don't rely
|
||||
* solely on every per-algorithm sub-driver to enforce it. */
|
||||
size_t expected_size = 0;
|
||||
switch (operation->sha_type) {
|
||||
case ESP_SHA_OPERATION_TYPE_SHA1: expected_size = PSA_HASH_LENGTH(PSA_ALG_SHA_1); break;
|
||||
case ESP_SHA_OPERATION_TYPE_SHA224: expected_size = PSA_HASH_LENGTH(PSA_ALG_SHA_224); break;
|
||||
case ESP_SHA_OPERATION_TYPE_SHA256: expected_size = PSA_HASH_LENGTH(PSA_ALG_SHA_256); break;
|
||||
case ESP_SHA_OPERATION_TYPE_SHA384: expected_size = PSA_HASH_LENGTH(PSA_ALG_SHA_384); break;
|
||||
case ESP_SHA_OPERATION_TYPE_SHA512: expected_size = PSA_HASH_LENGTH(PSA_ALG_SHA_512); break;
|
||||
default: return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
if (hash_size < expected_size) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1
|
||||
if (operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA1) {
|
||||
esp_sha1_context *ctx = (esp_sha1_context *)operation->sha_ctx;
|
||||
int ret = esp_sha1_driver_finish(ctx, hash, hash_size, hash_length);
|
||||
mbedtls_platform_zeroize(ctx, sizeof(esp_sha1_context));
|
||||
free(ctx); // Free the context after use
|
||||
operation->sha_ctx = NULL;
|
||||
return ret;
|
||||
return esp_sha1_driver_finish((esp_sha1_context *)operation->sha_ctx,
|
||||
hash, hash_size, hash_length);
|
||||
} else
|
||||
#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_1
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256)
|
||||
if (operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA256 ||
|
||||
operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA224) {
|
||||
esp_sha256_context *ctx = (esp_sha256_context *)operation->sha_ctx;
|
||||
int ret = esp_sha256_driver_finish(ctx, hash, hash_size, hash_length, operation->sha_type);
|
||||
mbedtls_platform_zeroize(ctx, sizeof(esp_sha256_context));
|
||||
free(ctx); // Free the context after use
|
||||
operation->sha_ctx = NULL;
|
||||
return ret;
|
||||
return esp_sha256_driver_finish((esp_sha256_context *)operation->sha_ctx,
|
||||
hash, hash_size, hash_length,
|
||||
operation->sha_type);
|
||||
} else
|
||||
#endif // defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256)
|
||||
#if (defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512))
|
||||
if (operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA384 ||
|
||||
operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA512) {
|
||||
esp_sha512_context *ctx = (esp_sha512_context *)operation->sha_ctx;
|
||||
int ret = esp_sha512_driver_finish(ctx, hash, hash_size, hash_length, operation->sha_type);
|
||||
mbedtls_platform_zeroize(ctx, sizeof(esp_sha512_context));
|
||||
free(ctx); // Free the context after use
|
||||
operation->sha_ctx = NULL;
|
||||
return ret;
|
||||
return esp_sha512_driver_finish((esp_sha512_context *)operation->sha_ctx,
|
||||
hash, hash_size, hash_length,
|
||||
operation->sha_type);
|
||||
}
|
||||
#endif // defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512)
|
||||
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
psa_status_t esp_sha_hash_abort(esp_sha_hash_operation_t *operation)
|
||||
{
|
||||
if (!operation) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1
|
||||
if (operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA1) {
|
||||
esp_sha1_context *ctx = (esp_sha1_context *)operation->sha_ctx;
|
||||
if (ctx) {
|
||||
esp_sha1_driver_abort(ctx);
|
||||
}
|
||||
} else
|
||||
#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_1
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256)
|
||||
if (operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA256 ||
|
||||
operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA224) {
|
||||
esp_sha256_context *ctx = (esp_sha256_context *)operation->sha_ctx;
|
||||
if (ctx) {
|
||||
esp_sha256_driver_abort(ctx);
|
||||
}
|
||||
} else
|
||||
#endif // defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256)
|
||||
#if (defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512))
|
||||
if (operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA384 ||
|
||||
operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA512) {
|
||||
esp_sha512_context *ctx = (esp_sha512_context *)operation->sha_ctx;
|
||||
if (ctx) {
|
||||
esp_sha512_driver_abort(ctx);
|
||||
}
|
||||
} else
|
||||
#endif // (defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512))
|
||||
{
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
if (operation->sha_ctx) {
|
||||
free(operation->sha_ctx);
|
||||
operation->sha_ctx = NULL;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
if (operation->sha_ctx == NULL) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
bool bad_state = false;
|
||||
switch (operation->sha_type) {
|
||||
#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1
|
||||
case ESP_SHA_OPERATION_TYPE_SHA1:
|
||||
(void)esp_sha1_driver_abort((esp_sha1_context *)operation->sha_ctx);
|
||||
break;
|
||||
#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_1
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256)
|
||||
case ESP_SHA_OPERATION_TYPE_SHA256:
|
||||
case ESP_SHA_OPERATION_TYPE_SHA224:
|
||||
(void)esp_sha256_driver_abort((esp_sha256_context *)operation->sha_ctx);
|
||||
break;
|
||||
#endif // defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256)
|
||||
#if (defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512))
|
||||
case ESP_SHA_OPERATION_TYPE_SHA384:
|
||||
case ESP_SHA_OPERATION_TYPE_SHA512:
|
||||
(void)esp_sha512_driver_abort((esp_sha512_context *)operation->sha_ctx);
|
||||
break;
|
||||
#endif // (defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512))
|
||||
default:
|
||||
bad_state = true;
|
||||
break;
|
||||
}
|
||||
|
||||
free(operation->sha_ctx);
|
||||
operation->sha_ctx = NULL;
|
||||
return bad_state ? PSA_ERROR_BAD_STATE : PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t esp_sha_hash_clone(
|
||||
const esp_sha_hash_operation_t *source_operation,
|
||||
esp_sha_hash_operation_t *target_operation)
|
||||
{
|
||||
target_operation->sha_type = source_operation->sha_type;
|
||||
if (!source_operation || !target_operation) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (source_operation->sha_ctx == NULL) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
if (target_operation->sha_ctx != NULL) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
void *ctx = NULL;
|
||||
size_t ctx_size = 0;
|
||||
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
|
||||
|
||||
#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1
|
||||
if (target_operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA1) {
|
||||
esp_sha1_context *sha1_ctx = heap_caps_malloc(sizeof(esp_sha1_context), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
if (!sha1_ctx) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
memset(sha1_ctx, 0, sizeof(esp_sha1_context));
|
||||
target_operation->sha_ctx = sha1_ctx;
|
||||
if (!target_operation->sha_ctx) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
esp_sha1_driver_clone(source_operation->sha_ctx, target_operation->sha_ctx);
|
||||
if (source_operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA1) {
|
||||
ctx_size = sizeof(esp_sha1_context);
|
||||
} else
|
||||
#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_1
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256)
|
||||
if (target_operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA256 ||
|
||||
target_operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA224) {
|
||||
esp_sha256_context *sha256_ctx = heap_caps_malloc(sizeof(esp_sha256_context), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
if (!sha256_ctx) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
memset(sha256_ctx, 0, sizeof(esp_sha256_context));
|
||||
target_operation->sha_ctx = sha256_ctx;
|
||||
if (!target_operation->sha_ctx) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
esp_sha256_driver_clone(source_operation->sha_ctx, target_operation->sha_ctx);
|
||||
if (source_operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA256 ||
|
||||
source_operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA224) {
|
||||
ctx_size = sizeof(esp_sha256_context);
|
||||
} else
|
||||
#endif // defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256)
|
||||
#if (defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512))
|
||||
if (target_operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA384 ||
|
||||
target_operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA512) {
|
||||
esp_sha512_context *sha512_ctx = heap_caps_malloc(sizeof(esp_sha512_context), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
if (!sha512_ctx) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
memset(sha512_ctx, 0, sizeof(esp_sha512_context));
|
||||
target_operation->sha_ctx = sha512_ctx;
|
||||
if (!target_operation->sha_ctx) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
esp_sha512_driver_clone(source_operation->sha_ctx, target_operation->sha_ctx);
|
||||
if (source_operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA384 ||
|
||||
source_operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA512) {
|
||||
ctx_size = sizeof(esp_sha512_context);
|
||||
} else
|
||||
#endif // (defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512))
|
||||
{
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
ctx = heap_caps_malloc(ctx_size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
if (!ctx) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
memset(ctx, 0, ctx_size);
|
||||
|
||||
#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1
|
||||
if (source_operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA1) {
|
||||
status = esp_sha1_driver_clone(source_operation->sha_ctx, ctx);
|
||||
} else
|
||||
#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_1
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256)
|
||||
if (source_operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA256 ||
|
||||
source_operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA224) {
|
||||
status = esp_sha256_driver_clone(source_operation->sha_ctx, ctx);
|
||||
} else
|
||||
#endif // defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256)
|
||||
#if (defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512))
|
||||
if (source_operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA384 ||
|
||||
source_operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA512) {
|
||||
status = esp_sha512_driver_clone(source_operation->sha_ctx, ctx);
|
||||
} else
|
||||
#endif // (defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384) || defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512))
|
||||
{
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_platform_zeroize(ctx, ctx_size);
|
||||
free(ctx);
|
||||
return status;
|
||||
}
|
||||
|
||||
target_operation->sha_ctx = ctx;
|
||||
target_operation->sha_type = source_operation->sha_type;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -37,9 +37,11 @@ typedef struct {
|
||||
* @brief Structure to store opaque HMAC operation context.
|
||||
*/
|
||||
typedef struct {
|
||||
psa_algorithm_t alg; /**< MAC algorithm (PSA_ALG_HMAC(PSA_ALG_SHA_256)); 0 = fresh / aborted. */
|
||||
const uint8_t *key_buffer; /**< Pointer to the per-source storage struct in key slot */
|
||||
uint8_t hmac[ESP_HMAC_RESULT_SIZE]; /**< Buffer to store the HMAC result */
|
||||
bool is_persistent; /**< Cached persistence flag for use in update */
|
||||
bool computed; /**< True once update has produced a MAC into hmac[]; gates double-update. */
|
||||
} esp_hmac_opaque_operation_t;
|
||||
|
||||
#endif /* ESP_HMAC_OPAQUE_DRIVER_ENABLED */
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "soc/soc_caps.h"
|
||||
#include "psa/crypto_driver_common.h"
|
||||
#include "psa_crypto_driver_esp_sha_contexts.h"
|
||||
#include "esp_rom_md5.h"
|
||||
#include "psa_crypto_driver_esp_md5_contexts.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -21,7 +21,7 @@ typedef struct {
|
||||
psa_algorithm_t alg;
|
||||
uint8_t *opad; // Dynamically allocated to save space
|
||||
union {
|
||||
md5_context_t md5_ctx;
|
||||
esp_md5_hash_operation_t md5_ctx;
|
||||
esp_sha_hash_operation_t esp_sha_ctx;
|
||||
};
|
||||
} esp_hmac_transparent_operation_t;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include "esp_types.h"
|
||||
#include "psa/crypto.h"
|
||||
#include "esp_rom_md5.h"
|
||||
#include "psa_crypto_driver_esp_md5_contexts.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -27,25 +27,25 @@ psa_status_t esp_md5_hash_compute(psa_algorithm_t alg,
|
||||
size_t hash_size,
|
||||
size_t *hash_length);
|
||||
|
||||
psa_status_t esp_md5_hash_setup(md5_context_t *operation,
|
||||
psa_status_t esp_md5_hash_setup(esp_md5_hash_operation_t *operation,
|
||||
psa_algorithm_t alg);
|
||||
|
||||
psa_status_t esp_md5_hash_update(
|
||||
md5_context_t *operation,
|
||||
esp_md5_hash_operation_t *operation,
|
||||
const uint8_t *input,
|
||||
size_t input_length );
|
||||
|
||||
psa_status_t esp_md5_hash_finish(
|
||||
md5_context_t *operation,
|
||||
esp_md5_hash_operation_t *operation,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length);
|
||||
|
||||
psa_status_t esp_md5_hash_abort(md5_context_t *operation);
|
||||
psa_status_t esp_md5_hash_abort(esp_md5_hash_operation_t *operation);
|
||||
|
||||
psa_status_t esp_md5_hash_clone(
|
||||
const md5_context_t *source_operation,
|
||||
md5_context_t *target_operation);
|
||||
const esp_md5_hash_operation_t *source_operation,
|
||||
esp_md5_hash_operation_t *target_operation);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "esp_rom_md5.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ESP MD5 driver operation context
|
||||
*
|
||||
* Wraps the ROM-supplied md5_context_t with an explicit is_active flag so
|
||||
* the driver can detect setup-twice / update-without-setup / use-after-abort
|
||||
* without relying on internal field values of the ROM struct.
|
||||
*/
|
||||
typedef struct {
|
||||
md5_context_t md5_ctx;
|
||||
bool is_active;
|
||||
} esp_md5_hash_operation_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -41,6 +41,14 @@ static const uint8_t expected_hmac_sha256[] = {
|
||||
0x50, 0xd7, 0x15, 0x78, 0x82, 0x10, 0xbe, 0xc6,
|
||||
};
|
||||
|
||||
/* HMAC-SHA256(key_256, "") — MAC of an empty (zero-length) message. */
|
||||
static const uint8_t expected_hmac_sha256_empty[] = {
|
||||
0x46, 0x24, 0x76, 0xa8, 0x97, 0xdd, 0xfd, 0xbd,
|
||||
0x40, 0xd1, 0x42, 0x0e, 0x08, 0xa5, 0xbc, 0xfe,
|
||||
0xeb, 0x25, 0xc3, 0xe2, 0xad, 0xe6, 0xa0, 0xa9,
|
||||
0x08, 0x3b, 0x32, 0x7b, 0x9e, 0xf9, 0xfc, 0xa1,
|
||||
};
|
||||
|
||||
// Helper function to set up key attributes for HMAC
|
||||
static void setup_hmac_key_attributes(psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
@@ -160,6 +168,27 @@ TEST_CASE("PSA HMAC SHA-256 test", "[psa_hmac]")
|
||||
psa_reset_key_attributes(&attributes);
|
||||
}
|
||||
|
||||
TEST_CASE("PSA HMAC SHA-256 empty input 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);
|
||||
|
||||
/* A zero-length input must produce HMAC(key, ""), not an error. */
|
||||
test_hmac_compute_and_verify(key_id, alg, test_data, 0,
|
||||
expected_hmac_sha256_empty,
|
||||
sizeof(expected_hmac_sha256_empty));
|
||||
|
||||
psa_destroy_key(key_id);
|
||||
psa_reset_key_attributes(&attributes);
|
||||
}
|
||||
|
||||
TEST_CASE("PSA HMAC SHA-256 multipart test", "[psa_hmac]")
|
||||
{
|
||||
psa_status_t status;
|
||||
@@ -257,4 +286,44 @@ TEST_CASE("PSA HMAC opaque driver compute and verify", "[psa_hmac][efuse_hmac_ke
|
||||
psa_destroy_key(key_id);
|
||||
psa_reset_key_attributes(&attributes);
|
||||
}
|
||||
|
||||
TEST_CASE("PSA HMAC opaque driver empty input compute and verify", "[psa_hmac][efuse_hmac_key]")
|
||||
{
|
||||
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);
|
||||
|
||||
esp_hmac_opaque_key_t opaque_key = {
|
||||
.efuse_key_id = HMAC_EFUSE_KEY_ID,
|
||||
};
|
||||
|
||||
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, PSA_KEY_LIFETIME_ESP_HMAC_VOLATILE);
|
||||
|
||||
status = psa_import_key(&attributes, (uint8_t *)&opaque_key, sizeof(opaque_key), &key_id);
|
||||
TEST_ASSERT_EQUAL_HEX32(PSA_SUCCESS, status);
|
||||
|
||||
/*
|
||||
* Zero-length input: update() no-ops, so finish() must compute HMAC(key, "")
|
||||
* rather than returning PSA_ERROR_BAD_STATE.
|
||||
*/
|
||||
uint8_t mac[32] = {0};
|
||||
size_t mac_length = 0;
|
||||
status = psa_mac_compute(key_id, alg, test_data, 0,
|
||||
mac, sizeof(mac), &mac_length);
|
||||
TEST_ASSERT_EQUAL_HEX32(PSA_SUCCESS, status);
|
||||
TEST_ASSERT_EQUAL(sizeof(expected_hmac_sha256_empty), mac_length);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_hmac_sha256_empty, mac, mac_length);
|
||||
|
||||
status = psa_mac_verify(key_id, alg, test_data, 0,
|
||||
expected_hmac_sha256_empty, sizeof(expected_hmac_sha256_empty));
|
||||
TEST_ASSERT_EQUAL_HEX32(PSA_SUCCESS, status);
|
||||
|
||||
psa_destroy_key(key_id);
|
||||
psa_reset_key_attributes(&attributes);
|
||||
}
|
||||
#endif /* ESP_HMAC_OPAQUE_DRIVER_ENABLED && CONFIG_MBEDTLS_TEST_HMAC_OPAQUE_EFUSE_KEY */
|
||||
|
||||
@@ -221,6 +221,10 @@ Using an eFuse-based HMAC key:
|
||||
// failure calculating HMAC
|
||||
}
|
||||
|
||||
.. note::
|
||||
|
||||
The ESP-HMAC opaque PSA driver is backed by the one-shot hardware HMAC peripheral, which computes the MAC over the whole message in a single operation and cannot save or restore intermediate state between calls. Multipart streaming is therefore not supported: supply the entire message in a single :cpp:func:`psa_mac_compute` call (as shown above) or in a single multipart update. A second non-empty update on the same operation returns ``PSA_ERROR_BAD_STATE``; the operation fails closed and never produces a MAC computed over only part of the message.
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
|
||||
@@ -221,6 +221,10 @@ HMAC 的第三种应用场景是将其作为密钥,启用软禁用的 JTAG 接
|
||||
// 计算 HMAC 失败
|
||||
}
|
||||
|
||||
.. note::
|
||||
|
||||
ESP-HMAC 不透明 PSA 驱动基于单次硬件 HMAC 外设实现,该外设可以通过单次运算为完整消息计算消息认证码 (MAC),但无法在多次调用之间保存或恢复运算中间状态。因此,该驱动不支持多分段流式运算:须在单次 :cpp:func:`psa_mac_compute` 调用中传入完整消息(如上所示),或仅执行一次多分段更新操作。若对同一 MAC 运算操作发起第二次非空更新,会返回 ``PSA_ERROR_BAD_STATE`` 错误,且该操作会直接失败并关闭,不会基于部分消息生成对应的 MAC 结果。
|
||||
|
||||
API 参考
|
||||
-------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user