cc3xx: extend psa aead tests to verify inline PSA operations

When PSA_FRAMEWORK_HAS_MM_IOVEC is disabled, input / output buffers are
not directly passed to the backend PSA calls, but scratch buffers are
used.

However, when PSA_FRAMEWORK_HAS_MM_IOVEC is enabled, it forces
zero-copying by passing the buffers directly. As there are cases where
the input buffer is the same as the output buffer, it is important to
cover the testing of such scenarios. This change achieves that.

Change-Id: Ie8d048efa406c700ebd46fd362e123a21111eb91
Signed-off-by: Amjad Ouled-Ameur <amjad.ouled-ameur@arm.com>
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 6ffc284..518e730 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
@@ -1752,6 +1752,7 @@
                    const uint8_t *key,
                    size_t key_bits,
                    size_t chunk_size,
+                   enum psa_test_iovec_inline inline_conf,
                    struct test_result_t *ret)
 {
     psa_aead_operation_t encop = psa_aead_operation_init();
@@ -1764,10 +1765,13 @@
         "This is my plaintext message and it's made of 68 characters...!1234";
     const uint8_t associated_data[] =
         "This is my associated data to authenticate";
+    const uint8_t inline_buf[ENC_DEC_BUFFER_SIZE_AEAD] = {0};
     uint8_t decrypted_data[MAX_PLAIN_DATA_SIZE_AEAD] = {0};
     uint8_t encrypted_data[ENC_DEC_BUFFER_SIZE_AEAD] = {0};
+    uint8_t *input_buffer, *output_buffer;
     size_t encrypted_data_length = 0, decrypted_data_length = 0;
     size_t total_output_length = 0, total_encrypted_length = 0;
+    uint8_t *tag;
     uint32_t comp_result;
     psa_key_attributes_t key_attributes = psa_key_attributes_init();
     psa_key_attributes_t retrieved_attributes = psa_key_attributes_init();
@@ -1775,14 +1779,23 @@
 #ifdef TFM_CRYPTO_TEST_SINGLE_PART_FUNCS
     uint8_t encrypted_data_single_shot[ENC_DEC_BUFFER_SIZE_AEAD] = {0};
 #endif
+    bool is_inline = (inline_conf == PSA_TEST_IOVEC_INLINED) ? true : false;
 
     /* Variables required for multipart operations */
-    uint8_t *tag = &encrypted_data[MAX_PLAIN_DATA_SIZE_AEAD];
     size_t tag_size = PSA_AEAD_TAG_LENGTH(key_type,
                                           psa_get_key_bits(&key_attributes),
                                           alg);
     size_t tag_length = 0;
 
+    if (is_inline) {
+        /* Initialise inline buffer with plaintext data */
+        memcpy(inline_buf, plain_text, sizeof(plain_text));
+
+        tag = &inline_buf[MAX_PLAIN_DATA_SIZE_AEAD];
+    } else {
+        tag = &encrypted_data[MAX_PLAIN_DATA_SIZE_AEAD];
+    }
+
     ret->val = TEST_PASSED;
 
     if (sizeof(encop) != sizeof(uint32_t)) {
@@ -1824,12 +1837,20 @@
 
 #ifdef TFM_CRYPTO_TEST_SINGLE_PART_FUNCS
     /* Perform AEAD encryption */
+    if (is_inline) {
+        input_buffer = inline_buf;
+        output_buffer = inline_buf;
+    } else {
+        input_buffer = plain_text;
+        output_buffer = encrypted_data;
+    }
+
     status = psa_aead_encrypt(key_id_local, alg, nonce, nonce_length,
                               associated_data,
                               sizeof(associated_data),
-                              plain_text,
+                              input_buffer,
                               sizeof(plain_text),
-                              encrypted_data,
+                              output_buffer,
                               sizeof(encrypted_data),
                               &encrypted_data_length);
 
@@ -1856,15 +1877,20 @@
         TEST_FAIL("Encrypted data length is above the maximum expected value");
         goto destroy_key_aead;
     }
-    memcpy(encrypted_data_single_shot, encrypted_data, encrypted_data_length);
+    memcpy(encrypted_data_single_shot, output_buffer, encrypted_data_length);
+
+    if (!is_inline) {
+        input_buffer = encrypted_data;
+        output_buffer = decrypted_data;
+    }
 
     /* Perform AEAD decryption */
     status = psa_aead_decrypt(key_id_local, alg, nonce, nonce_length,
                               associated_data,
                               sizeof(associated_data),
-                              encrypted_data,
+                              input_buffer,
                               encrypted_data_length,
-                              decrypted_data,
+                              output_buffer,
                               sizeof(decrypted_data),
                               &decrypted_data_length);
 
@@ -1884,7 +1910,7 @@
     }
 
     /* Check that the decrypted data is the same as the original data */
