Crypto: Add support for AEAD operations

This patch introduces support for the AEAD (authenticated
encryption with associated data) operations in the context
of the Crypto service. It also adds two functional test
cases to the NS suite to showcase AEAD in GCM and CCM mode
using AES-128.

Change-Id: I42ca3b27c68cb95dcddaf525d5a7ff53f92e911c
Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
diff --git a/docs/user_guides/services/tfm_crypto_integration_guide.md b/docs/user_guides/services/tfm_crypto_integration_guide.md
index c16b102..001e39e 100644
--- a/docs/user_guides/services/tfm_crypto_integration_guide.md
+++ b/docs/user_guides/services/tfm_crypto_integration_guide.md
@@ -52,7 +52,9 @@
  The current implementation provides only SW primitives based on Mbed TLS
  functions;
  - `crypto_mac.c` : This file implements functionalities related to the
- MAC (Message Authentication Code) module.
+ MAC (Message Authentication Code) module;
+ - `crypto_aead.c` : This file implements functionalities related to the AEAD
+ (Authenticated Encryption with Associated Data) module.
 
 ## Crypto service integration guide
 
diff --git a/interface/include/crypto_psa_wrappers.h b/interface/include/crypto_psa_wrappers.h
index c337962..c34f828 100644
--- a/interface/include/crypto_psa_wrappers.h
+++ b/interface/include/crypto_psa_wrappers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -50,6 +50,90 @@
                                         struct psa_cipher_update_input *input_s,
                                      struct psa_cipher_update_output *output_s);
 
+/*!
+ * \struct psa_aead_encrypt_input
+ *
+ * \brief Input structure for the tfm_crypto_aead_encrypt_wrapper function
+ *
+ */
+struct psa_aead_encrypt_input {
+    psa_key_slot_t key;             /*!< Key slot */
+    psa_algorithm_t alg;            /*!< Algorithm type */
+    const uint8_t *nonce;           /*!< Nonce or IV to be used */
+    size_t nonce_length;            /*!< Size in bytes of the nonce buffer */
+    const uint8_t *additional_data; /*!< Additional data to be authenticated */
+    size_t additional_data_length;  /*!< Size in bytes of additional_data */
+    const uint8_t *plaintext;       /*!< Buffer holding data for encryption */
+    size_t plaintext_length;        /*!< Size in bytes of plaintext */
+};
+
+/*!
+ * \struct psa_aead_encrypt_output
+ *
+ * \brief Output structure for the tfm_crypto_aead_encrypt_wrapper function
+ *
+ */
+struct psa_aead_encrypt_output {
+    uint8_t *ciphertext;       /*!< Pointer for the buffer to hold ciphertext */
+    size_t ciphertext_size;    /*!< Size in bytes of the ciphertext buffer */
+    size_t *ciphertext_length; /*!< Actual size in bytes of ciphertext */
+};
+
+/*!
+ * \struct psa_aead_decrypt_input
+ *
+ * \brief Input structure for the tfm_crypto_aead_decrypt_wrapper function
+ *
+ */
+struct psa_aead_decrypt_input {
+    psa_key_slot_t key;             /*!< Key slot */
+    psa_algorithm_t alg;            /*!< Algorithm type */
+    const uint8_t *nonce;           /*!< Nonce or IV to be used */
+    size_t nonce_length;            /*!< Size in bytes of the nonce buffer */
+    const uint8_t *additional_data; /*!< Original data that was authenticated */
+    size_t additional_data_length;  /*!< Size in bytes of additional_data */
+    const uint8_t *ciphertext;      /*!< Buffer holding data for decryption */
+    size_t ciphertext_length;       /*!< Size in bytes of ciphertext */
+};
+
+/*!
+ * \struct psa_aead_decrypt_output
+ *
+ * \brief Output structure for the tfm_crypto_aead_decrypt_wrapper function
+ *
+ */
+struct psa_aead_decrypt_output {
+    uint8_t *plaintext;       /*!< Pointer for the buffer to hold plaintext */
+    size_t plaintext_size;    /*!< Size in bytes of the plaintext buffer */
+    size_t *plaintext_length; /*!< Actual size in bytes of plaintext */
+};
+
+/*!
+ * \brief This function is a TF-M compatible wrapper for the
+ *        \ref tfm_crypto_aead_encrypt implemented in the Crypto service
+ *
+ * \param[in]  input_s  Pointer to the structure containing input parameters
+ *                      associated with \ref psa_aead_encrypt_input
+ * \param[out] output_s Pointer to the structure containing output parameters
+ *                      associated with \ref psa_aead_encrypt_output
+ *
+ */
+enum tfm_crypto_err_t tfm_crypto_aead_encrypt_wrapper(
+                                        struct psa_aead_encrypt_input *input_s,
+                                     struct psa_aead_encrypt_output *output_s);
+/*!
+ * \brief This function is a TF-M compatible wrapper for the
+ *        \ref tfm_crypto_aead_decrypt implemented in the Crypto service
+ *
+ * \param[in]  input_s  Pointer to the structure containing input parameters
+ *                      associated with \ref psa_aead_decrypt_input
+ * \param[out] output_s Pointer to the structure containing output parameters
+ *                      associated with \ref psa_aead_decrypt_output
+ *
+ */
+enum tfm_crypto_err_t tfm_crypto_aead_decrypt_wrapper(
+                                        struct psa_aead_decrypt_input *input_s,
+                                     struct psa_aead_decrypt_output *output_s);
 #ifdef __cplusplus
 }
 #endif
