Implement ChaCha20 and ChaCha20-Poly1305

Smoke tests: test data for ChaCha20 calculated with PyCryptodome; test
vector from RFC 7539 for ChaCha20-Poly1305.
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 3e3c5eb..7794e7a 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -51,6 +51,8 @@
 #include "mbedtls/bignum.h"
 #include "mbedtls/blowfish.h"
 #include "mbedtls/camellia.h"
+#include "mbedtls/chacha20.h"
+#include "mbedtls/chachapoly.h"
 #include "mbedtls/cipher.h"
 #include "mbedtls/ccm.h"
 #include "mbedtls/cmac.h"
@@ -179,6 +181,14 @@
         case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
             return( PSA_ERROR_HARDWARE_FAILURE );
 
+        case MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA:
+            return( PSA_ERROR_INVALID_ARGUMENT );
+
+        case MBEDTLS_ERR_CHACHAPOLY_BAD_STATE:
+            return( PSA_ERROR_BAD_STATE );
+        case MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED:
+            return( PSA_ERROR_INVALID_SIGNATURE );
+
         case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
             return( PSA_ERROR_NOT_SUPPORTED );
         case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
@@ -466,6 +476,12 @@
                 return( PSA_ERROR_INVALID_ARGUMENT );
             break;
 #endif
+#if defined(MBEDTLS_CHACHA20_C)
+        case PSA_KEY_TYPE_CHACHA20:
+            if( bits != 256 )
+                return( PSA_ERROR_INVALID_ARGUMENT );
+            break;
+#endif
         default:
             return( PSA_ERROR_NOT_SUPPORTED );
     }
@@ -2026,6 +2042,7 @@
         switch( alg )
         {
             case PSA_ALG_ARC4:
+            case PSA_ALG_CHACHA20:
                 mode = MBEDTLS_MODE_STREAM;
                 break;
             case PSA_ALG_CTR:
@@ -2049,6 +2066,9 @@
             case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
                 mode = MBEDTLS_MODE_GCM;
                 break;
+            case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CHACHA20_POLY1305, 0 ):
+                mode = MBEDTLS_MODE_CHACHAPOLY;
+                break;
             default:
                 return( NULL );
         }
@@ -2084,6 +2104,9 @@
         case PSA_KEY_TYPE_ARC4:
             cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
             break;
+        case PSA_KEY_TYPE_CHACHA20:
+            cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
+            break;
         default:
             return( NULL );
     }
@@ -3318,6 +3341,11 @@
     {
         operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type );
     }
+#if defined(MBEDTLS_CHACHA20_C)
+    else
+    if( alg == PSA_ALG_CHACHA20 )
+        operation->iv_size = 12;
+#endif
 
 exit:
     if( status == 0 )
@@ -3631,6 +3659,9 @@
 #if defined(MBEDTLS_GCM_C)
         mbedtls_gcm_context gcm;
 #endif /* MBEDTLS_GCM_C */
+#if defined(MBEDTLS_CHACHAPOLY_C)
+        mbedtls_chachapoly_context chachapoly;
+#endif /* MBEDTLS_CHACHAPOLY_C */
     } ctx;
     psa_algorithm_t core_alg;
     uint8_t full_tag_length;
@@ -3715,6 +3746,22 @@
             break;
 #endif /* MBEDTLS_GCM_C */
 
+#if defined(MBEDTLS_CHACHAPOLY_C)
+        case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CHACHA20_POLY1305, 0 ):
+            operation->core_alg = PSA_ALG_CHACHA20_POLY1305;
+            operation->full_tag_length = 16;
+            /* We only support the default tag length. */
+            if( alg != PSA_ALG_CHACHA20_POLY1305 )
+                return( PSA_ERROR_NOT_SUPPORTED );
+            mbedtls_chachapoly_init( &operation->ctx.chachapoly );
+            status = mbedtls_to_psa_error(
+                mbedtls_chachapoly_setkey( &operation->ctx.chachapoly,
+                                           operation->slot->data.raw.data ) );
+            if( status != 0 )
+                goto cleanup;
+            break;
+#endif /* MBEDTLS_CHACHAPOLY_C */
+
         default:
             return( PSA_ERROR_NOT_SUPPORTED );
     }
@@ -3792,6 +3839,26 @@
     }
     else
 #endif /* MBEDTLS_CCM_C */
+#if defined(MBEDTLS_CHACHAPOLY_C)
+    if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 )
+    {
+        if( nonce_length != 12 || operation.tag_length != 16 )
+        {
+            status = PSA_ERROR_NOT_SUPPORTED;
+            goto exit;
+        }
+        status = mbedtls_to_psa_error(
+            mbedtls_chachapoly_encrypt_and_tag( &operation.ctx.chachapoly,
+                                                plaintext_length,
+                                                nonce,
+                                                additional_data,
+                                                additional_data_length,
+                                                plaintext,
+                                                ciphertext,
+                                                tag ) );
+    }
+    else
+#endif /* MBEDTLS_CHACHAPOLY_C */
     {
         return( PSA_ERROR_NOT_SUPPORTED );
     }
@@ -3883,6 +3950,26 @@
     }
     else
 #endif /* MBEDTLS_CCM_C */
