Merge pull request #861 from ronald-cron-arm/fix-aead-nonce

psa: aead: Fix invalid output buffer usage in generate_nonce()
diff --git a/ChangeLog.d/fix-aead-nonce.txt b/ChangeLog.d/fix-aead-nonce.txt
new file mode 100644
index 0000000..767cc1d
--- /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 e950de4..54ae50c 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -3901,6 +3901,7 @@
                                       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 @@
         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 );