Crypto: Add frontend support for multipart AEAD APIs

This patch adds support in the TF-M Crypto service
frontend for AEAD multipart APIs.

Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
Change-Id: I81b55bc6ae1b0e1c1c015c90577518328a3286fa
diff --git a/interface/src/tfm_crypto_func_api.c b/interface/src/tfm_crypto_func_api.c
index 2cf3fde..bcbf24c 100644
--- a/interface/src/tfm_crypto_func_api.c
+++ b/interface/src/tfm_crypto_func_api.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -135,7 +135,7 @@
     };
 
     (void)API_DISPATCH(tfm_crypto_reset_key_attributes,
-                          TFM_CRYPTO_RESET_KEY_ATTRIBUTES);
+                       TFM_CRYPTO_RESET_KEY_ATTRIBUTES);
     return;
 }
 
@@ -867,6 +867,259 @@
     return status;
 }
 
+psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation,
+                                    psa_key_id_t key,
+                                    psa_algorithm_t alg)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_AEAD_ENCRYPT_SETUP_SID,
+        .key_id = key,
+        .alg = alg,
+        .op_handle = operation->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}
+    };
+    psa_outvec out_vec[] = {
+        {.base = &(operation->handle), .len = sizeof(uint32_t)}
+    };
+
+    status = API_DISPATCH(tfm_crypto_aead_encrypt_setup,
+                          TFM_CRYPTO_AEAD_ENCRYPT_SETUP);
+    return status;
+}
+
+psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation,
+                                    psa_key_id_t key,
+                                    psa_algorithm_t alg)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_AEAD_DECRYPT_SETUP_SID,
+        .key_id = key,
+        .alg = alg,
+        .op_handle = operation->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}
+    };
+    psa_outvec out_vec[] = {
+        {.base = &(operation->handle), .len = sizeof(uint32_t)}
+    };
+
+    status = API_DISPATCH(tfm_crypto_aead_decrypt_setup,
+                          TFM_CRYPTO_AEAD_DECRYPT_SETUP);
+    return status;
+}
+
+psa_status_t psa_aead_generate_nonce(psa_aead_operation_t *operation,
+                                     uint8_t *nonce,
+                                     size_t nonce_size,
+                                     size_t *nonce_length)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_AEAD_GENERATE_NONCE_SID,
+        .op_handle = operation->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
+        {.base = nonce, .len = nonce_size}
+    };
+
+    status = API_DISPATCH(tfm_crypto_aead_generate_nonce,
+                          TFM_CRYPTO_AEAD_GENERATE_NONCE);
+
+    *nonce_length = out_vec[1].len;
+    return status;
+}
+
+psa_status_t psa_aead_set_nonce(psa_aead_operation_t *operation,
+                                const uint8_t *nonce,
+                                size_t nonce_length)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_AEAD_SET_NONCE_SID,
+        .op_handle = operation->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = nonce, .len = nonce_length}
+    };
+    psa_outvec out_vec[] = {
+        {.base = &(operation->handle), .len = sizeof(uint32_t)}
+    };
+
+    status = API_DISPATCH(tfm_crypto_aead_set_nonce,
+                          TFM_CRYPTO_AEAD_SET_NONCE);
+    return status;
+}
+
+psa_status_t psa_aead_set_lengths(psa_aead_operation_t *operation,
+                                  size_t ad_length,
+                                  size_t plaintext_length)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_AEAD_SET_LENGTHS_SID,
+        .ad_length = ad_length,
+        .plaintext_length = plaintext_length,
+        .op_handle = operation->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = &(operation->handle), .len = sizeof(uint32_t)}
+    };
+
+    status = API_DISPATCH(tfm_crypto_aead_set_lengths,
+                          TFM_CRYPTO_AEAD_SET_LENGTHS);
+    return status;
+}
+
+psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation,
+                                const uint8_t *input,
+                                size_t input_length)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_AEAD_UPDATE_AD_SID,
+        .op_handle = operation->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = input, .len = input_length}
+    };
+    psa_outvec out_vec[] = {
+        {.base = &(operation->handle), .len = sizeof(uint32_t)}
+    };
+
+    status = API_DISPATCH(tfm_crypto_aead_update_ad,
+                          TFM_CRYPTO_AEAD_UPDATE_AD);
+    return status;
+}
+
+psa_status_t psa_aead_update(psa_aead_operation_t *operation,
+                             const uint8_t *input,
+                             size_t input_length,
+                             uint8_t *output,
+                             size_t output_size,
+                             size_t *output_length)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_AEAD_UPDATE_SID,
+        .op_handle = operation->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = input, .len = input_length}
+    };
+    psa_outvec out_vec[] = {
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
+        {.base = output, .len = output_size},
+    };
+
+    status = API_DISPATCH(tfm_crypto_aead_update,
+                          TFM_CRYPTO_AEAD_UPDATE);
+
+    *output_length = out_vec[1].len;
+    return status;
+}
+
+psa_status_t psa_aead_finish(psa_aead_operation_t *operation,
+                             uint8_t *ciphertext,
+                             size_t ciphertext_size,
+                             size_t *ciphertext_length,
+                             uint8_t *tag,
+                             size_t tag_size,
+                             size_t *tag_length)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_AEAD_FINISH_SID,
+        .op_handle = operation->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
+        {.base = tag, .len = tag_size},
+        {.base = ciphertext, .len = ciphertext_size}
+    };
+
+    status = API_DISPATCH(tfm_crypto_aead_finish,
+                          TFM_CRYPTO_AEAD_FINISH);
+
+    *ciphertext_length = out_vec[2].len;
+    *tag_length = out_vec[1].len;
+    return status;
+}
+
+psa_status_t psa_aead_verify(psa_aead_operation_t *operation,
+                             uint8_t *plaintext,
+                             size_t plaintext_size,
+                             size_t *plaintext_length,
+                             const uint8_t *tag,
+                             size_t tag_length)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_AEAD_VERIFY_SID,
+        .op_handle = operation->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = tag, .len = tag_length}
+    };
+    psa_outvec out_vec[] = {
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
+        {.base = plaintext, .len = plaintext_size},
+    };
+
+    status = API_DISPATCH(tfm_crypto_aead_verify,
+                          TFM_CRYPTO_AEAD_VERIFY);
+
+    *plaintext_length = out_vec[1].len;
+    return status;
+}
+
+psa_status_t psa_aead_abort(psa_aead_operation_t *operation)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_AEAD_ABORT_SID,
+        .op_handle = operation->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
+    };
+
+    status = API_DISPATCH(tfm_crypto_aead_abort,
+                          TFM_CRYPTO_AEAD_ABORT);
+    return status;
+}
+
 psa_status_t psa_sign_message(psa_key_id_t key,
                               psa_algorithm_t alg,
                               const uint8_t *input,
@@ -1232,55 +1485,6 @@
     return status;
 }
 
-psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation,
-                                const uint8_t *input,
-                                size_t input_length)
-{
-    psa_status_t status;
-
-    status = PSA_ERROR_NOT_SUPPORTED;
-
-    return status;
-}
-
-psa_status_t psa_aead_finish(psa_aead_operation_t *operation,
-                             uint8_t *ciphertext,
-                             size_t ciphertext_size,
-                             size_t *ciphertext_length,
-                             uint8_t *tag,
-                             size_t tag_size,
-                             size_t *tag_length)
-{
-    psa_status_t status;
-
-    status = PSA_ERROR_NOT_SUPPORTED;
-
-    return status;
-}
-
-psa_status_t psa_aead_verify(psa_aead_operation_t *operation,
-                             uint8_t *plaintext,
-                             size_t plaintext_size,
-                             size_t *plaintext_length,
-                             const uint8_t *tag,
-                             size_t tag_length)
-{
-    psa_status_t status;
-
-    status = PSA_ERROR_NOT_SUPPORTED;
-
-    return status;
-}
-
-psa_status_t psa_aead_abort(psa_aead_operation_t *operation)
-{
-    psa_status_t status;
-
-    status = PSA_ERROR_NOT_SUPPORTED;
-
-    return status;
-}
-
 psa_status_t psa_mac_compute(psa_key_id_t key,
                              psa_algorithm_t alg,
                              const uint8_t *input,
@@ -1360,7 +1564,7 @@
         {.base = input, .len = input_length},
     };
     psa_outvec out_vec[] = {
-        {.base = output, .len = output_size},
+        {.base = output, .len = output_size}
     };
 
     status = API_DISPATCH(tfm_crypto_cipher_encrypt,
@@ -1393,7 +1597,7 @@
         {.base = input, .len = input_length},
     };
     psa_outvec out_vec[] = {
-        {.base = output, .len = output_size},
+        {.base = output, .len = output_size}
     };
 
     status = API_DISPATCH(tfm_crypto_cipher_decrypt,
@@ -1527,73 +1731,3 @@
                           TFM_CRYPTO_KEY_DERIVATION_OUTPUT_KEY);
     return status;
 }
-
-psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation,
-                                    psa_key_id_t key,
-                                    psa_algorithm_t alg)
-{
-    psa_status_t status;
-
-    status = PSA_ERROR_NOT_SUPPORTED;
-
-    return status;
-}
-
-psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation,
-                                    psa_key_id_t key,
-                                    psa_algorithm_t alg)
-{
-    psa_status_t status;
-
-    status = PSA_ERROR_NOT_SUPPORTED;
-
-    return status;
-}
-
-psa_status_t psa_aead_generate_nonce(psa_aead_operation_t *operation,
-                                     uint8_t *nonce,
-                                     size_t nonce_size,
-                                     size_t *nonce_length)
-{
-    psa_status_t status;
-
-    status = PSA_ERROR_NOT_SUPPORTED;
-
-    return status;
-}
-
-psa_status_t psa_aead_set_nonce(psa_aead_operation_t *operation,
-                                const uint8_t *nonce,
-                                size_t nonce_length)
-{
-    psa_status_t status;
-
-    status = PSA_ERROR_NOT_SUPPORTED;
-
-    return status;
-}
-
-psa_status_t psa_aead_set_lengths(psa_aead_operation_t *operation,
-                                  size_t ad_length,
-                                  size_t plaintext_length)
-{
-    psa_status_t status;
-
-    status = PSA_ERROR_NOT_SUPPORTED;
-
-    return status;
-}
-
-psa_status_t psa_aead_update(psa_aead_operation_t *operation,
-                             const uint8_t *input,
-                             size_t input_length,
-                             uint8_t *output,
-                             size_t output_size,
-                             size_t *output_length)
-{
-    psa_status_t status;
-
-    status = PSA_ERROR_NOT_SUPPORTED;
-
-    return status;
-}