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 <ronald.cron@arm.com>
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 3a286aa..a8df97f 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -3502,8 +3502,8 @@
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 @@
.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 @@
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;