diff --git a/interface/include/psa_crypto_sizes.h b/interface/include/psa_crypto_sizes.h
index 07b52e4..e21c130 100644
--- a/interface/include/psa_crypto_sizes.h
+++ b/interface/include/psa_crypto_sizes.h
@@ -156,7 +156,7 @@
  */
 #define PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length)    \
     (PSA_AEAD_TAG_SIZE(alg) != 0 ?                              \
-     (plaintext_length) - PSA_AEAD_TAG_SIZE(alg) :              \
+     (ciphertext_length) - PSA_AEAD_TAG_SIZE(alg) :              \
      0)
 
 /** Safe signature buffer size for psa_asymmetric_sign().
diff --git a/interface/include/tfm_crypto_veneers.h b/interface/include/tfm_crypto_veneers.h
index 312c2c3..83ab510 100644
--- a/interface/include/tfm_crypto_veneers.h
+++ b/interface/include/tfm_crypto_veneers.h
@@ -242,7 +242,6 @@
  */
 enum tfm_crypto_err_t tfm_crypto_veneer_hash_abort(
                                                psa_hash_operation_t *operation);
-
 /**
  * \brief Start a MAC operation with the provided algorithm (for signing)
  *        (veneer function)
@@ -342,6 +341,33 @@
  */
 enum tfm_crypto_err_t tfm_crypto_veneer_mac_abort(
                                                 psa_mac_operation_t *operation);
+/**
+ * \brief Perform an AEAD encryption operation on input data with additional
+ *        data to be authenticated, producing ciphertext in output with an
+ *        appended authentication tag (veneer function)
+ *
+ * \param[in]  input_s   Pointer to the struct containing input parameters
+ * \param[out] output_s  Pointer to the struct containing output parameters
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_veneer_aead_encrypt(
+                                     struct psa_aead_encrypt_input *input_s,
+                                     struct psa_aead_encrypt_output *output_s);
+/**
+ * \brief Perform an AEAD decryption operation on input data with additional
+ *        data to be verified, producing back the original plain text in case
+ *        the verification of the authentication tag is successful (veneer
+ *        function)
+ *
+ * \param[in]  input_s   Pointer to the struct containing input parameters
+ * \param[out] output_s  Pointer to the struct containing output parameters
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_veneer_aead_decrypt(
+                                     struct psa_aead_decrypt_input *input_s,
+                                     struct psa_aead_decrypt_output *output_s);
 
 #ifdef __cplusplus
 }
diff --git a/interface/src/tfm_crypto_api.c b/interface/src/tfm_crypto_api.c
index a1bf389..8069934 100644
--- a/interface/src/tfm_crypto_api.c
+++ b/interface/src/tfm_crypto_api.c
@@ -352,3 +352,86 @@
 
     return TFM_CRYPTO_ERR_TO_PSA_STATUS(err);
 }
+
+psa_status_t psa_aead_encrypt(psa_key_slot_t key,
+                              psa_algorithm_t alg,
+                              const uint8_t *nonce,
+                              size_t nonce_length,
+                              const uint8_t *additional_data,
+                              size_t additional_data_length,
+                              const uint8_t *plaintext,
+                              size_t plaintext_length,
+                              uint8_t *ciphertext,
+                              size_t ciphertext_size,
+                              size_t *ciphertext_length)
+{
+    enum tfm_crypto_err_t err;
+
+    /* Packing in structures is needed to overcome the 4 parameters
+     * per call limit
+     */
+    struct psa_aead_encrypt_input input_s = {.key = key,
+                                             .alg = alg,
+                                             .nonce = nonce,
+                                             .nonce_length = nonce_length,
+                                             .additional_data = additional_data,
+                                             .additional_data_length =
+                                                         additional_data_length,
+                                             .plaintext = plaintext,
+                                             .plaintext_length =
+                                                              plaintext_length};
+    struct psa_aead_encrypt_output output_s = {.ciphertext = ciphertext,
+                                               .ciphertext_size =
+                                                                ciphertext_size,
+                                               .ciphertext_length =
+                                                             ciphertext_length};
+
+    err = tfm_ns_lock_dispatch((veneer_fn)tfm_crypto_veneer_aead_encrypt,
+                               (uint32_t)&input_s,
+                               (uint32_t)&output_s,
+                               0,
+                               0);
+
+    return TFM_CRYPTO_ERR_TO_PSA_STATUS(err);
+}
+
+psa_status_t psa_aead_decrypt(psa_key_slot_t key,
+                              psa_algorithm_t alg,
+                              const uint8_t *nonce,
+                              size_t nonce_length,
+                              const uint8_t *additional_data,
+                              size_t additional_data_length,
+                              const uint8_t *ciphertext,
+                              size_t ciphertext_length,
+                              uint8_t *plaintext,
+                              size_t plaintext_size,
+                              size_t *plaintext_length)
+{
+    enum tfm_crypto_err_t err;
+
+    /* Packing in structures is needed to overcome the 4 parameters
+     * per call limit
+     */
+    struct psa_aead_decrypt_input input_s = {.key = key,
+                                             .alg = alg,
+                                             .nonce = nonce,
+                                             .nonce_length = nonce_length,
+                                             .additional_data = additional_data,
+                                             .additional_data_length =
+                                                         additional_data_length,
+                                             .ciphertext = ciphertext,
+                                             .ciphertext_length =
+                                                             ciphertext_length};
+    struct psa_aead_decrypt_output output_s = {.plaintext = plaintext,
+                                               .plaintext_size = plaintext_size,
+                                               .plaintext_length =
+                                                              plaintext_length};
+
+    err = tfm_ns_lock_dispatch((veneer_fn)tfm_crypto_veneer_aead_decrypt,
+                               (uint32_t)&input_s,
+                               (uint32_t)&output_s,
+                               0,
+                               0);
+
+    return TFM_CRYPTO_ERR_TO_PSA_STATUS(err);
+}
diff --git a/secure_fw/ns_callable/tfm_crypto_veneers.c b/secure_fw/ns_callable/tfm_crypto_veneers.c
index 7f8208d..a3ecc8d 100644
--- a/secure_fw/ns_callable/tfm_crypto_veneers.c
+++ b/secure_fw/ns_callable/tfm_crypto_veneers.c
@@ -218,3 +218,21 @@
     TFM_CORE_SFN_REQUEST(TFM_SP_CRYPTO_ID, tfm_crypto_mac_abort,
                          operation, 0, 0, 0);
 }