+#if defined(MBEDTLS_CHACHAPOLY_C)
+    if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 )
+    {
+        if( nonce_length != 12 || operation.tag_length != 16 )
+        {
+            status = PSA_ERROR_NOT_SUPPORTED;
+            goto exit;
+        }
+        status = mbedtls_to_psa_error(
+            mbedtls_chachapoly_auth_decrypt( &operation.ctx.chachapoly,
+                                             ciphertext_length - operation.tag_length,
+                                             nonce,
+                                             additional_data,
+                                             additional_data_length,
+                                             tag,
+                                             ciphertext,
+                                             plaintext ) );
+    }
+    else
+#endif /* MBEDTLS_CHACHAPOLY_C */
     {
         return( PSA_ERROR_NOT_SUPPORTED );
     }
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 6ea927a..6f81a8e 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -1100,6 +1100,26 @@
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
 cipher_verify_output_multipart:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"a076ec9dfbe47d52afc357336f20743b":4
 
+PSA symmetric encrypt: ChaCha20, K=0 N=0
+depends_on:MBEDTLS_CHACHA20_C
+cipher_encrypt:PSA_ALG_CHACHA20:PSA_KEY_TYPE_CHACHA20:"0000000000000000000000000000000000000000000000000000000000000000":"000000000000000000000000":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":"76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586":PSA_SUCCESS
+
+PSA symmetric encrypt: ChaCha20, K=rand N=rand
+depends_on:MBEDTLS_CHACHA20_C
+cipher_encrypt:PSA_ALG_CHACHA20:PSA_KEY_TYPE_CHACHA20:"4bddc98c551a95395ef719557f813656b566bc45aac04eca3866324cc75489f2":"a170d9349d24955aa4501891":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":"9ba7d8de0c6b579fc436e368619e09228070d23246c836d6c6b4c476af6f5eb2b78fbe809d03f7881e6af28cfe3746e8dcf1eb7f762fe7d003141f1539a6cec4":PSA_SUCCESS
+
+PSA symmetric encryption multipart: ChaCha20, 14+50 bytes
+depends_on:MBEDTLS_CHACHA20_C
+cipher_encrypt_multipart:PSA_ALG_CHACHA20:PSA_KEY_TYPE_CHACHA20:"4bddc98c551a95395ef719557f813656b566bc45aac04eca3866324cc75489f2":"a170d9349d24955aa4501891":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":14:14:50:"9ba7d8de0c6b579fc436e368619e09228070d23246c836d6c6b4c476af6f5eb2b78fbe809d03f7881e6af28cfe3746e8dcf1eb7f762fe7d003141f1539a6cec4"
+
+PSA symmetric decrypt: ChaCha20, K=rand N=rand
+depends_on:MBEDTLS_CHACHA20_C
+cipher_decrypt:PSA_ALG_CHACHA20:PSA_KEY_TYPE_CHACHA20:"4bddc98c551a95395ef719557f813656b566bc45aac04eca3866324cc75489f2":"a170d9349d24955aa4501891":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":"9ba7d8de0c6b579fc436e368619e09228070d23246c836d6c6b4c476af6f5eb2b78fbe809d03f7881e6af28cfe3746e8dcf1eb7f762fe7d003141f1539a6cec4":PSA_SUCCESS
+
+PSA symmetric decryption multipart: ChaCha20, 14+50 bytes
+depends_on:MBEDTLS_CHACHA20_C
+cipher_decrypt_multipart:PSA_ALG_CHACHA20:PSA_KEY_TYPE_CHACHA20:"4bddc98c551a95395ef719557f813656b566bc45aac04eca3866324cc75489f2":"a170d9349d24955aa4501891":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":14:14:50:"9ba7d8de0c6b579fc436e368619e09228070d23246c836d6c6b4c476af6f5eb2b78fbe809d03f7881e6af28cfe3746e8dcf1eb7f762fe7d003141f1539a6cec4"
+
 PSA AEAD encrypt/decrypt: AES-CCM, 19 bytes #1
 depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
 aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":PSA_ALG_CCM:"000102030405060708090A0B":"000102030405060708090A0B":"0C0D0E0F101112131415161718191A1B1C1D1E":PSA_SUCCESS
@@ -1280,10 +1300,26 @@
 depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
 aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 18 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
 
+PSA AEAD encrypt: ChaCha20-Poly1305 (RFC7539)
+depends_on:MBEDTLS_CHACHAPOLY_C
+aead_encrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd0600691"
+
+PSA AEAD decrypt: ChaCha20-Poly1305 (RFC7539, good tag)
+depends_on:MBEDTLS_CHACHAPOLY_C
+aead_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd0600691":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":PSA_SUCCESS
+
+PSA AEAD decrypt: ChaCha20-Poly1305 (RFC7539, bad tag)
+depends_on:MBEDTLS_CHACHAPOLY_C
+aead_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd0600690":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":PSA_ERROR_INVALID_SIGNATURE
+
 PSA AEAD encrypt/decrypt: invalid algorithm (CTR)
 depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
 aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CTR:"000102030405060708090A0B0C0D0E0F":"":"":PSA_ERROR_NOT_SUPPORTED
 
+PSA AEAD encrypt/decrypt: invalid algorithm (ChaCha20)
+depends_on:MBEDTLS_CHACHA20_C
+aead_encrypt_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20:"":"":"":PSA_ERROR_NOT_SUPPORTED
+
 PSA signature size: RSA keypair, 1024 bits, PKCS#1 v1.5 raw
 signature_size:PSA_KEY_TYPE_RSA_KEYPAIR:1024:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:128