From c6e6f50d4783a12957f904a5d127897b05bcf706 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 9 Jul 2021 18:44:58 +0200 Subject: [PATCH] psa: cipher: Fix invalid output buffer usage in psa_cipher_encrypt() Don't use the output buffer in psa_cipher_encrypt() to pass the generated IV to the driver as local attacker could potentially control it. Signed-off-by: Ronald Cron --- library/psa_crypto.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 3a286aa037..a8df97fabd 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3502,8 +3502,8 @@ psa_status_t psa_cipher_encrypt( mbedtls_svc_key_id_t key, psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot = NULL; - psa_key_type_t key_type; - size_t iv_length; + uint8_t local_iv[PSA_CIPHER_IV_MAX_SIZE]; + size_t default_iv_length = 0; if( ! PSA_ALG_IS_CIPHER( alg ) ) { @@ -3521,26 +3521,31 @@ psa_status_t psa_cipher_encrypt( mbedtls_svc_key_id_t key, .core = slot->attr }; - key_type = slot->attr.type; - iv_length = PSA_CIPHER_IV_LENGTH( key_type, alg ); - - if( iv_length > 0 ) + default_iv_length = PSA_CIPHER_IV_LENGTH( slot->attr.type, alg ); + if( default_iv_length > PSA_CIPHER_IV_MAX_SIZE ) { - if( output_size < iv_length ) + status = PSA_ERROR_GENERIC_ERROR; + goto exit; + } + + if( default_iv_length > 0 ) + { + if( output_size < default_iv_length ) { status = PSA_ERROR_BUFFER_TOO_SMALL; goto exit; } - status = psa_generate_random( output, iv_length ); + status = psa_generate_random( local_iv, default_iv_length ); if( status != PSA_SUCCESS ) goto exit; } status = psa_driver_wrapper_cipher_encrypt( &attributes, slot->key.data, slot->key.bytes, - alg, output, iv_length, input, input_length, - output + iv_length, output_size - iv_length, output_length ); + alg, local_iv, default_iv_length, input, input_length, + output + default_iv_length, output_size - default_iv_length, + output_length ); exit: unlock_status = psa_unlock_key_slot( slot ); @@ -3548,7 +3553,11 @@ exit: status = unlock_status; if( status == PSA_SUCCESS ) - *output_length += iv_length; + { + if( default_iv_length > 0 ) + memcpy( output, local_iv, default_iv_length ); + *output_length += default_iv_length; + } else *output_length = 0;