-    comp_result = memcmp(plain_text, decrypted_data, sizeof(plain_text));
+    comp_result = memcmp(plain_text, output_buffer, sizeof(plain_text));
     if (comp_result != 0) {
         TEST_FAIL("Decrypted data doesn't match with plain text");
         goto destroy_key_aead;
@@ -1967,6 +1993,17 @@
         goto destroy_key_aead;
     }
 
+    if (is_inline) {
+        memcpy(inline_buf, plain_text, sizeof(plain_text));
+        //memset(inline_buf + sizeof(plain_text), 0, PSA_AEAD_TAG_MAX_SIZE);
+
+        input_buffer = inline_buf;
+        output_buffer = inline_buf;
+    } else {
+        input_buffer = plain_text;
+        output_buffer = encrypted_data;
+    }
+
     /* Encrypt one chunk of information at a time */
     for (size_t i = 0;
          i < ROUND_UP(sizeof(plain_text), chunk_size) / chunk_size;
@@ -1976,9 +2013,9 @@
             chunk_size : (sizeof(plain_text) - i*chunk_size);
 
         status = psa_aead_update(&encop,
-                                 plain_text + i*chunk_size,
+                                 input_buffer + i*chunk_size,
                                  size_to_encrypt,
-                                 encrypted_data + total_encrypted_length,
+                                 output_buffer + total_encrypted_length,
                                  sizeof(encrypted_data) -
                                                       total_encrypted_length,
                                  &encrypted_data_length);
@@ -1996,7 +2033,7 @@
 
     /* Finish the aead operation */
     status = psa_aead_finish(&encop,
-                             encrypted_data + total_encrypted_length,
+                             output_buffer + total_encrypted_length,
                              sizeof(encrypted_data) - total_encrypted_length,
                              &encrypted_data_length,
                              tag,
@@ -2024,7 +2061,7 @@
     /* Compare encrypted data between single part and multipart case */
     comp_result = memcmp(
                       encrypted_data_single_shot,
-                      encrypted_data, total_encrypted_length);
+                      output_buffer, total_encrypted_length);
     if (comp_result != 0) {
         TEST_FAIL("Single shot encrypted data does not match with multipart");
         goto destroy_key_aead;
@@ -2075,6 +2112,14 @@
         goto destroy_key_aead;
     }
 
+    if (is_inline) {
+        input_buffer = inline_buf;
+        output_buffer = inline_buf;
+    } else {
+        input_buffer = encrypted_data;
+        output_buffer = decrypted_data;
+    }
+
     /* Decrypt */
     for (size_t i = 0;
         i < ROUND_UP(total_encrypted_length, chunk_size) / chunk_size;
@@ -2084,9 +2129,9 @@
             chunk_size : (total_encrypted_length - i*chunk_size);
 
         status = psa_aead_update(&decop,
-                                 encrypted_data + i*chunk_size,
+                                 input_buffer + i*chunk_size,
                                  size_to_decrypt,
-                                 decrypted_data + total_output_length,
+                                 output_buffer + total_output_length,
                                  sizeof(decrypted_data)
                                                        - total_output_length,
                                  &decrypted_data_length);
@@ -2104,7 +2149,7 @@
 
     /* Verify the AEAD operation */
     status = psa_aead_verify(&decop,
-                             decrypted_data + total_output_length,
+                             output_buffer + total_output_length,
                              sizeof(decrypted_data) - total_output_length,
                              &decrypted_data_length,
                              tag,
@@ -2129,7 +2174,7 @@
     }
 
     /* Check that the decrypted data is the same as the original data */
-    comp_result = memcmp(plain_text, decrypted_data, sizeof(plain_text));
+    comp_result = memcmp(plain_text, output_buffer, sizeof(plain_text));
     if (comp_result != 0) {
         TEST_FAIL("Decrypted data doesn't match with plain text");
     }
diff --git a/tests_reg/test/secure_fw/suites/crypto/crypto_tests_common.h b/tests_reg/test/secure_fw/suites/crypto/crypto_tests_common.h
index 1eecc85..a87f13a 100644
--- a/tests_reg/test/secure_fw/suites/crypto/crypto_tests_common.h
+++ b/tests_reg/test/secure_fw/suites/crypto/crypto_tests_common.h
@@ -16,6 +16,11 @@
 #include "test_framework_helpers.h"
 #include "crypto_tests_check_config.h"
 
+enum psa_test_iovec_inline {
+    PSA_TEST_IOVEC_INLINED,
+    PSA_TEST_IOVEC_NOT_INLINED,
+};
+
 /**
  * \brief Size of the key to use in tests in bits
  *
@@ -201,12 +206,13 @@
 /**
  * \brief Run AEAD tests with different algorithms and key types
  *
- * \param[in]  key_type   PSA key type
- * \param[in]  alg        PSA algorithm
- * \param[in]  key        Encryption key
- * \param[in]  key_bits   Encryption key size in bits
- * \param[in]  chunk_size Chunk size in bytes
- * \param[out] ret        Test result
+ * \param[in]  key_type    PSA key type
+ * \param[in]  alg         PSA algorithm
+ * \param[in]  key         Encryption key
+ * \param[in]  key_bits    Encryption key size in bits
+ * \param[in]  inline_conf inline config of IOVEC buffers
+ * \param[in]  chunk_size  Chunk size in bytes
+ * \param[out] ret         Test result
  *
  */
 void psa_aead_test(const psa_key_type_t key_type,
@@ -214,6 +220,7 @@
                    const uint8_t *key,
                    size_t key_bits,
                    size_t chunk_size,
+                   enum psa_test_iovec_inline inline_conf,
                    struct test_result_t *ret);
 /**
  * \brief Tests invalid key length
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 ef14da3..1906571 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
@@ -424,15 +424,41 @@
 {
     psa_aead_test(PSA_KEY_TYPE_AES, PSA_ALG_CCM,
                   test_key_128, BIT_SIZE_TEST_KEY,
-                  BYTE_SIZE_CHUNK, ret);
+                  BYTE_SIZE_CHUNK,
+                  PSA_TEST_IOVEC_NOT_INLINED,
+                  ret);
 
     psa_aead_test(PSA_KEY_TYPE_AES, PSA_ALG_CCM,
-                test_key_128, BIT_SIZE_TEST_KEY,
-                BYTE_SIZE_CHUNK / 3, ret);
+                  test_key_128, BIT_SIZE_TEST_KEY,
+                  BYTE_SIZE_CHUNK / 3,
+                  PSA_TEST_IOVEC_NOT_INLINED,
+                  ret);
 
     psa_aead_test(PSA_KEY_TYPE_AES, PSA_ALG_CCM,
-                test_key_128, BIT_SIZE_TEST_KEY,
-                BYTE_SIZE_CHUNK / 4, ret);
+                  test_key_128, BIT_SIZE_TEST_KEY,
+                  BYTE_SIZE_CHUNK / 4,
+                  PSA_TEST_IOVEC_NOT_INLINED,
+                  ret);
+
+    /* Inline Tests */
+    TEST_LOG("Inlined iovec\n");
+    psa_aead_test(PSA_KEY_TYPE_AES, PSA_ALG_CCM,
+                  test_key_128, BIT_SIZE_TEST_KEY,
+                  BYTE_SIZE_CHUNK,
+                  PSA_TEST_IOVEC_INLINED,
+                  ret);
+
+    psa_aead_test(PSA_KEY_TYPE_AES, PSA_ALG_CCM,
+                  test_key_128, BIT_SIZE_TEST_KEY,
+                  BYTE_SIZE_CHUNK / 3,
+                  PSA_TEST_IOVEC_INLINED,
+                  ret);
+
+    psa_aead_test(PSA_KEY_TYPE_AES, PSA_ALG_CCM,
+                  test_key_128, BIT_SIZE_TEST_KEY,
+                  BYTE_SIZE_CHUNK / 4,
+                  PSA_TEST_IOVEC_INLINED,
+                  ret);
 }
 #endif /* TFM_CRYPTO_TEST_ALG_CCM */
 
@@ -441,7 +467,9 @@
 {
     psa_aead_test(PSA_KEY_TYPE_AES, PSA_ALG_GCM,
                   test_key_128, BIT_SIZE_TEST_KEY,
-                  BYTE_SIZE_CHUNK, ret);
+                  BYTE_SIZE_CHUNK,
+                  PSA_TEST_IOVEC_NOT_INLINED,
+                  ret);
 }
 #endif /* TFM_CRYPTO_TEST_ALG_GCM */
 