+
+__tfm_secure_gateway_attributes__
+enum tfm_crypto_err_t tfm_crypto_veneer_aead_encrypt(
+                                      struct psa_aead_encrypt_input *input_s,
+                                      struct psa_aead_encrypt_output *output_s)
+{
+    TFM_CORE_SFN_REQUEST(TFM_SP_CRYPTO_ID, tfm_crypto_aead_encrypt_wrapper,
+                         input_s, output_s, 0, 0);
+}
+
+__tfm_secure_gateway_attributes__
+enum tfm_crypto_err_t tfm_crypto_veneer_aead_decrypt(
+                                      struct psa_aead_decrypt_input *input_s,
+                                      struct psa_aead_decrypt_output *output_s)
+{
+    TFM_CORE_SFN_REQUEST(TFM_SP_CRYPTO_ID, tfm_crypto_aead_decrypt_wrapper,
+                         input_s, output_s, 0, 0);
+}
diff --git a/secure_fw/services/crypto/CMakeLists.inc b/secure_fw/services/crypto/CMakeLists.inc
index 18dcbb0..4b572eb 100644
--- a/secure_fw/services/crypto/CMakeLists.inc
+++ b/secure_fw/services/crypto/CMakeLists.inc
@@ -50,6 +50,7 @@
                     "${CRYPTO_DIR}/crypto_wrappers.c"
                     "${CRYPTO_DIR}/crypto_utils.c"
                     "${CRYPTO_DIR}/crypto_engine.c"
+                    "${CRYPTO_DIR}/crypto_aead.c"
       )
 
   #Append all our source files to global lists.
diff --git a/secure_fw/services/crypto/crypto_aead.c b/secure_fw/services/crypto/crypto_aead.c
new file mode 100644
index 0000000..a0e2a5c
--- /dev/null
+++ b/secure_fw/services/crypto/crypto_aead.c
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <limits.h>
+
+#include "tfm_crypto_defs.h"
+
+#include "crypto_engine.h"
+
+#include "psa_crypto.h"
+
+#include "tfm_crypto_api.h"
+#include "crypto_utils.h"
+
+/*!
+ * \defgroup public_psa Public functions, PSA
+ *
+ */
+
+/*!@{*/
+enum tfm_crypto_err_t tfm_crypto_aead_encrypt(psa_key_slot_t key,
+                                              psa_algorithm_t alg,
+                                              const uint8_t *nonce,
+                                              size_t nonce_length,
+                                              const uint8_t *additional_data,
+                                              size_t additional_data_length,
+                                              const uint8_t *plaintext,
+                                              size_t plaintext_length,
+                                              uint8_t *ciphertext,
+                                              size_t ciphertext_size,
+                                              size_t *ciphertext_length)
+{
+    psa_status_t status = PSA_SUCCESS;
+    enum tfm_crypto_err_t err;
+    uint8_t key_data[TFM_CRYPTO_MAX_KEY_LENGTH];
+    uint32_t key_size;
+    psa_key_type_t key_type;
+
+    if (PSA_ALG_IS_AEAD(alg) == 0) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    if (PSA_AEAD_TAG_SIZE(alg) == 0) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    if (PSA_AEAD_ENCRYPT_OUTPUT_SIZE(alg, plaintext_length) > ciphertext_size) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    if ((nonce_length == 0) ||
+        ((additional_data_length == 0) && (additional_data != NULL))) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    /* Validate pointers */
+    err = tfm_crypto_memory_check((void *)nonce,
+                                  nonce_length,
+                                  TFM_MEMORY_ACCESS_RO);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    if ((additional_data != NULL) || (additional_data_length != 0)) {
+        err = tfm_crypto_memory_check((void *)additional_data,
+                                      additional_data_length,
+                                      TFM_MEMORY_ACCESS_RO);
+        if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+            return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+        }
+    }
+
+    err = tfm_crypto_memory_check((void *)plaintext,
+                                  plaintext_length,
+                                  TFM_MEMORY_ACCESS_RO);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    err = tfm_crypto_memory_check((void *)ciphertext,
+                                  ciphertext_size,
+                                  TFM_MEMORY_ACCESS_RW);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    err = tfm_crypto_memory_check((void *)ciphertext_length,
+                                  sizeof(size_t),
+                                  TFM_MEMORY_ACCESS_RW);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    /* Access the key data */
+    err = tfm_crypto_get_key_information(key, &key_type, (size_t *)&key_size);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    /* Access the crypto service key module to retrieve key data */
+    err = tfm_crypto_export_key(key,
+                                &key_data[0],
+                                TFM_CRYPTO_MAX_KEY_LENGTH,
+                                (size_t *)&key_size);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return err;
+    }
+
+    /* Request AEAD encryption on the crypto engine */
+    status = tfm_crypto_engine_aead_encrypt(key_type,
+                                            alg,
+                                            key_data,
+                                            key_size,
+                                            nonce,
+                                            nonce_length,
+                                            additional_data,
+                                            additional_data_length,
+                                            plaintext,
+                                            plaintext_length,
+                                            ciphertext,
+                                            ciphertext_size,
+                                            (uint32_t *)ciphertext_length);
+
+    return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+}
+
+enum tfm_crypto_err_t tfm_crypto_aead_decrypt(psa_key_slot_t key,
+                                              psa_algorithm_t alg,
+                                              const uint8_t *nonce,
+                                              size_t nonce_length,
+                                              const uint8_t *additional_data,
+                                              size_t additional_data_length,
+                                              const uint8_t *ciphertext,
+                                              size_t ciphertext_length,
+                                              uint8_t *plaintext,
+                                              size_t plaintext_size,
+                                              size_t *plaintext_length)
+{
+    psa_status_t status = PSA_SUCCESS;
+    enum tfm_crypto_err_t err;
+    uint8_t key_data[TFM_CRYPTO_MAX_KEY_LENGTH];
+    uint32_t key_size;
+    psa_key_type_t key_type;
+
+    if (PSA_ALG_IS_AEAD(alg) == 0) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    if (PSA_AEAD_TAG_SIZE(alg) == 0) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    if (PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length) > plaintext_size) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    if ((nonce_length == 0) ||
+        ((additional_data_length == 0) && (additional_data != NULL))) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    /* Validate pointers */
+    err = tfm_crypto_memory_check((void *)nonce,
+                                  nonce_length,
+                                  TFM_MEMORY_ACCESS_RO);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    if ((additional_data != NULL) || (additional_data_length != 0)) {
+        err = tfm_crypto_memory_check((void *)additional_data,
+                                      additional_data_length,
+                                      TFM_MEMORY_ACCESS_RO);
+        if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+            return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+        }
+    }
+
+    err = tfm_crypto_memory_check((void *)ciphertext,
+                                  ciphertext_length,
+                                  TFM_MEMORY_ACCESS_RO);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    err = tfm_crypto_memory_check((void *)plaintext,
+                                  plaintext_size,
+                                  TFM_MEMORY_ACCESS_RW);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    err = tfm_crypto_memory_check((void *)plaintext_length,
+                                  sizeof(size_t),
+                                  TFM_MEMORY_ACCESS_RW);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    /* Access the key data */
+    err = tfm_crypto_get_key_information(key, &key_type, (size_t *)&key_size);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    /* Access the crypto service key module to retrieve key data */
+    err = tfm_crypto_export_key(key,
+                                &key_data[0],
+                                TFM_CRYPTO_MAX_KEY_LENGTH,
+                                (size_t *)&key_size);
+    if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+        return err;
+    }
+
+    /* Request AEAD decryption on the crypto engine */
+    status = tfm_crypto_engine_aead_decrypt(key_type,
+                                            alg,
+                                            key_data,
+                                            key_size,
+                                            nonce,
+                                            nonce_length,
+                                            additional_data,
+                                            additional_data_length,
+                                            ciphertext,
+                                            ciphertext_length,
+                                            plaintext,
+                                            plaintext_size,
+                                            (uint32_t *)plaintext_length);
+
+    return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+}
+/*!@}*/
diff --git a/secure_fw/services/crypto/crypto_engine.c b/secure_fw/services/crypto/crypto_engine.c
index e1fdb17..f9fe896 100644
--- a/secure_fw/services/crypto/crypto_engine.c
+++ b/secure_fw/services/crypto/crypto_engine.c
@@ -537,3 +537,149 @@
 
     return return_value;
 }
