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 -------------