@@ -470,15 +498,40 @@
 
     psa_aead_test(PSA_KEY_TYPE_AES, alg,
                   test_key_128, BIT_SIZE_TEST_KEY,
-                  BYTE_SIZE_CHUNK, ret);
+                  BYTE_SIZE_CHUNK,
+                  PSA_TEST_IOVEC_NOT_INLINED,
+                  ret);
 
     psa_aead_test(PSA_KEY_TYPE_AES, alg,
                   test_key_128, BIT_SIZE_TEST_KEY,
-                  BYTE_SIZE_CHUNK / 3, ret);
+                  BYTE_SIZE_CHUNK / 3,
+                  PSA_TEST_IOVEC_NOT_INLINED,
+                  ret);
 
     psa_aead_test(PSA_KEY_TYPE_AES, alg,
                   test_key_128, BIT_SIZE_TEST_KEY,
-                  BYTE_SIZE_CHUNK / 4, ret);
+                  BYTE_SIZE_CHUNK / 4,
+                  PSA_TEST_IOVEC_NOT_INLINED,
+                  ret);
+
+    /* Inline Tests */
+    psa_aead_test(PSA_KEY_TYPE_AES, alg,
+                  test_key_128, BIT_SIZE_TEST_KEY,
+                  BYTE_SIZE_CHUNK,
+                  PSA_TEST_IOVEC_INLINED,
+                  ret);
+
+    psa_aead_test(PSA_KEY_TYPE_AES, alg,
+                  test_key_128, BIT_SIZE_TEST_KEY,
+                  BYTE_SIZE_CHUNK / 3,
+                  PSA_TEST_IOVEC_INLINED,
+                  ret);
+
+    psa_aead_test(PSA_KEY_TYPE_AES, alg,
+                  test_key_128, BIT_SIZE_TEST_KEY,
+                  BYTE_SIZE_CHUNK / 4,
+                  PSA_TEST_IOVEC_INLINED,
+                  ret);
 }
 #endif /* TFM_CRYPTO_TEST_ALG_CCM */
 