+
+psa_status_t tfm_crypto_engine_aead_encrypt(psa_key_type_t key_type,
+                                            psa_algorithm_t alg,
+                                            const uint8_t *key_data,
+                                            uint32_t key_size,
+                                            const uint8_t *nonce,
+                                            uint32_t nonce_length,
+                                            const uint8_t *additional_data,
+                                            uint32_t additional_data_length,
+                                            const uint8_t *plaintext,
+                                            uint32_t plaintext_length,
+                                            uint8_t *ciphertext,
+                                            uint32_t ciphertext_size,
+                                            uint32_t *ciphertext_length)
+{
+    psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
+
+#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
+    int ret;
+    mbedtls_cipher_context_t aead_ctx;
+    const uint32_t key_size_bits = PSA_BYTES_TO_BITS(key_size);
+
+    const mbedtls_cipher_info_t *info = get_mbedtls_cipher_info(key_type,
+                                                                alg,
+                                                                key_size_bits);
+    const uint32_t encrypted_message_length =
+                           PSA_AEAD_ENCRYPT_OUTPUT_SIZE(alg, plaintext_length) -
+                                                         PSA_AEAD_TAG_SIZE(alg);
+    if (info == NULL) {
+        /* The combination of key_type, alg and key_size is not a valid Mbed TLS
+         * cipher configuration.
+         */
+        return_value = PSA_ERROR_NOT_SUPPORTED;
+    } else {
+        /* Init the mbedTLS context */
+        mbedtls_cipher_init(&aead_ctx);
+
+        /* Setup the mbedTLS context */
+        ret = mbedtls_cipher_setup(&aead_ctx, info);
+        if (ret != 0) {
+            return_value = mbedtls_to_psa_return(ret);
+        } else {
+            /* Set the key on the Mbed TLS context */
+            ret = mbedtls_cipher_setkey(&aead_ctx,
+                                        key_data,
+                                        key_size_bits,
+                                        MBEDTLS_ENCRYPT);
+            if (ret != 0) {
+                return_value = mbedtls_to_psa_return(ret);
+            } else {
+                /* Perform the AEAD operation on the Mbed TLS context */
+                ret = mbedtls_cipher_auth_encrypt(&aead_ctx,
+                                                  nonce, nonce_length,
+                                                  additional_data,
+                                                  additional_data_length,
+                                                  plaintext,
+                                                  plaintext_length,
+                                                  ciphertext,
+                                                  (size_t *)ciphertext_length,
+                                                  ciphertext +
+                                                      encrypted_message_length,
+                                                  PSA_AEAD_TAG_SIZE(alg));
+
+                /* Clear the Mbed TLS context */
+                mbedtls_cipher_free(&aead_ctx);
+                return_value = mbedtls_to_psa_return(ret);
+            }
+        }
+    }
+#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
+
+    return return_value;
+}
+
+psa_status_t tfm_crypto_engine_aead_decrypt(psa_key_type_t key_type,
+                                            psa_algorithm_t alg,
+                                            const uint8_t *key_data,
+                                            uint32_t key_size,
+                                            const uint8_t *nonce,
+                                            uint32_t nonce_length,
+                                            const uint8_t *additional_data,
+                                            uint32_t additional_data_length,
+                                            const uint8_t *ciphertext,
+                                            uint32_t ciphertext_length,
+                                            uint8_t *plaintext,
+                                            uint32_t plaintext_size,
+                                            uint32_t *plaintext_length)
+{
+    psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
+
+#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
+    int ret;
+    mbedtls_cipher_context_t aead_ctx;
+    const uint32_t key_size_bits = PSA_BYTES_TO_BITS(key_size);
+
+    const mbedtls_cipher_info_t *info = get_mbedtls_cipher_info(key_type,
+                                                                alg,
+                                                                key_size_bits);
+
+    const uint32_t encrypted_message_length =
+                           PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length);
+    if (info == NULL) {
+        /* The combination of key_type, alg and key_size is not a valid Mbed TLS
+         * cipher configuration.
+         */
+        return_value = PSA_ERROR_NOT_SUPPORTED;
+    } else {
+        /* Init the mbedTLS context */
+        mbedtls_cipher_init(&aead_ctx);
+
+        /* Setup the mbedTLS context */
+        ret = mbedtls_cipher_setup(&aead_ctx, info);
+        if (ret != 0) {
+            return_value = mbedtls_to_psa_return(ret);
+        } else {
+             /* Set the key on the Mbed TLS context */
+            ret = mbedtls_cipher_setkey(&aead_ctx,
+                                        key_data,
+                                        key_size_bits,
+                                        MBEDTLS_DECRYPT);
+            if (ret != 0) {
+                return_value = mbedtls_to_psa_return(ret);
+            } else {
+                /* Perform the AEAD operation on the Mbed TLS context */
+                ret = mbedtls_cipher_auth_decrypt(&aead_ctx,
+                                                  nonce, nonce_length,
+                                                  additional_data,
+                                                  additional_data_length,
+                                                  ciphertext,
+                                                  encrypted_message_length,
+                                                  plaintext,
+                                                  (size_t *)plaintext_length,
+                                                  ciphertext +
+                                                      encrypted_message_length,
+                                                  PSA_AEAD_TAG_SIZE(alg));
+
+                /* Clear the Mbed TLS context */
+                mbedtls_cipher_free(&aead_ctx);
+                return_value = mbedtls_to_psa_return(ret);
+            }
+        }
+    }
+#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
+
+    return return_value;
+}
diff --git a/secure_fw/services/crypto/crypto_engine.h b/secure_fw/services/crypto/crypto_engine.h
index a4e388d..c5771bf 100644
--- a/secure_fw/services/crypto/crypto_engine.h
+++ b/secure_fw/services/crypto/crypto_engine.h
@@ -302,6 +302,82 @@
  * \return Return values as specified by \ref psa_status_t
  */
 psa_status_t tfm_crypto_engine_cipher_release(union engine_cipher_context *cp);
