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