diff --git a/tests_reg/test/secure_fw/suites/crypto/secure/crypto_sec_interface_testsuite.c b/tests_reg/test/secure_fw/suites/crypto/secure/crypto_sec_interface_testsuite.c
index 93bc5ed..4ef0309 100644
--- a/tests_reg/test/secure_fw/suites/crypto/secure/crypto_sec_interface_testsuite.c
+++ b/tests_reg/test/secure_fw/suites/crypto/secure/crypto_sec_interface_testsuite.c
@@ -421,15 +421,39 @@
 {
     psa_aead_test(PSA_KEY_TYPE_AES, PSA_ALG_CCM,
                   test_key_128, BIT_SIZE_TEST_KEY,
-                  BYTE_SIZE_CHUNK, ret);
+                  BYTE_SIZE_CHUNK,
+                  PSA_TEST_IOVEC_NOT_INLINED,
+                  ret);
 
     psa_aead_test(PSA_KEY_TYPE_AES, PSA_ALG_CCM,
-                test_key_128, BIT_SIZE_TEST_KEY,
-                BYTE_SIZE_CHUNK / 3, ret);
+                  test_key_128, BIT_SIZE_TEST_KEY,
+                  BYTE_SIZE_CHUNK / 3,
+                  PSA_TEST_IOVEC_NOT_INLINED,
+                  ret);
 
     psa_aead_test(PSA_KEY_TYPE_AES, PSA_ALG_CCM,
-                test_key_128, BIT_SIZE_TEST_KEY,
-                BYTE_SIZE_CHUNK / 4, ret);
+                  test_key_128, BIT_SIZE_TEST_KEY,
+                  BYTE_SIZE_CHUNK / 4,
+                  PSA_TEST_IOVEC_NOT_INLINED,
+                  ret);
+
+    psa_aead_test(PSA_KEY_TYPE_AES, PSA_ALG_CCM,
+                  test_key_128, BIT_SIZE_TEST_KEY,
+                  BYTE_SIZE_CHUNK,
+                  PSA_TEST_IOVEC_INLINED,
+                  ret);
+
+    psa_aead_test(PSA_KEY_TYPE_AES, PSA_ALG_CCM,
+                  test_key_128, BIT_SIZE_TEST_KEY,
+                  BYTE_SIZE_CHUNK / 3,
+                  PSA_TEST_IOVEC_INLINED,
+                  ret);
+
+    psa_aead_test(PSA_KEY_TYPE_AES, PSA_ALG_CCM,
+                  test_key_128, BIT_SIZE_TEST_KEY,
+                  BYTE_SIZE_CHUNK / 4,
+                  PSA_TEST_IOVEC_INLINED,
+                  ret);
 }
 #endif /* TFM_CRYPTO_TEST_ALG_CCM */
 