+
+/**
+ * \brief This function performs an AEAD encryption on the provided data
+ *
+ * \param[in]  key_type               Key type of the key that will be used
+ * \param[in]  alg                    Algorithm to be used
+ * \param[in]  key_data               Pointer to the buffer containing key
+ *                                    material
+ * \param[in]  key_size               Size in bytes of the key pointed to by
+ *                                    key_data
+ * \param[in]  nonce                  Pointer to a buffer holding a nonce or IV
+ *                                    to use
+ * \param[in]  nonce_length           Size in bytes of the nonce or IV data
+ * \param[in]  additional_data        Additional information to be authenticated
+ * \param[in]  additional_data_length Size in bytes of the additional data
+ * \param[in]  plaintext              Buffer pointing to data to be encrypted
+ * \param[in]  plaintext_length       Size in bytes of the plain text buffer
+ * \param[out] ciphertext             Output encrypted data, with the
+ *                                    authentication tag appended
+ * \param[in]  ciphertext_size        Size in bytes of the buffer to hold the
+ *                                    cipher text plus authentication tag
+ * \param[out] ciphertext_length      Size of the ciphertext plus tag produced
+ *                                    as output
+ *
+ * \return Return values as specified by \ref psa_status_t
+ */
+psa_status_t tfm_crypto_engine_aead_encrypt(psa_key_type_t key_type,
+                                            psa_algorithm_t alg,
+                                            const uint8_t *key_data,
+                                            uint32_t key_size,
+                                            const uint8_t *nonce,
+                                            uint32_t nonce_length,
+                                            const uint8_t *additional_data,
+                                            uint32_t additional_data_length,
+                                            const uint8_t *plaintext,
+                                            uint32_t plaintext_length,
+                                            uint8_t *ciphertext,
+                                            uint32_t ciphertext_size,
+                                            uint32_t *ciphertext_length);
+/**
+ * \brief This function performs an AEAD decryption on the provided data
+ *
+ * \param[in]  key_type               Key type of the key that will be used
+ * \param[in]  alg                    Algorithm to be used
+ * \param[in]  key_data               Pointer to the buffer containing key
+ *                                    material
+ * \param[in]  key_size               Size in bytes of the key pointed to by
+ *                                    key_data
+ * \param[in]  nonce                  Pointer to a buffer holding a nonce or IV
+ *                                    to use
+ * \param[in]  nonce_length           Size in bytes of the nonce or IV data
+ * \param[in]  additional_data        Additional information which was
+ *                                    authenticated but not encrypted
+ * \param[in]  additional_data_length Size in bytes of the additional data
+ * \param[in]  ciphertext             Buffer pointing to data be decrypted
+ * \param[in]  ciphertext_length      Size in bytes of the cipher text buffer
+ * \param[out] plaintext              Buffer for decrypted output data
+ * \param[in]  plaintext_size         Size in bytes of the buffer to hold the
+ *                                    plain text
+ * \param[out] plaintext_length       Size of the plain text actually produced
+ *
+ * \return Return values as specified by \ref psa_status_t
+ */
+psa_status_t tfm_crypto_engine_aead_decrypt(psa_key_type_t key_type,
+                                            psa_algorithm_t alg,
+                                            const uint8_t *key_data,
+                                            uint32_t key_size,
+                                            const uint8_t *nonce,
+                                            uint32_t nonce_length,
+                                            const uint8_t *additional_data,
+                                            uint32_t additional_data_length,
+                                            const uint8_t *ciphertext,
+                                            uint32_t ciphertext_length,
+                                            uint8_t *plaintext,
+                                            uint32_t plaintext_size,
+                                            uint32_t *plaintext_length);
 #ifdef __cplusplus
 }
 #endif
