From b5d16d86dc639e7e8dfc0b9d1ceefea8fee4ce62 Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Thu, 21 May 2026 12:37:37 +0530 Subject: [PATCH 1/3] fix(mbedtls/port): align ESP PSA hardware drivers with software references Audited every esp_* PSA driver against its corresponding software driver in mbedtls/library (psa_crypto_cipher.c, psa_crypto_aead.c, psa_crypto_mac.c, psa_crypto_hash.c, psa_crypto_ecp.c, psa_crypto_rsa.c) and fixed gaps in workflow ownership, error-path cleanup, sensitive-data wiping, and BAD_STATE gating per the PSA Crypto API spec. esp_aes (cipher): fix padding oracle in cipher_finish by replacing leaky branches with mbedtls_ct_* primitives; abort wipes the driver-level ctx, not just the inner mbedtls_aes_context; setup routes errors through abort. esp_aes_gcm (AEAD): zeroize the 16-byte full_tag scratch; restore the *output_length = finish_output_size assignment that the SW reference keeps for future ciphers; NULL the inner ctx pointer after free in abort; gate update/finish on a live ctx with PSA_ERROR_BAD_STATE. esp_ecdsa: keep abort-at-exit in the one-shot wrappers so the stack-copy of the hash (needed for little-endian byte order on HW) is wiped per PSA spec 6.3.3, drop the over-defensive public-key qx/qy wipes that the SW driver does not perform. esp_cmac / esp_hmac_transparent / esp_hmac_opaque (MAC): make abort idempotent, route setup errors through abort, gate update/finish/ verify_finish on PSA_ERROR_BAD_STATE, wipe M_last and intermediate hmac[] buffers on completion or HW failure. HMAC opaque gains alg + computed fields to mirror the SW psa_crypto_mac.c state machine. HMAC transparent explicitly aborts the inner SHA context before reusing it for the outer hash. esp_sha: switch the per-op live indicator to (sha_ctx != NULL) so the public esp_sha_operation_type_t enum keeps its original ordinal values; free + NULL sha_ctx on every error path; gate update/finish/clone on a live ctx; wipe per-algorithm core/parallel-engine scratch buffers (W[], A[], state) on HW-engine failure. esp_md5: replace bare memset in abort with mbedtls_platform_zeroize. esp_rsa_ds: complete() no longer frees sig_buffer (abort owns that); start() routes failures through abort; asymmetric_decrypt funnels all cleanup through a single exit: label. RSA-DS utilities wipe the decrypted-plaintext scratch on v15 / OAEP unpad failure. --- components/mbedtls/mbedtls | 2 +- .../esp_aes/psa_crypto_driver_esp_aes.c | 123 +++++--- .../esp_aes/psa_crypto_driver_esp_aes_gcm.c | 31 +- .../esp_ecdsa/psa_crypto_driver_esp_ecdsa.c | 60 +++- .../esp_mac/psa_crypto_driver_esp_cmac.c | 84 ++++-- .../psa_crypto_driver_esp_hmac_opaque.c | 68 ++++- .../psa_crypto_driver_esp_hmac_transparent.c | 91 ++++-- .../esp_md/psa_crypto_driver_esp_md5.c | 67 +++-- .../psa_crypto_driver_esp_rsa_ds_utilities.h | 4 +- .../esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c | 165 ++++++----- .../psa_crypto_driver_esp_rsa_ds_utilities.c | 6 +- .../esp_sha/core/psa_crypto_driver_esp_sha1.c | 15 +- .../core/psa_crypto_driver_esp_sha256.c | 15 +- .../core/psa_crypto_driver_esp_sha512.c | 15 +- .../psa_crypto_driver_esp_sha1.c | 17 +- .../psa_crypto_driver_esp_sha256.c | 22 +- .../psa_crypto_driver_esp_sha512.c | 21 +- .../esp_sha/psa_crypto_driver_esp_sha.c | 272 +++++++++++------- ...a_crypto_driver_esp_hmac_opaque_contexts.h | 2 + ...pto_driver_esp_hmac_transparent_contexts.h | 4 +- .../include/psa_crypto_driver_esp_md5.h | 14 +- .../psa_crypto_driver_esp_md5_contexts.h | 30 ++ 22 files changed, 768 insertions(+), 360 deletions(-) create mode 100644 components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_md5_contexts.h diff --git a/components/mbedtls/mbedtls b/components/mbedtls/mbedtls index 6cc42afad30..06505cc5be2 160000 --- a/components/mbedtls/mbedtls +++ b/components/mbedtls/mbedtls @@ -1 +1 @@ -Subproject commit 6cc42afad309e861f4c07e6f106e2ab14a9cb8e5 +Subproject commit 06505cc5be21602f667490e476a9bae7989ef411 diff --git a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c index c6fdf384d21..60d738d5efe 100644 --- a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c +++ b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c @@ -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; } @@ -388,23 +394,28 @@ static int get_pkcs_padding(unsigned char *input, size_t input_len, size_t *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)); } + /* Gate *data_len on the bad flag so it does not leak padding validity. */ + *data_len = mbedtls_ct_if(bad, 0, pad_idx); + return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING); } @@ -415,9 +426,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 }; + int invalid_padding = 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 +449,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 +464,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,13 +475,17 @@ 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); + if (ret == MBEDTLS_ERR_CIPHER_INVALID_PADDING) { + invalid_padding = 1; + } else if (ret != 0) { + status = mbedtls_to_psa_error(ret); + goto exit; } } else { *output_length = esp_aes_driver_ctx->block_length; @@ -481,9 +501,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 +514,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 +526,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(mbedtls_ct_bool(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 +545,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 +660,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; } diff --git a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c index 028c5a72e60..a8f7c255885 100644 --- a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c +++ b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c @@ -6,6 +6,7 @@ #include #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; @@ -90,6 +99,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 +111,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 +129,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 +151,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 +180,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 +247,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); diff --git a/components/mbedtls/port/psa_driver/esp_ecdsa/psa_crypto_driver_esp_ecdsa.c b/components/mbedtls/port/psa_driver/esp_ecdsa/psa_crypto_driver_esp_ecdsa.c index eed84dce00d..749d1d213ed 100644 --- a/components/mbedtls/port/psa_driver/esp_ecdsa/psa_crypto_driver_esp_ecdsa.c +++ b/components/mbedtls/port/psa_driver/esp_ecdsa/psa_crypto_driver_esp_ecdsa.c @@ -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}; @@ -1156,7 +1189,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 +1217,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( diff --git a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_cmac.c b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_cmac.c index 0eaa6d1c1e5..4de2a593b72 100644 --- a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_cmac.c +++ b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_cmac.c @@ -66,20 +66,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 +88,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 +121,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 +153,19 @@ 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 (data_length == 0) { + return PSA_SUCCESS; + } + + if (esp_cmac_ctx->alg == 0) { + return PSA_ERROR_BAD_STATE; + } 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,7 @@ psa_status_t esp_cmac_finish( exit: mbedtls_platform_zeroize(K1, sizeof(K1)); mbedtls_platform_zeroize(K2, sizeof(K2)); - - 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); + mbedtls_platform_zeroize(M_last, sizeof(M_last)); return status; } @@ -384,7 +410,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; } diff --git a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c index db6185a6505..f5bb67f73e5 100644 --- a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c +++ b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c @@ -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,6 +269,7 @@ 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; @@ -273,9 +278,20 @@ psa_status_t esp_hmac_setup_opaque( psa_status_t esp_hmac_update_opaque(esp_hmac_opaque_operation_t *esp_hmac_ctx, const uint8_t *data, size_t data_length) { - if (!esp_hmac_ctx || !data || data_length == 0) { + 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; + } hmac_key_id_t hmac_key_id = 0; @@ -331,12 +347,17 @@ psa_status_t esp_hmac_update_opaque(esp_hmac_opaque_operation_t *esp_hmac_ctx, c } #endif /* SOC_KEY_MANAGER_SUPPORTED && !ESP_TEE_BUILD */ + if (hmac_ret == ESP_OK) { + esp_hmac_ctx->computed = true; + return PSA_SUCCESS; + } + + mbedtls_platform_zeroize(esp_hmac_ctx->hmac, sizeof(esp_hmac_ctx->hmac)); + if (hmac_ret == ESP_ERR_INVALID_ARG) { return PSA_ERROR_INVALID_ARGUMENT; } else if (hmac_ret == ESP_FAIL) { return PSA_ERROR_HARDWARE_FAILURE; - } else if (hmac_ret == ESP_OK) { - return PSA_SUCCESS; } return PSA_ERROR_CORRUPTION_DETECTED; @@ -352,12 +373,20 @@ 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 || !esp_hmac_ctx->computed) { + 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; + } + + /* 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 +408,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 +436,15 @@ 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; + } + + 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; diff --git a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c index 01bb37963d5..f2e65c9c653 100644 --- a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c +++ b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c @@ -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 (data_length == 0) { + return PSA_SUCCESS; + } + + if (esp_hmac_ctx->alg == 0) { + return PSA_ERROR_BAD_STATE; + } #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]; @@ -244,6 +275,16 @@ psa_status_t esp_hmac_finish_transparent( } /* 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); @@ -357,7 +398,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; } diff --git a/components/mbedtls/port/psa_driver/esp_md/psa_crypto_driver_esp_md5.c b/components/mbedtls/port/psa_driver/esp_md/psa_crypto_driver_esp_md5.c index b903212465a..7b35a75663e 100644 --- a/components/mbedtls/port/psa_driver/esp_md/psa_crypto_driver_esp_md5.c +++ b/components/mbedtls/port/psa_driver/esp_md/psa_crypto_driver_esp_md5.c @@ -5,6 +5,7 @@ */ #include +#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; } diff --git a/components/mbedtls/port/psa_driver/esp_rsa_ds/include/psa_crypto_driver_esp_rsa_ds_utilities.h b/components/mbedtls/port/psa_driver/esp_rsa_ds/include/psa_crypto_driver_esp_rsa_ds_utilities.h index e1462d5a4c1..c3677155199 100644 --- a/components/mbedtls/port/psa_driver/esp_rsa_ds/include/psa_crypto_driver_esp_rsa_ds_utilities.h +++ b/components/mbedtls/port/psa_driver/esp_rsa_ds/include/psa_crypto_driver_esp_rsa_ds_utilities.h @@ -91,7 +91,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 } diff --git a/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c b/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c index da12c90749a..e7ce69e4b14 100644 --- a/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c +++ b/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c @@ -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; } @@ -545,14 +578,6 @@ psa_status_t esp_rsa_ds_opaque_sign_hash_complete( *signature_length = expected_signature_size; - 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; } @@ -583,7 +608,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 +617,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 +645,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 +788,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 +808,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 +855,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 +870,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 +909,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 +937,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; } diff --git a/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds_utilities.c b/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds_utilities.c index fc19cfce2c3..e5acfa0d836 100644 --- a/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds_utilities.c +++ b/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds_utilities.c @@ -445,7 +445,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 +514,8 @@ 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); + mbedtls_platform_zeroize(lhash, sizeof(lhash)); return PSA_ERROR_INVALID_ARGUMENT; } diff --git a/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha1.c b/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha1.c index 5e7102ac828..b4193d122c2 100644 --- a/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha1.c +++ b/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha1.c @@ -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 #include #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; } diff --git a/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha256.c b/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha256.c index 434023b127a..078b54a2770 100644 --- a/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha256.c +++ b/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha256.c @@ -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 #include #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; } diff --git a/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha512.c b/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha512.c index b1078efab0b..c76af5b0eec 100644 --- a/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha512.c +++ b/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha512.c @@ -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 #include #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; } diff --git a/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha1.c b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha1.c index 160ff865598..55065eb0032 100644 --- a/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha1.c +++ b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha1.c @@ -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 @@ -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) \ @@ -409,6 +410,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 +426,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 +459,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; } diff --git a/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha256.c b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha256.c index 4d99864dfe9..81d828ab59f 100644 --- a/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha256.c +++ b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha256.c @@ -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 @@ -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) @@ -187,6 +188,11 @@ static void esp_sha256_software_process(esp_sha256_context *ctx, const unsigned for ( i = 0; i < 8; i++ ) { ctx->state[i] += A[i]; } + + mbedtls_platform_zeroize(W, sizeof(W)); + mbedtls_platform_zeroize(A, sizeof(A)); + temp1 = temp2 = 0; + (void)temp1; (void)temp2; } static int esp_internal_sha256_parallel_engine_process(esp_sha256_context *ctx, const unsigned char data[64], bool read_digest) { @@ -346,6 +352,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 +383,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 +442,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; } diff --git a/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha512.c b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha512.c index d58420ab1fd..a2bf53d40e0 100644 --- a/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha512.c +++ b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha512.c @@ -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 @@ -205,6 +206,12 @@ static void esp_sha512_software_process(esp_sha512_context *ctx, const unsigned ctx->state[5] += F; ctx->state[6] += G; ctx->state[7] += H; + + mbedtls_platform_zeroize(W, sizeof(W)); + A = B = C = D = E = F = G = H = 0; + temp1 = temp2 = 0; + (void)A; (void)B; (void)C; (void)D; (void)E; (void)F; (void)G; (void)H; + (void)temp1; (void)temp2; } static int esp_internal_sha512_parallel_engine_process( esp_sha512_context *ctx, const unsigned char data[128], bool read_digest ) @@ -349,6 +356,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 +379,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 +455,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; } diff --git a/components/mbedtls/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c b/components/mbedtls/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c index 8c3feda61d4..f47b571296a 100644 --- a/components/mbedtls/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c +++ b/components/mbedtls/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ #include +#include #include #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,7 +217,13 @@ 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; } #ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1 @@ -213,7 +244,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 +257,168 @@ 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; + } + + *hash_length = expected_size; + if (hash_size != 0) { + memset(hash, '!', hash_size); + } + #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; } diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque_contexts.h index bf66e66b45d..8ebb4060923 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque_contexts.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_opaque_contexts.h @@ -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 */ diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent_contexts.h index 0ad70ca7b1f..195d946f067 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent_contexts.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_hmac_transparent_contexts.h @@ -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; diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_md5.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_md5.h index 9705ae3319d..5a66d2a30f8 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_md5.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_md5.h @@ -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 } diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_md5_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_md5_contexts.h new file mode 100644 index 00000000000..ac10b4f6a28 --- /dev/null +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_md5_contexts.h @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#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 From 33cb603e02e44c283ac96094254caf82d9cabac3 Mon Sep 17 00:00:00 2001 From: Ashish Sharma Date: Tue, 26 May 2026 10:36:07 +0800 Subject: [PATCH 2/3] fix(mbedtls/port): add additional hardening for PSA drivers --- components/mbedtls/mbedtls | 2 +- .../esp_aes/psa_crypto_driver_esp_aes.c | 46 ++-- .../esp_aes/psa_crypto_driver_esp_aes_gcm.c | 6 +- .../esp_ecdsa/psa_crypto_driver_esp_ecdsa.c | 5 + .../esp_mac/psa_crypto_driver_esp_cmac.c | 10 +- .../psa_crypto_driver_esp_hmac_opaque.c | 170 ++++++++----- .../psa_crypto_driver_esp_hmac_transparent.c | 8 +- .../psa_crypto_driver_esp_rsa_ds_utilities.h | 2 + .../esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c | 9 +- .../psa_crypto_driver_esp_rsa_ds_utilities.c | 18 +- .../psa_crypto_driver_esp_sha1.c | 225 +++++++++--------- .../psa_crypto_driver_esp_sha256.c | 79 +++--- .../psa_crypto_driver_esp_sha512.c | 64 +++-- .../esp_sha/psa_crypto_driver_esp_sha.c | 8 +- .../test_apps/mbedtls_ut/main/test_psa_hmac.c | 69 ++++++ docs/en/api-reference/peripherals/hmac.rst | 4 + 16 files changed, 437 insertions(+), 288 deletions(-) diff --git a/components/mbedtls/mbedtls b/components/mbedtls/mbedtls index 06505cc5be2..a2b32072ea8 160000 --- a/components/mbedtls/mbedtls +++ b/components/mbedtls/mbedtls @@ -1 +1 @@ -Subproject commit 06505cc5be21602f667490e476a9bae7989ef411 +Subproject commit a2b32072ea898afc1ed5b6caf6931e36028c91d6 diff --git a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c index 60d738d5efe..fc191cdd3e5 100644 --- a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c +++ b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c @@ -104,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; } @@ -274,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)) { @@ -384,15 +405,15 @@ 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]; mbedtls_ct_condition_t bad = mbedtls_ct_uint_gt(padding_len, input_len); @@ -416,7 +437,7 @@ static int get_pkcs_padding(unsigned char *input, size_t input_len, size_t *data /* Gate *data_len on the bad flag so it does not leak padding validity. */ *data_len = mbedtls_ct_if(bad, 0, pad_idx); - return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING); + *invalid_padding = bad; } psa_status_t esp_aes_cipher_finish( @@ -428,7 +449,7 @@ psa_status_t esp_aes_cipher_finish( int ret = -1; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; uint8_t temp_output_buffer[ESP_MBEDTLS_AES_MAX_BLOCK_LENGTH] = { 0 }; - int invalid_padding = 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; @@ -480,13 +501,8 @@ psa_status_t esp_aes_cipher_finish( } 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 == MBEDTLS_ERR_CIPHER_INVALID_PADDING) { - invalid_padding = 1; - } else if (ret != 0) { - status = mbedtls_to_psa_error(ret); - goto exit; - } + 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; } @@ -530,7 +546,7 @@ psa_status_t esp_aes_cipher_finish( memcpy(output, temp_output_buffer, output_size); } - status = mbedtls_ct_error_if_else_0(mbedtls_ct_bool(invalid_padding), + 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, diff --git a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c index a8f7c255885..d255986dba5 100644 --- a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c +++ b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c @@ -55,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; diff --git a/components/mbedtls/port/psa_driver/esp_ecdsa/psa_crypto_driver_esp_ecdsa.c b/components/mbedtls/port/psa_driver/esp_ecdsa/psa_crypto_driver_esp_ecdsa.c index 749d1d213ed..44ab52e60bf 100644 --- a/components/mbedtls/port/psa_driver/esp_ecdsa/psa_crypto_driver_esp_ecdsa.c +++ b/components/mbedtls/port/psa_driver/esp_ecdsa/psa_crypto_driver_esp_ecdsa.c @@ -1102,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; } diff --git a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_cmac.c b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_cmac.c index 4de2a593b72..5c0d38e16bf 100644 --- a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_cmac.c +++ b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_cmac.c @@ -6,6 +6,7 @@ #include #include +#include "mbedtls/platform_util.h" #include "psa/crypto.h" #include "psa_crypto_driver_esp_cmac.h" #include "psa_crypto_driver_esp_cmac_contexts.h" @@ -159,13 +160,12 @@ psa_status_t esp_cmac_update(esp_cmac_operation_t *esp_cmac_ctx, const uint8_t * if (data == NULL && data_length != 0) { return PSA_ERROR_INVALID_ARGUMENT; } - if (data_length == 0) { - return PSA_SUCCESS; - } - 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; @@ -355,6 +355,8 @@ exit: mbedtls_platform_zeroize(K2, sizeof(K2)); mbedtls_platform_zeroize(M_last, sizeof(M_last)); + (void)esp_cmac_abort(esp_cmac_ctx); + return status; } diff --git a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c index f5bb67f73e5..31851d1dad4 100644 --- a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c +++ b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c @@ -276,6 +276,84 @@ psa_status_t esp_hmac_setup_opaque( return PSA_SUCCESS; } +#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) +{ + 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 *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 (status != PSA_SUCCESS) { + return status; + } + + 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 (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; + } + + 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) { @@ -293,74 +371,16 @@ psa_status_t esp_hmac_update_opaque(esp_hmac_opaque_operation_t *esp_hmac_ctx, c return PSA_ERROR_BAD_STATE; } - hmac_key_id_t hmac_key_id = 0; - -#if SOC_KEY_MANAGER_SUPPORTED && !ESP_TEE_BUILD - const esp_key_mgr_key_recovery_info_t *key_recovery_info = NULL; -#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; - } - } - - esp_err_t hmac_ret = esp_hmac_calculate(hmac_key_id, data, data_length, esp_hmac_ctx->hmac); - -#if SOC_KEY_MANAGER_SUPPORTED && !ESP_TEE_BUILD - if (key_recovery_info) { - esp_key_mgr_deactivate_key(key_recovery_info->key_type); - } -#endif /* SOC_KEY_MANAGER_SUPPORTED && !ESP_TEE_BUILD */ - - if (hmac_ret == ESP_OK) { - esp_hmac_ctx->computed = true; + /* + * 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; } - mbedtls_platform_zeroize(esp_hmac_ctx->hmac, sizeof(esp_hmac_ctx->hmac)); - - if (hmac_ret == ESP_ERR_INVALID_ARG) { - return PSA_ERROR_INVALID_ARGUMENT; - } else if (hmac_ret == ESP_FAIL) { - return PSA_ERROR_HARDWARE_FAILURE; - } - - return PSA_ERROR_CORRUPTION_DETECTED; + return esp_hmac_opaque_calculate(esp_hmac_ctx, data, data_length); } psa_status_t esp_hmac_finish_opaque( @@ -373,7 +393,7 @@ psa_status_t esp_hmac_finish_opaque( return PSA_ERROR_INVALID_ARGUMENT; } - if (esp_hmac_ctx->alg == 0 || !esp_hmac_ctx->computed) { + if (esp_hmac_ctx->alg == 0) { return PSA_ERROR_BAD_STATE; } @@ -381,6 +401,20 @@ psa_status_t esp_hmac_finish_opaque( 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); @@ -444,6 +478,10 @@ psa_status_t esp_hmac_verify_finish_opaque( 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) { diff --git a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c index f2e65c9c653..f2b362825e2 100644 --- a/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c +++ b/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_transparent.c @@ -221,13 +221,13 @@ psa_status_t esp_hmac_update_transparent(esp_hmac_transparent_operation_t *esp_h 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 (esp_hmac_ctx->alg == 0) { - return PSA_ERROR_BAD_STATE; - } #if defined(ESP_MD5_DRIVER_ENABLED) psa_algorithm_t hash_alg = PSA_ALG_GET_HASH(esp_hmac_ctx->alg); @@ -271,6 +271,7 @@ 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. */ @@ -342,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; } diff --git a/components/mbedtls/port/psa_driver/esp_rsa_ds/include/psa_crypto_driver_esp_rsa_ds_utilities.h b/components/mbedtls/port/psa_driver/esp_rsa_ds/include/psa_crypto_driver_esp_rsa_ds_utilities.h index c3677155199..53befa233ce 100644 --- a/components/mbedtls/port/psa_driver/esp_rsa_ds/include/psa_crypto_driver_esp_rsa_ds_utilities.h +++ b/components/mbedtls/port/psa_driver/esp_rsa_ds/include/psa_crypto_driver_esp_rsa_ds_utilities.h @@ -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 diff --git a/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c b/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c index e7ce69e4b14..af0a812cdcc 100644 --- a/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c +++ b/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds.c @@ -563,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; @@ -577,8 +579,11 @@ psa_status_t esp_rsa_ds_opaque_sign_hash_complete( } *signature_length = expected_signature_size; + status = PSA_SUCCESS; - 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( diff --git a/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds_utilities.c b/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds_utilities.c index e5acfa0d836..84b3cd562bb 100644 --- a/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds_utilities.c +++ b/components/mbedtls/port/psa_driver/esp_rsa_ds/psa_crypto_driver_esp_rsa_ds_utilities.c @@ -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 �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 �5.5 (e) and RFC 8017 - * (PKCS#1 v2.2) �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; @@ -515,7 +520,6 @@ psa_status_t esp_rsa_ds_pad_oaep_unpad(unsigned char *input, if (bad != MBEDTLS_CT_FALSE) { *olen = 0; mbedtls_platform_zeroize(input, ilen); - mbedtls_platform_zeroize(lhash, sizeof(lhash)); return PSA_ERROR_INVALID_ARGUMENT; } diff --git a/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha1.c b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha1.c index 55065eb0032..1d3e5c9f20c 100644 --- a/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha1.c +++ b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha1.c @@ -78,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) \ @@ -111,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 @@ -147,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 @@ -174,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 @@ -201,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 ) diff --git a/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha256.c b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha256.c index 81d828ab59f..b7119f9be5c 100644 --- a/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha256.c +++ b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha256.c @@ -123,76 +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]; } - mbedtls_platform_zeroize(W, sizeof(W)); - mbedtls_platform_zeroize(A, sizeof(A)); - temp1 = temp2 = 0; - (void)temp1; (void)temp2; + /* 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) { @@ -325,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: diff --git a/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha512.c b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha512.c index a2bf53d40e0..f52db5d12fa 100644 --- a/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha512.c +++ b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha512.c @@ -146,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))) @@ -163,55 +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(W, sizeof(W)); - A = B = C = D = E = F = G = H = 0; - temp1 = temp2 = 0; - (void)A; (void)B; (void)C; (void)D; (void)E; (void)F; (void)G; (void)H; - (void)temp1; (void)temp2; + 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 ) @@ -244,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) { diff --git a/components/mbedtls/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c b/components/mbedtls/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c index f47b571296a..44370cb098e 100644 --- a/components/mbedtls/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c +++ b/components/mbedtls/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c @@ -226,6 +226,9 @@ psa_status_t esp_sha_hash_update( 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; @@ -276,11 +279,6 @@ psa_status_t esp_sha_hash_finish( return PSA_ERROR_BUFFER_TOO_SMALL; } - *hash_length = expected_size; - if (hash_size != 0) { - memset(hash, '!', hash_size); - } - #ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1 if (operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA1) { return esp_sha1_driver_finish((esp_sha1_context *)operation->sha_ctx, diff --git a/components/mbedtls/test_apps/mbedtls_ut/main/test_psa_hmac.c b/components/mbedtls/test_apps/mbedtls_ut/main/test_psa_hmac.c index 1cc551b8e08..a97b1195745 100644 --- a/components/mbedtls/test_apps/mbedtls_ut/main/test_psa_hmac.c +++ b/components/mbedtls/test_apps/mbedtls_ut/main/test_psa_hmac.c @@ -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 */ diff --git a/docs/en/api-reference/peripherals/hmac.rst b/docs/en/api-reference/peripherals/hmac.rst index bed3555eefa..cb79b78394c 100644 --- a/docs/en/api-reference/peripherals/hmac.rst +++ b/docs/en/api-reference/peripherals/hmac.rst @@ -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 ------------- From b75d565c3545438976b0654d26857591c2fd6bce Mon Sep 17 00:00:00 2001 From: renpeiying Date: Wed, 24 Jun 2026 17:03:04 +0800 Subject: [PATCH 3/3] udpate CN trans for hmac --- docs/zh_CN/api-reference/peripherals/hmac.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/zh_CN/api-reference/peripherals/hmac.rst b/docs/zh_CN/api-reference/peripherals/hmac.rst index 53fb41ed9de..cd027012d70 100644 --- a/docs/zh_CN/api-reference/peripherals/hmac.rst +++ b/docs/zh_CN/api-reference/peripherals/hmac.rst @@ -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 参考 -------------