@@ -438,7 +462,9 @@
 {
     psa_aead_test(PSA_KEY_TYPE_AES, PSA_ALG_GCM,
                   test_key_128, BIT_SIZE_TEST_KEY,
-                  BYTE_SIZE_CHUNK, ret);
+                  BYTE_SIZE_CHUNK,
+                  PSA_TEST_IOVEC_NOT_INLINED,
+                  ret);
 }
 #endif /* TFM_CRYPTO_TEST_ALG_GCM */
 
@@ -507,15 +533,39 @@
 
     psa_aead_test(PSA_KEY_TYPE_AES, alg,
                   test_key_128, BIT_SIZE_TEST_KEY,
-                  BYTE_SIZE_CHUNK, ret);
+                  BYTE_SIZE_CHUNK,
+                  PSA_TEST_IOVEC_NOT_INLINED,
+                  ret);
 
     psa_aead_test(PSA_KEY_TYPE_AES, alg,
                   test_key_128, BIT_SIZE_TEST_KEY,
-                  BYTE_SIZE_CHUNK / 3, ret);
+                  BYTE_SIZE_CHUNK / 3,
+                  PSA_TEST_IOVEC_NOT_INLINED,
+                  ret);
 
     psa_aead_test(PSA_KEY_TYPE_AES, alg,
                   test_key_128, BIT_SIZE_TEST_KEY,
-                  BYTE_SIZE_CHUNK / 4, ret);
+                  BYTE_SIZE_CHUNK / 4,
+                  PSA_TEST_IOVEC_NOT_INLINED,
+                  ret);
+
+    psa_aead_test(PSA_KEY_TYPE_AES, alg,
+                  test_key_128, BIT_SIZE_TEST_KEY,
+                  BYTE_SIZE_CHUNK,
+                  PSA_TEST_IOVEC_INLINED,
+                  ret);
+
+    psa_aead_test(PSA_KEY_TYPE_AES, alg,
+                  test_key_128, BIT_SIZE_TEST_KEY,
+                  BYTE_SIZE_CHUNK / 3,
+                  PSA_TEST_IOVEC_INLINED,
+                  ret);
+
+    psa_aead_test(PSA_KEY_TYPE_AES, alg,
+                  test_key_128, BIT_SIZE_TEST_KEY,
+                  BYTE_SIZE_CHUNK / 4,
+                  PSA_TEST_IOVEC_INLINED,
+                  ret);
 }
 #endif /* TFM_CRYPTO_TEST_ALG_CCM */