diff --git a/secure_fw/services/crypto/crypto_wrappers.c b/secure_fw/services/crypto/crypto_wrappers.c
index cb68600..40e08ce 100644
--- a/secure_fw/services/crypto/crypto_wrappers.c
+++ b/secure_fw/services/crypto/crypto_wrappers.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -24,7 +24,6 @@
                                       struct psa_cipher_update_output *output_s)
 {
     /* Extract the following fields from the input and output structures */
-
     const uint8_t *input = input_s->input;
     size_t input_length = input_s->input_length;
 
@@ -35,4 +34,52 @@
     return tfm_crypto_cipher_update(operation, input, input_length,
                                     output, output_size, output_length);
 }
+
+enum tfm_crypto_err_t tfm_crypto_aead_encrypt_wrapper(
+                                        struct psa_aead_encrypt_input *input_s,
+                                      struct psa_aead_encrypt_output *output_s)
+{
+    /* Extract the following fields from the input and output structures */
+    psa_key_slot_t key = input_s->key;
+    psa_algorithm_t alg = input_s->alg;
+    const uint8_t *nonce = input_s->nonce;
+    size_t nonce_length = input_s->nonce_length;
+    const uint8_t *additional_data = input_s->additional_data;
+    size_t additional_data_length = input_s->additional_data_length;
+    const uint8_t *plaintext = input_s->plaintext;
+    size_t plaintext_length = input_s->plaintext_length;
+
+    uint8_t *ciphertext = output_s->ciphertext;
+    size_t ciphertext_size = output_s->ciphertext_size;
+    size_t *ciphertext_length = output_s->ciphertext_length;
+
+    return tfm_crypto_aead_encrypt(key, alg, nonce, nonce_length,
+                                   additional_data, additional_data_length,
+                                   plaintext, plaintext_length, ciphertext,
+                                   ciphertext_size, ciphertext_length);
+}
+
+enum tfm_crypto_err_t tfm_crypto_aead_decrypt_wrapper(
+                                        struct psa_aead_decrypt_input *input_s,
+                                      struct psa_aead_decrypt_output *output_s)
+{
+    /* Extract the following fields from the input and output structures */
+    psa_key_slot_t key = input_s->key;
+    psa_algorithm_t alg = input_s->alg;
+    const uint8_t *nonce = input_s->nonce;
+    size_t nonce_length = input_s->nonce_length;
+    const uint8_t *additional_data = input_s->additional_data;
+    size_t additional_data_length = input_s->additional_data_length;
+    const uint8_t *ciphertext = input_s->ciphertext;
+    size_t ciphertext_length = input_s->ciphertext_length;
+
+    uint8_t *plaintext = output_s->plaintext;
+    size_t plaintext_size = output_s->plaintext_size;
+    size_t *plaintext_length = output_s->plaintext_length;
+
+    return tfm_crypto_aead_decrypt(key, alg, nonce, nonce_length,
+                                   additional_data, additional_data_length,
+                                   ciphertext, ciphertext_length, plaintext,
+                                   plaintext_size, plaintext_length);
+}
 /*!@}*/
diff --git a/secure_fw/services/crypto/manifest.yaml b/secure_fw/services/crypto/manifest.yaml
index c6037a9..dae7a12 100644
--- a/secure_fw/services/crypto/manifest.yaml
+++ b/secure_fw/services/crypto/manifest.yaml
@@ -185,6 +185,22 @@
       "minor_version": 1,
       "minor_policy": "strict"
     },
