diff --git a/ChangeLog.d/fix-aead-nonce.txt b/ChangeLog.d/fix-aead-nonce.txt new file mode 100644 index 000000000..767cc1d4a --- /dev/null +++ b/ChangeLog.d/fix-aead-nonce.txt @@ -0,0 +1,5 @@ +Security + * In psa_aead_generate_nonce(), do not read back from the output buffer. + This fixes a potential policy bypass or decryption oracle vulnerability + if the output buffer is in memory that is shared with an untrusted + application. diff --git a/library/psa_crypto.c b/library/psa_crypto.c index e950de440..54ae50c1e 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3901,6 +3901,7 @@ psa_status_t psa_aead_generate_nonce( psa_aead_operation_t *operation, size_t *nonce_length ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + uint8_t local_nonce[PSA_AEAD_NONCE_MAX_SIZE]; size_t required_nonce_size; *nonce_length = 0; @@ -3925,15 +3926,18 @@ psa_status_t psa_aead_generate_nonce( psa_aead_operation_t *operation, goto exit; } - status = psa_generate_random( nonce, required_nonce_size ); + status = psa_generate_random( local_nonce, required_nonce_size ); if( status != PSA_SUCCESS ) goto exit; - status = psa_aead_set_nonce( operation, nonce, required_nonce_size ); + status = psa_aead_set_nonce( operation, local_nonce, required_nonce_size ); exit: if( status == PSA_SUCCESS ) + { + memcpy( nonce, local_nonce, required_nonce_size ); *nonce_length = required_nonce_size; + } else psa_aead_abort( operation );