Crypto: Amend Chacha20-Poly1305 related tests

* Support running Chacha20 in block cipher mode
* Extend RFC 7539 test vector verification to check single part
* Run RFC 7539 tests also in the Non Secure regression

Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
Change-Id: I251042d395e940f7a24a97320dc1bf3f1af83e6b
diff --git a/tests_reg/test/secure_fw/suites/crypto/crypto_tests_common.c b/tests_reg/test/secure_fw/suites/crypto/crypto_tests_common.c
index c7eef0c..954cd61 100644
--- a/tests_reg/test/secure_fw/suites/crypto/crypto_tests_common.c
+++ b/tests_reg/test/secure_fw/suites/crypto/crypto_tests_common.c
@@ -697,6 +697,10 @@
     size_t start_idx = 0;
     size_t output_length = 0; size_t total_output_length = 0;
     int comp_result;
+#ifdef TFM_CRYPTO_TEST_SINGLE_PART_FUNCS
+    uint8_t encrypted_data_single_shot[sizeof(chacha20_testPlaintext) + 16] = {0};
+    size_t encrypted_data_length, decrypted_data_length;
+#endif
 
     ret->val = TEST_PASSED;
 
@@ -712,6 +716,90 @@
         return;
     }
 
+#ifdef TFM_CRYPTO_TEST_SINGLE_PART_FUNCS
+    /* Perform AEAD encryption */
+    status = psa_aead_encrypt(key_id_local, alg,
+                              chacha20poly1305_testNonce,
+                              sizeof(chacha20poly1305_testNonce),
+                              chacha20poly1305_testAad,
+                              sizeof(chacha20poly1305_testAad),
+                              chacha20_testPlaintext,
+                              sizeof(chacha20_testPlaintext),
+                              encrypted_data_single_shot,
+                              sizeof(encrypted_data_single_shot),
+                              &encrypted_data_length);
+
+    if (status != PSA_SUCCESS) {
+        if (status == PSA_ERROR_NOT_SUPPORTED) {
+            TEST_FAIL("Algorithm NOT SUPPORTED by the implementation");
+        } else {
+            TEST_FAIL("Error performing single shot AEAD encryption");
+        }
+        goto destroy_key;
+    }
+
+    if (encrypted_data_length
+        != PSA_AEAD_ENCRYPT_OUTPUT_SIZE(key_type, alg, sizeof(chacha20_testPlaintext))) {
+        TEST_FAIL("Single shot encrypted data length is different than expected");
+        goto destroy_key;
+    }
+
+    /* Check that the encrypted data is the same as reference */
+    comp_result = memcmp(encrypted_data_single_shot,
+                         chacha20poly1305_testCiphertext_expected,
+                         sizeof(chacha20poly1305_testCiphertext_expected));
+    if (comp_result != 0) {
+        TEST_FAIL("Single shot encrypted data doesn't match with reference");
+        goto destroy_key;
+    }
+
+    /* Check that the tag matches the expected tag */
+    comp_result = memcmp(&encrypted_data_single_shot[encrypted_data_length - 16],
+                         chacha20poly1305_testTag_expected,
+                         sizeof(chacha20poly1305_testTag_expected));
+    if (comp_result != 0) {
+        TEST_FAIL("Single shot computed tag doesn't match with reference");
+        goto destroy_key;
+    }
+
+    /* Perform AEAD decryption */
+    status = psa_aead_decrypt(key_id_local, alg,
+                              chacha20poly1305_testNonce,
+                              sizeof(chacha20poly1305_testNonce),
+                              chacha20poly1305_testAad,
+                              sizeof(chacha20poly1305_testAad),
+                              encrypted_data_single_shot,
+                              encrypted_data_length,
+                              chacha20_testCiphertext,
+                              sizeof(chacha20_testCiphertext),
+                              &decrypted_data_length);
+
+    if (status != PSA_SUCCESS) {
+        if (status == PSA_ERROR_NOT_SUPPORTED) {
+            TEST_FAIL("Algorithm NOT SUPPORTED by the implementation");
+        } else {
+            TEST_FAIL("Error performing single shot AEAD decryption");
+        }
+        goto destroy_key;
+    }
+
+    if (sizeof(chacha20_testPlaintext) != decrypted_data_length) {
+        TEST_FAIL("Single shot decrypted data length is different from plain text");
+        goto destroy_key;
+    }
+
+    /* Check that the decrypted data is the same as the original data */
+    comp_result = memcmp(chacha20_testPlaintext,
+                         chacha20_testCiphertext,
+                         sizeof(chacha20_testPlaintext));
+    if (comp_result != 0) {
+        TEST_FAIL("Single shot decrypted data doesn't match with plain text");
+        goto destroy_key;
+    }
+
+    memset(chacha20_testCiphertext, 0, sizeof(chacha20_testCiphertext));
+#endif /* TFM_CRYPTO_TEST_SINGLE_PART_FUNCS */
+
     /* Setup the encryption object */
     status = psa_aead_encrypt_setup(&handle, key_id_local, alg);
     if (status != PSA_SUCCESS) {
@@ -1084,7 +1172,7 @@
     size_t data_left = sizeof(plain_text);
     while (data_left) {
         /* Encrypt one chunk of information */
-        status = psa_cipher_update(&handle, &plain_text[total_output_length],
+        status = psa_cipher_update(&handle, &plain_text[sizeof(plain_text) - data_left],
                                    BYTE_SIZE_CHUNK,
                                    &input.encrypted_data[total_output_length],
                                    ENC_DEC_BUFFER_SIZE - total_output_length,
@@ -1095,8 +1183,12 @@
             goto abort;
         }
 
-        if (output_length != BYTE_SIZE_CHUNK) {
-            TEST_FAIL("Expected encrypted length is different from expected");
+        /* When CHACHA20 is tested, if the backend does not support working in
+         * stream cipher, it will output only when it has enough data to fill a
+         * CHACHA20 block, i.e. 64 bytes
+         */
+        if (output_length != BYTE_SIZE_CHUNK && alg != PSA_ALG_STREAM_CIPHER) {
+            TEST_FAIL("Encrypted length different from expected");
             goto abort;
         }
 
@@ -1124,7 +1216,7 @@
             goto abort;
         }
     } else {
-        if (output_length != 0) {
+        if (output_length != 0 && alg != PSA_ALG_STREAM_CIPHER) {
             TEST_FAIL("Un-padded mode final output length unexpected");
             goto abort;
         }
@@ -1186,7 +1278,7 @@
             goto abort;
         }
 
-        if (!bIsLagging && output_length != BYTE_SIZE_CHUNK) {
+        if (!bIsLagging && output_length != BYTE_SIZE_CHUNK && alg != PSA_ALG_STREAM_CIPHER) {
             TEST_FAIL("Expected encrypted length is different from expected");
             goto abort;
         }
@@ -1199,7 +1291,7 @@
 
     /* Finalise the cipher operation for decryption (destroys decrypted data) */
     status = psa_cipher_finish(&handle_dec, &decrypted_data[total_output_length],
-                               BYTE_SIZE_CHUNK,
+                               ENC_DEC_BUFFER_SIZE - total_output_length,
                                &output_length);
 
     if (status != PSA_SUCCESS) {
diff --git a/tests_reg/test/secure_fw/suites/crypto/non_secure/crypto_ns_interface_testsuite.c b/tests_reg/test/secure_fw/suites/crypto/non_secure/crypto_ns_interface_testsuite.c
index 3ebffd1..43a24eb 100644
--- a/tests_reg/test/secure_fw/suites/crypto/non_secure/crypto_ns_interface_testsuite.c
+++ b/tests_reg/test/secure_fw/suites/crypto/non_secure/crypto_ns_interface_testsuite.c
@@ -92,9 +92,11 @@
 #endif /* TFM_CRYPTO_TEST_ALG_CBC */
 #ifdef TFM_CRYPTO_TEST_CHACHA20
 static void tfm_crypto_test_1048(struct test_result_t *ret);
+static void tfm_crypto_test_1051(struct test_result_t *ret);
 #endif /* TFM_CRYPTO_TEST_CHACHA20 */
 #ifdef TFM_CRYPTO_TEST_ALG_CHACHA20_POLY1305
 static void tfm_crypto_test_1049(struct test_result_t *ret);
+static void tfm_crypto_test_1052(struct test_result_t *ret);
 #endif /* TFM_CRYPTO_TEST_ALG_CHACHA20_POLY1305 */
 #ifdef TFM_CRYPTO_TEST_ALG_RSASSA_PSS_VERIFICATION
 static void tfm_crypto_test_1050(struct test_result_t *ret);
@@ -229,6 +231,14 @@
     {&tfm_crypto_test_1050, "TFM_NS_CRYPTO_TEST_1050",
      "Non Secure RSASSA-PSS signature verification (RSASSA-PSS-SHA256)"},
 #endif /* TFM_CRYPTO_TEST_ALG_RSASSA_PSS_VERIFICATION */
+#ifdef TFM_CRYPTO_TEST_CHACHA20
+    {&tfm_crypto_test_1051, "TFM_NS_CRYPTO_TEST_1051",
+     "Non Secure RFC7539 verification on Chacha20"},
+#endif /* TFM_CRYPTO_TEST_CHACHA20 */
+#ifdef TFM_CRYPTO_TEST_ALG_CHACHA20_POLY1305
+    {&tfm_crypto_test_1052, "TFM_NS_CRYPTO_TEST_1052",
+     "Non Secure RFC7539 verification on Chacha20-Poly1305"},
+#endif /* TFM_CRYPTO_TEST_ALG_CHACHA20_POLY1305 */
 };
 
 void register_testsuite_ns_crypto_interface(struct test_suite_t *p_test_suite)
@@ -499,6 +509,11 @@
     psa_cipher_test(PSA_KEY_TYPE_CHACHA20, PSA_ALG_STREAM_CIPHER,
                     test_key_256, BIT_SIZE_TEST_LONG_KEY, ret);
 }
+
+static void tfm_crypto_test_1051(struct test_result_t *ret)
+{
+    psa_cipher_rfc7539_test(ret);
+}
 #endif /* TFM_CRYPTO_TEST_CHACHA20 */
 
 #ifdef TFM_CRYPTO_TEST_ALG_CHACHA20_POLY1305
@@ -507,6 +522,11 @@
     psa_aead_test(PSA_KEY_TYPE_CHACHA20, PSA_ALG_CHACHA20_POLY1305,
                   test_key_256, BIT_SIZE_TEST_LONG_KEY, ret);
 }
+
+static void tfm_crypto_test_1052(struct test_result_t *ret)
+{
+    psa_aead_rfc7539_test(ret);
+}
 #endif /* TFM_CRYPTO_TEST_ALG_CHACHA20_POLY1305 */
 
 #ifdef TFM_CRYPTO_TEST_ALG_RSASSA_PSS_VERIFICATION