+    {
+      "sfid": "TFM_CRYPTO_AEAD_DECRYPT_SFID",
+      "signal": "TFM_CRYPTO_AEAD_DECRYPT",
+      "tfm_symbol": "tfm_crypto_aead_decrypt_wrapper",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_AEAD_ENCRYPT_SFID",
+      "signal": "TFM_CRYPTO_AEAD_ENCRYPT",
+      "tfm_symbol": "tfm_crypto_aead_encrypt_wrapper",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
   ],
   "source_files": [
     "crypto_alloc.c",
@@ -195,7 +211,8 @@
     "crypto_utils.c",
     "crypto_hash.c",
     "crypto_engine.c",
-    "crypto_mac.c"
+    "crypto_mac.c",
+    "crypto_aead.c",
   ],
   "tfm_linker_pattern": [
     "library_list": [
diff --git a/secure_fw/services/crypto/tfm_crypto_api.h b/secure_fw/services/crypto/tfm_crypto_api.h
index 3638885..af8f7fb 100644
--- a/secure_fw/services/crypto/tfm_crypto_api.h
+++ b/secure_fw/services/crypto/tfm_crypto_api.h
@@ -405,6 +405,73 @@
  */
 enum tfm_crypto_err_t tfm_crypto_mac_abort(psa_mac_operation_t *operation);
 
+/**
+ * \brief Perform an AEAD encryption operation on input data with additional
+ *        data to be authenticated, producing ciphertext in output with an
+ *        appended authentication tag
+ *
+ * \param[in]  key                    Key slot for the key
+ * \param[in]  alg                    Algorithm to be used
+ * \param[in]  nonce                  Pointer to a buffer holding a nonce or IV
+ *                                    to use
+ * \param[in]  nonce_length           Size in bytes of the nonce or IV data
+ * \param[in]  additional_data        Additional information to be authenticated
+ * \param[in]  additional_data_length Size in bytes of the additional data
+ * \param[in]  plaintext              Buffer pointing to data to be encrypted
+ * \param[in]  plaintext_length       Size in bytes of the plain text buffer
+ * \param[out] ciphertext             Output encrypted data, with the
+ *                                    authentication tag appended
+ * \param[in]  ciphertext_size        Size in bytes of the buffer to hold the
+ *                                    cipher text plus authentication tag
+ * \param[out] ciphertext_length      Size of the ciphertext plus tag produced
+ *                                    as output
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_aead_encrypt(psa_key_slot_t key,
+                                              psa_algorithm_t alg,
+                                              const uint8_t *nonce,
+                                              size_t nonce_length,
+                                              const uint8_t *additional_data,
+                                              size_t additional_data_length,
+                                              const uint8_t *plaintext,
+                                              size_t plaintext_length,
+                                              uint8_t *ciphertext,
+                                              size_t ciphertext_size,
+                                              size_t *ciphertext_length);
+/**
+ * \brief Perform an AEAD decryption operation on input data with additional
+ *        data to be verified, producing back the original plain text in case
+ *        the verification of the authentication tag is successful
+ *
+ * \param[in]  key                    Key slot for the key
+ * \param[in]  alg                    Algorithm to be used
+ * \param[in]  nonce                  Pointer to a buffer holding a nonce or IV
+ *                                    to use
+ * \param[in]  nonce_length           Size in bytes of the nonce or IV data
+ * \param[in]  additional_data        Additional information which was
+ *                                    authenticated but not encrypted
+ * \param[in]  additional_data_length Size in bytes of the additional data
+ * \param[in]  ciphertext             Buffer pointing to data be decrypted
+ * \param[in]  ciphertext_length      Size in bytes of the cipher text buffer
+ * \param[out] plaintext              Buffer for decrypted output data
+ * \param[in]  plaintext_size         Size in bytes of the buffer to hold the
+ *                                    plain text
+ * \param[out] plaintext_length       Size of the plain text actually produced
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_aead_decrypt(psa_key_slot_t key,
+                                              psa_algorithm_t alg,
+                                              const uint8_t *nonce,
+                                              size_t nonce_length,
+                                              const uint8_t *additional_data,
+                                              size_t additional_data_length,
+                                              const uint8_t *ciphertext,
+                                              size_t ciphertext_length,
+                                              uint8_t *plaintext,
+                                              size_t plaintext_size,
+                                              size_t *plaintext_length);
 #ifdef __cplusplus
 }
 #endif
diff --git a/secure_fw/services/tfm_sfid_list.inc b/secure_fw/services/tfm_sfid_list.inc
index 0a38ac1..f9d0708 100644
--- a/secure_fw/services/tfm_sfid_list.inc
+++ b/secure_fw/services/tfm_sfid_list.inc
@@ -48,6 +48,8 @@
     {tfm_crypto_mac_sign_finish, TFM_CRYPTO_MAC_SIGN_FINISH_SFID},
     {tfm_crypto_mac_verify_finish, TFM_CRYPTO_MAC_VERIFY_FINISH_SFID},
     {tfm_crypto_mac_abort, TFM_CRYPTO_MAC_ABORT_SFID},
+    {tfm_crypto_aead_decrypt_wrapper, TFM_CRYPTO_AEAD_DECRYPT_SFID},
+    {tfm_crypto_aead_encrypt_wrapper, TFM_CRYPTO_AEAD_ENCRYPT_SFID},
 
     /******** TFM_SP_PLATFORM ********/
     {platform_sp_system_reset, TFM_SP_PLATFORM_SYSTEM_RESET_SFID},
diff --git a/test/suites/crypto/non_secure/crypto_ns_interface_testsuite.c b/test/suites/crypto/non_secure/crypto_ns_interface_testsuite.c
index e953e25..ea9316b 100644
--- a/test/suites/crypto/non_secure/crypto_ns_interface_testsuite.c
+++ b/test/suites/crypto/non_secure/crypto_ns_interface_testsuite.c
@@ -17,6 +17,7 @@
 #define BYTE_SIZE_TEST_KEY (BIT_SIZE_TEST_KEY/8)
 #define BYTE_SIZE_CHUNK (16)
 #define ENC_DEC_BUFFER_SIZE (32)
+#define ASSOCIATED_DATA_SIZE (24)
 
 /* List of tests */
 static void tfm_crypto_test_6001(struct test_result_t *ret);
@@ -41,6 +42,9 @@
 static void tfm_crypto_test_6020(struct test_result_t *ret);
 static void tfm_crypto_test_6021(struct test_result_t *ret);
 static void tfm_crypto_test_6022(struct test_result_t *ret);
+static void tfm_crypto_test_6028(struct test_result_t *ret);
+static void tfm_crypto_test_6029(struct test_result_t *ret);
+
 
 static struct test_t crypto_veneers_tests[] = {
     {&tfm_crypto_test_6001, "TFM_CRYPTO_TEST_6001",
@@ -87,6 +91,10 @@
      "Non Secure HMAC (MD-5) interface", {0} },
     {&tfm_crypto_test_6022, "TFM_CRYPTO_TEST_6022",
      "Non Secure HMAC with long key (SHA-1) interface", {0} },
+    {&tfm_crypto_test_6028, "TFM_CRYPTO_TEST_6028",
+     "Non Secure AEAD (AES-128-CCM) interface", {0} },
+    {&tfm_crypto_test_6029, "TFM_CRYPTO_TEST_6029",
+     "Non Secure AEAD (AES-128-GCM) interface", {0} },
 };
 
 void register_testsuite_ns_crypto_interface(struct test_suite_t *p_test_suite)
@@ -666,6 +674,7 @@
     } else {
         status = psa_import_key(slot, PSA_KEY_TYPE_HMAC, data, sizeof(data));
     }
+
     if (status != PSA_SUCCESS) {
         TEST_FAIL("Error importing a key");
         return;
@@ -766,3 +775,127 @@
 {
     psa_mac_test(PSA_ALG_HMAC(PSA_ALG_SHA_1), 1, ret);
 }
+
+static void psa_aead_test(const psa_key_type_t key_type,
+                          const psa_algorithm_t alg,
+                          struct test_result_t *ret)
+{
+    const psa_key_slot_t slot = 0;
+    const size_t nonce_length = 12;
+    const uint8_t nonce[] = "01234567890";
+    const uint8_t plain_text[BYTE_SIZE_CHUNK] = "Sixteen bytes!!";
+    const uint8_t associated_data[ASSOCIATED_DATA_SIZE] =
+                                                      "This is associated data";
+    uint8_t encrypted_data[ENC_DEC_BUFFER_SIZE] = {0};
+    size_t encrypted_data_length = 0, decrypted_data_length = 0;
+    uint8_t decrypted_data[ENC_DEC_BUFFER_SIZE] = {0};
+    psa_status_t status;
+    const uint8_t data[] = "THIS IS MY KEY1";
+    psa_key_type_t type = PSA_KEY_TYPE_NONE;
+    size_t bits = 0;
+    uint32_t comp_result;
+
+    ret->val = TEST_PASSED;
+
+    /* Import a key on slot 0 */
+    status = psa_import_key(slot, key_type, data, sizeof(data));
+    if (status != PSA_SUCCESS) {
+        TEST_FAIL("Error importing a key");
+        return;
+    }
+
+    status = psa_get_key_information(slot, &type, &bits);
+    if (status != PSA_SUCCESS) {
+        TEST_FAIL("Error getting key metadata");
+        goto destroy_key_aead;
+    }
+
+    if (bits != BIT_SIZE_TEST_KEY) {
+        TEST_FAIL("The number of key bits is different from expected");
+        goto destroy_key_aead;
+    }
+
+    if (type != key_type) {
+        TEST_FAIL("The type of the key is different from expected");
+        goto destroy_key_aead;
+    }
+
+    /* Perform AEAD encryption */
+    status = psa_aead_encrypt(slot, alg, nonce, nonce_length,
+                              associated_data,
+                              sizeof(associated_data),
+                              plain_text,
+                              sizeof(plain_text),
+                              encrypted_data,
+                              sizeof(encrypted_data),
+                              &encrypted_data_length );
+
+    if (status != PSA_SUCCESS) {
+        if (status == PSA_ERROR_NOT_SUPPORTED) {
+            TEST_FAIL("Algorithm NOT SUPPORTED by the implementation");
+            goto destroy_key_aead;
+        }
+
+        TEST_FAIL("Error performing AEAD encryption");
+        goto destroy_key_aead;
+    }
+
+    /* Increment the encrypted_data_length with the tag size which has
+     * been appended to the encrypted data
+     */
+    encrypted_data_length += PSA_AEAD_TAG_SIZE(alg);
+
+    /* Perform AEAD decryption */
+    status = psa_aead_decrypt(slot, alg, nonce, nonce_length,
+                              associated_data,
+                              sizeof(associated_data),
+                              encrypted_data,
+                              encrypted_data_length,
+                              decrypted_data,
+                              sizeof(decrypted_data),
+                              &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 AEAD decryption");
+        }
+
+        goto destroy_key_aead;
+    }
+
+    if (sizeof(plain_text) != decrypted_data_length) {
+        TEST_FAIL("Decrypted data length is different from plain text");
+        goto destroy_key_aead;
+    }
+
+    /* Check that the decrypted data is the same as the original data */
+    comp_result = compare_buffers(plain_text,
+                                  decrypted_data,
+                                  sizeof(plain_text),
+                                  decrypted_data_length);
+
+    if (comp_result != 0) {
+        TEST_FAIL("Decrypted data doesn't match with plain text");
+        goto destroy_key_aead;
+    }
+
+
+destroy_key_aead:
+    /* Destroy the key on slot 0 */
+    status = psa_destroy_key(slot);
+    if (status != PSA_SUCCESS) {
+        TEST_FAIL("Error destroying a key");
+    }
+}
+
+static void tfm_crypto_test_6028(struct test_result_t *ret)
+{
+    psa_aead_test(PSA_KEY_TYPE_AES, PSA_ALG_CCM, ret);
+}
+
+static void tfm_crypto_test_6029(struct test_result_t *ret)
+{
+    psa_aead_test(PSA_KEY_TYPE_AES, PSA_ALG_GCM, ret);
+}