Merge pull request #4927 from yuhaoth/pr/add-tls13-serverhello-utils

TLS 1.3: ServerHello: add  utils functions used by ServerHello
Regarding the merge job, there was only one of the failure we currently encounter on almost all PR (Session resume using tickets, DTLS: openssl client test case see #5012) thus we can consider that this PR passed CI.
diff --git a/ChangeLog.d/add_psa_m_aead.txt b/ChangeLog.d/add_psa_m_aead.txt
new file mode 100644
index 0000000..fa4e7ac
--- /dev/null
+++ b/ChangeLog.d/add_psa_m_aead.txt
@@ -0,0 +1,3 @@
+Features
+   * Implement the PSA multipart AEAD interface, currently supporting
+     ChaChaPoly and GCM.
diff --git a/ChangeLog.d/fix-mbedtls_cipher_crypt-aes-ecb.txt b/ChangeLog.d/fix-mbedtls_cipher_crypt-aes-ecb.txt
new file mode 100644
index 0000000..6dc4724
--- /dev/null
+++ b/ChangeLog.d/fix-mbedtls_cipher_crypt-aes-ecb.txt
@@ -0,0 +1,2 @@
+Bugfix
+   * Fix mbedtls_cipher_crypt: AES-ECB when MBEDTLS_USE_PSA_CRYPTO is enabled.
diff --git a/README.md b/README.md
index b80ee11..dbe6a23 100644
--- a/README.md
+++ b/README.md
@@ -298,3 +298,10 @@
 ------------
 
 We gratefully accept bug reports and contributions from the community. Please see the [contributing guidelines](CONTRIBUTING.md) for details on how to do this.
+
+Contact
+-------
+
+* To report a security vulnerability in Mbed TLS, please email <mbed-tls-security@lists.trustedfirmware.org>. For more information, see [`SECURITY.md`](SECURITY.md).
+* To report a bug or request a feature in Mbed TLS, please [file an issue on GitHub](https://github.com/ARMmbed/mbedtls/issues/new/choose).
+* Please see [`SUPPORT.md`](SUPPORT.md) for other channels for discussion and support about Mbed TLS.
diff --git a/docs/architecture/tls13-experimental.md b/docs/architecture/tls13-experimental.md
index 0009c68..5d7c14f 100644
--- a/docs/architecture/tls13-experimental.md
+++ b/docs/architecture/tls13-experimental.md
@@ -66,3 +66,342 @@
   as part of `MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL`:
 
   - Reader ([`library/mps_reader.h`](../../library/mps_reader.h))
+
+
+MVP definition
+--------------
+
+- Overview
+
+  - The TLS 1.3 MVP implements only the client side of the protocol.
+
+  - The TLS 1.3 MVP supports ECDHE key establishment.
+
+  - The TLS 1.3 MVP does not support DHE key establishment.
+
+  - The TLS 1.3 MVP does not support pre-shared keys, including any form of
+    session resumption. This implies that it does not support sending early
+    data (0-RTT data).
+
+  - The TLS 1.3 MVP supports the authentication of the server by the client
+    but does not support authentication of the client by the server. In terms
+    of TLS 1.3 authentication messages, this means that the TLS 1.3 MVP
+    supports the processing of the Certificate and CertificateVerify messages
+    but not of the CertificateRequest message.
+
+  - The TLS 1.3 MVP does not support the handling of server HelloRetryRequest
+    message. In practice, this means that the handshake will fail if the MVP
+    does not provide in its ClientHello the shared secret associated to the
+    group selected by the server for key establishement. For more information,
+    see the comment associated to the `key_share` extension below.
+
+  - If the TLS 1.3 MVP receives a HelloRetryRequest or a CertificateRequest
+    message, it aborts the handshake with an handshake_failure closure alert
+    and the `mbedtls_ssl_handshake()` returns in error with the
+    `MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE` error code.
+
+- Supported cipher suites: depends on the library configuration. Potentially
+  all of them:
+  TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256,
+  TLS_AES_128_CCM_SHA256 and TLS_AES_128_CCM_8_SHA256.
+
+- Supported ClientHello extensions:
+
+  | Extension                    |   MVP   | Prototype (1) |
+  | ---------------------------- | ------- | ------------- |
+  | server_name                  | YES     | YES           |
+  | max_fragment_length          | no      | YES           |
+  | status_request               | no      | no            |
+  | supported_groups             | YES     | YES           |
+  | signature_algorithms         | YES     | YES           |
+  | use_srtp                     | no      | no            |
+  | heartbeat                    | no      | no            |
+  | apln                         | no      | YES           |
+  | signed_certificate_timestamp | no      | no            |
+  | client_certificate_type      | no      | no            |
+  | server_certificate_type      | no      | no            |
+  | padding                      | no      | no            |
+  | key_share                    | YES (2) | YES           |
+  | pre_shared_key               | no      | YES           |
+  | psk_key_exchange_modes       | no      | YES           |
+  | early_data                   | no      | YES           |
+  | cookie                       | no      | YES           |
+  | supported_versions           | YES (3) | YES           |
+  | certificate_authorities      | no      | no            |
+  | post_handshake_auth          | no      | no            |
+  | signature_algorithms_cert    | no      | no            |
+
+  (1) This is just for comparison.
+
+  (2) The MVP sends one shared secret corresponding to the configured preferred
+      group. The preferred group is the group of the first curve in the list of
+      allowed curves as defined by the configuration. The allowed curves are
+      by default ordered as follow: `secp256r1`, `x25519`, `secp384r1`
+      and finally `secp521r1`. This default order is aligned with the
+      list of mandatory-to-implement groups (in absence of an application
+      profile standard specifying otherwise) defined in section 9.1 of the
+      specification. The list of allowed curves can be changed through the
+      `mbedtls_ssl_conf_curves()` API.
+
+  (3) The MVP proposes only TLS 1.3 and does not support version negociation.
+      Out-of-protocol fallback is supported though if the Mbed TLS library
+      has been built to support both TLS 1.3 and TLS 1.2: just set the
+      maximum of the minor version of the SSL configuration to
+      MBEDTLS_SSL_MINOR_VERSION_3 (`mbedtls_ssl_conf_min_version()` API) and
+      re-initiate a server handshake.
+
+- Supported groups: depends on the library configuration.
+  Potentially all ECDHE groups but x448:
+  secp256r1, x25519, secp384r1 and secp521r1.
+
+  Finite field groups (DHE) are not supported.
+
+- Supported signature algorithms (both for certificates and CertificateVerify):
+  depends on the library configuration.
+  Potentially:
+  rsa_pkcs1_sha256, rsa_pss_rsae_sha256, ecdsa_secp256r1_sha256,
+  ecdsa_secp384r1_sha384 and ecdsa_secp521r1_sha512.
+
+  Note that in absence of an application profile standard specifying otherwise
+  the three first ones in the list above are mandatory (see section 9.1 of the
+  specification).
+
+- Supported versions: only TLS 1.3, version negotiation is not supported.
+
+- Compatibility with existing SSL/TLS build options:
+
+  The TLS 1.3 MVP is compatible with all TLS 1.2 configuration options in the
+  sense that when enabling the TLS 1.3 MVP in the library there is no need to
+  modify the configuration for TLS 1.2. Mbed TLS SSL/TLS related features are
+  not supported or not applicable to the TLS 1.3 MVP:
+
+  | Mbed TLS configuration option            | Support |
+  | ---------------------------------------- | ------- |
+  | MBEDTLS_SSL_ALL_ALERT_MESSAGES           | no      |
+  | MBEDTLS_SSL_ASYNC_PRIVATE                | no      |
+  | MBEDTLS_SSL_CONTEXT_SERIALIZATION        | no      |
+  | MBEDTLS_SSL_DEBUG_ALL                    | no      |
+  | MBEDTLS_SSL_ENCRYPT_THEN_MAC             | n/a     |
+  | MBEDTLS_SSL_EXTENDED_MASTER_SECRET       | n/a     |
+  | MBEDTLS_SSL_KEEP_PEER_CERTIFICATE        | no      |
+  | MBEDTLS_SSL_RENEGOTIATION                | n/a     |
+  | MBEDTLS_SSL_MAX_FRAGMENT_LENGTH          | no      |
+  |                                          |         |
+  | MBEDTLS_SSL_SESSION_TICKETS              | no      |
+  | MBEDTLS_SSL_EXPORT_KEYS                  | no (1)  |
+  | MBEDTLS_SSL_SERVER_NAME_INDICATION       | no      |
+  | MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH       | no      |
+  |                                          |         |
+  | MBEDTLS_ECP_RESTARTABLE                  | no      |
+  | MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED     | no      |
+  |                                          |         |
+  | MBEDTLS_KEY_EXCHANGE_PSK_ENABLED         | n/a (2) |
+  | MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED     | n/a     |
+  | MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED   | n/a     |
+  | MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED     | n/a     |
+  | MBEDTLS_KEY_EXCHANGE_RSA_ENABLED         | n/a     |
+  | MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED     | n/a     |
+  | MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED   | n/a     |
+  | MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED | n/a     |
+  | MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED  | n/a     |
+  | MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED    | n/a     |
+  | MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED     | n/a     |
+  |                                          |         |
+  | MBEDTLS_USE_PSA_CRYPTO                   | no      |
+
+  (1) Some support has already been upstreamed but it is incomplete.
+  (2) Key exchange configuration options for TLS 1.3 will likely to be
+      organized around the notion of key exchange mode along the line
+      of the MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_NONE/PSK/PSK_EPHEMERAL/EPHEMERAL
+      runtime configuration macros.
+
+- Quality considerations
+  - Standard Mbed TLS review bar
+  - Interoperability testing with OpenSSL and GnuTLS. Test with all the
+    cipher suites and signature algorithms supported by OpenSSL/GnuTLS server.
+  - Negative testing against OpenSSL/GnuTLS servers with which the
+    handshake fails due to incompatibility with the capabilities of the
+    MVP: TLS 1.2 or 1.1 server, server sending an HelloRetryRequest message in
+    response to the MVP ClientHello, server sending a CertificateRequest
+    message ...
+
+Coding rules checklist for TLS 1.3
+----------------------------------
+
+The following coding rules are aimed to be a checklist for TLS 1.3 upstreaming
+work to reduce review rounds and the number of comments in each round. They
+come along (do NOT replace) the project coding rules
+(https://tls.mbed.org/kb/development/mbedtls-coding-standards). They have been
+established and discussed following the review of #4882 that was the
+PR upstreaming the first part of TLS 1.3 ClientHello writing code.
+
+TLS 1.3 specific coding rules:
+
+  - TLS 1.3 specific C modules, headers, static functions names are prefixed
+    with `ssl_tls13_`. The same applies to structures and types that are
+    internal to C modules.
+
+  - TLS 1.3 specific exported functions, structures and types are
+    prefixed with `mbedtls_ssl_tls13_`.
+
+  - Use TLS1_3 in TLS 1.3 specific macros.
+
+  - The names of macros and variables related to a field or structure in the
+    TLS 1.3 specification should contain as far as possible the field name as
+    it is in the specification. If the field name is "too long" and we prefer
+    to introduce some kind of abbreviation of it, use the same abbreviation
+    everywhere in the code.
+
+    Example 1: #define CLIENT_HELLO_RANDOM_LEN 32, macro for the length of the
+        `random` field of the ClientHello message.
+
+    Example 2 (consistent abbreviation): `mbedtls_ssl_tls1_3_write_sig_alg_ext()`
+        and `MBEDTLS_TLS_EXT_SIG_ALG`, `sig_alg` standing for
+        `signature_algorithms`.
+
+  - Regarding vectors that are represented by a length followed by their value
+    in the data exchanged between servers and clients:
+
+    - Use `<vector name>_len` for the name of a variable used to compute the
+      length in bytes of the vector, where <vector name> is the name of the
+      vector as defined in the TLS 1.3 specification.
+
+    - Use `p_<vector_name>_len` for the name of a variable intended to hold
+      the address of the first byte of the vector length.
+
+    - Use `<vector_name>` for the name of a variable intended to hold the
+      address of the first byte of the vector value.
+
+    - Use `<vector_name>_end` for the name of a variable intended to hold
+      the address of the first byte past the vector value.
+
+    Those idioms should lower the risk of mis-using one of the address in place
+    of another one which could potentially lead to some nasty issues.
+
+    Example: `cipher_suites` vector of ClientHello in
+             `ssl_tls1_3_write_client_hello_cipher_suites()`
+    ```
+    size_t cipher_suites_len;
+    unsigned char *p_cipher_suites_len;
+    unsigned char *cipher_suites;
+    ```
+
+  - Where applicable, use:
+    - the macros to extract a byte from a multi-byte integer MBEDTLS_BYTE_{0-8}.
+    - the macros to write in memory in big-endian order a multi-byte integer
+      MBEDTLS_PUT_UINT{8|16|32|64}_BE.
+    - the macros to read from memory a multi-byte integer in big-endian order
+      MBEDTLS_GET_UINT{8|16|32|64}_BE.
+    - the macro to check for space when writing into an output buffer
+      `MBEDTLS_SSL_CHK_BUF_PTR`.
+    - the macro to check for data when reading from an input buffer
+      `MBEDTLS_SSL_CHK_BUF_READ_PTR`.
+
+    These macros were introduced after the prototype was written thus are
+    likely not to be used in prototype where we now would use them in
+    development.
+
+    The three first types, MBEDTLS_BYTE_{0-8}, MBEDTLS_PUT_UINT{8|16|32|64}_BE
+    and MBEDTLS_GET_UINT{8|16|32|64}_BE improve the readability of the code and
+    reduce the risk of writing or reading bytes in the wrong order.
+
+    The two last types, `MBEDTLS_SSL_CHK_BUF_PTR` and
+    `MBEDTLS_SSL_CHK_BUF_READ_PTR`, improve the readability of the code and
+    reduce the risk of error in the non-completely-trivial arithmetic to
+    check that we do not write or read past the end of a data buffer. The
+    usage of those macros combined with the following rule mitigate the risk
+    to read/write past the end of a data buffer.
+
+    Examples:
+    ```
+    hs_hdr[1] = MBEDTLS_BYTE_2( total_hs_len );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS, p, 0 );
+    MBEDTLS_SSL_CHK_BUF_PTR( p, end, 7 );
+    ```
+
+  - To mitigate what happened here
+    (https://github.com/ARMmbed/mbedtls/pull/4882#discussion_r701704527) from
+    happening again, use always a local variable named `p` for the reading
+    pointer in functions parsing TLS 1.3 data, and for the writing pointer in
+    functions writing data into an output buffer and only that variable. The
+    name `p` has been chosen as it was already widely used in TLS code.
+
+  - When an TLS 1.3 structure is written or read by a function or as part of
+    a function, provide as documentation the definition of the structure as
+    it is in the TLS 1.3 specification.
+
+General coding rules:
+
+  - We prefer grouping "related statement lines" by not adding blank lines
+    between them.
+
+    Example 1:
+    ```
+    ret = ssl_tls13_write_client_hello_cipher_suites( ssl, buf, end, &output_len );
+    if( ret != 0 )
+        return( ret );
+    buf += output_len;
+    ```
+
+    Example 2:
+    ```
+    MBEDTLS_SSL_CHK_BUF_PTR( cipher_suites_iter, end, 2 );
+    MBEDTLS_PUT_UINT16_BE( cipher_suite, cipher_suites_iter, 0 );
+    cipher_suites_iter += 2;
+    ```
+
+  - Use macros for constants that are used in different functions, different
+    places in the code. When a constant is used only locally in a function
+    (like the length in bytes of the vector lengths in functions reading and
+    writing TLS handshake message) there is no need to define a macro for it.
+
+    Example: `#define CLIENT_HELLO_RANDOM_LEN 32`
+
+  - When declaring a pointer the dereferencing operator should be prepended to
+    the pointer name not appended to the pointer type:
+
+    Example: `mbedtls_ssl_context *ssl;`
+
+  - Maximum line length is 80 characters.
+
+    Exceptions:
+
+    - string literals can extend beyond 80 characters as we do not want to
+      split them to ease their search in the code base.
+
+    - A line can be more than 80 characters by a few characters if just looking
+      at the 80 first characters is enough to fully understand the line. For
+      example it is generally fine if some closure characters like ";" or ")"
+      are beyond the 80 characters limit.
+
+    If a line becomes too long due to a refactoring (for example renaming a
+    function to a longer name, or indenting a block more), avoid rewrapping
+    lines in the same commit: it makes the review harder. Make one commit with
+    the longer lines and another commit with just the rewrapping.
+
+  - When in successive lines, functions and macros parameters should be aligned
+    vertically.
+
+    Example:
+    ```
+    int mbedtls_ssl_tls13_start_handshake_msg( mbedtls_ssl_context *ssl,
+                                               unsigned hs_type,
+                                               unsigned char **buf,
+                                               size_t *buf_len );
+    ```
+
+  - When a function's parameters span several lines, group related parameters
+    together if possible.
+
+    For example, prefer:
+
+    ```
+    mbedtls_ssl_tls13_start_handshake_msg( ssl, hs_type,
+                                           buf, buf_len );
+    ```
+    over
+    ```
+    mbedtls_ssl_tls13_start_handshake_msg( ssl, hs_type, buf,
+                                           buf_len );
+    ```
+    even if it fits.
diff --git a/include/mbedtls/asn1.h b/include/mbedtls/asn1.h
index f45fc17..4746c1c 100644
--- a/include/mbedtls/asn1.h
+++ b/include/mbedtls/asn1.h
@@ -152,9 +152,9 @@
  */
 typedef struct mbedtls_asn1_buf
 {
-    int MBEDTLS_PRIVATE(tag);                /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */
-    size_t MBEDTLS_PRIVATE(len);             /**< ASN1 length, in octets. */
-    unsigned char *MBEDTLS_PRIVATE(p);       /**< ASN1 data, e.g. in ASCII. */
+    int tag;                /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */
+    size_t len;             /**< ASN1 length, in octets. */
+    unsigned char *p;       /**< ASN1 data, e.g. in ASCII. */
 }
 mbedtls_asn1_buf;
 
@@ -163,9 +163,9 @@
  */
 typedef struct mbedtls_asn1_bitstring
 {
-    size_t MBEDTLS_PRIVATE(len);                 /**< ASN1 length, in octets. */
-    unsigned char MBEDTLS_PRIVATE(unused_bits);  /**< Number of unused bits at the end of the string */
-    unsigned char *MBEDTLS_PRIVATE(p);           /**< Raw ASN1 data for the bit string */
+    size_t len;                 /**< ASN1 length, in octets. */
+    unsigned char unused_bits;  /**< Number of unused bits at the end of the string */
+    unsigned char *p;           /**< Raw ASN1 data for the bit string */
 }
 mbedtls_asn1_bitstring;
 
@@ -174,8 +174,16 @@
  */
 typedef struct mbedtls_asn1_sequence
 {
-    mbedtls_asn1_buf MBEDTLS_PRIVATE(buf);                   /**< Buffer containing the given ASN.1 item. */
-    struct mbedtls_asn1_sequence *MBEDTLS_PRIVATE(next);    /**< The next entry in the sequence. */
+    mbedtls_asn1_buf buf;                   /**< Buffer containing the given ASN.1 item. */
+
+    /** The next entry in the sequence.
+     *
+     * The details of memory management for sequences are not documented and
+     * may change in future versions. Set this field to \p NULL when
+     * initializing a structure, and do not modify it except via Mbed TLS
+     * library functions.
+     */
+    struct mbedtls_asn1_sequence *next;
 }
 mbedtls_asn1_sequence;
 
@@ -184,10 +192,24 @@
  */
 typedef struct mbedtls_asn1_named_data
 {
-    mbedtls_asn1_buf MBEDTLS_PRIVATE(oid);                   /**< The object identifier. */
-    mbedtls_asn1_buf MBEDTLS_PRIVATE(val);                   /**< The named value. */
-    struct mbedtls_asn1_named_data *MBEDTLS_PRIVATE(next);  /**< The next entry in the sequence. */
-    unsigned char MBEDTLS_PRIVATE(next_merged);      /**< Merge next item into the current one? */
+    mbedtls_asn1_buf oid;                   /**< The object identifier. */
+    mbedtls_asn1_buf val;                   /**< The named value. */
+
+    /** The next entry in the sequence.
+     *
+     * The details of memory management for named data sequences are not
+     * documented and may change in future versions. Set this field to \p NULL
+     * when initializing a structure, and do not modify it except via Mbed TLS
+     * library functions.
+     */
+    struct mbedtls_asn1_named_data *next;
+
+    /** Merge next item into the current one?
+     *
+     * This field exists for the sake of Mbed TLS's X.509 certificate parsing
+     * code and may change in future versions of the library.
+     */
+    unsigned char MBEDTLS_PRIVATE(next_merged);
 }
 mbedtls_asn1_named_data;
 
diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h
index 9c9a2e8..b4630f6 100644
--- a/include/mbedtls/cipher.h
+++ b/include/mbedtls/cipher.h
@@ -258,6 +258,13 @@
 /**
  * Cipher information. Allows calling cipher functions
  * in a generic way.
+ *
+ * \note        The library does not support custom cipher info structures,
+ *              only built-in structures returned by the functions
+ *              mbedtls_cipher_info_from_string(),
+ *              mbedtls_cipher_info_from_type(),
+ *              mbedtls_cipher_info_from_values(),
+ *              mbedtls_cipher_info_from_psa().
  */
 typedef struct mbedtls_cipher_info_t
 {
@@ -415,6 +422,82 @@
                                               const mbedtls_cipher_mode_t mode );
 
 /**
+ * \brief               Retrieve the identifier for a cipher info structure.
+ *
+ * \param[in] info      The cipher info structure to query.
+ *                      This may be \c NULL.
+ *
+ * \return              The full cipher identifier (\c MBEDTLS_CIPHER_xxx).
+ * \return              #MBEDTLS_CIPHER_NONE if \p info is \c NULL.
+ */
+static inline mbedtls_cipher_type_t mbedtls_cipher_info_get_type(
+    const mbedtls_cipher_info_t *info )
+{
+    if( info == NULL )
+        return( MBEDTLS_CIPHER_NONE );
+    else
+        return( info->MBEDTLS_PRIVATE(type) );
+}
+
+/**
+ * \brief               Retrieve the operation mode for a cipher info structure.
+ *
+ * \param[in] info      The cipher info structure to query.
+ *                      This may be \c NULL.
+ *
+ * \return              The cipher mode (\c MBEDTLS_MODE_xxx).
+ * \return              #MBEDTLS_MODE_NONE if \p info is \c NULL.
+ */
+static inline mbedtls_cipher_mode_t mbedtls_cipher_info_get_mode(
+    const mbedtls_cipher_info_t *info )
+{
+    if( info == NULL )
+        return( MBEDTLS_MODE_NONE );
+    else
+        return( info->MBEDTLS_PRIVATE(mode) );
+}
+
+/**
+ * \brief               Retrieve the key size for a cipher info structure.
+ *
+ * \param[in] info      The cipher info structure to query.
+ *                      This may be \c NULL.
+ *
+ * \return              The key length in bits.
+ *                      For variable-sized ciphers, this is the default length.
+ *                      For DES, this includes the parity bits.
+ * \return              \c 0 if \p info is \c NULL.
+ */
+static inline size_t mbedtls_cipher_info_get_key_bitlen(
+    const mbedtls_cipher_info_t *info )
+{
+    if( info == NULL )
+        return( 0 );
+    else
+        return( info->MBEDTLS_PRIVATE(key_bitlen) );
+}
+
+/**
+ * \brief               Retrieve the human-readable name for a
+ *                      cipher info structure.
+ *
+ * \param[in] info      The cipher info structure to query.
+ *                      This may be \c NULL.
+ *
+ * \return              The cipher name, which is a human readable string,
+ *                      with static storage duration.
+ * \return              \c NULL if \c info is \p NULL.
+ */
+static inline const char *mbedtls_cipher_info_get_name(
+    const mbedtls_cipher_info_t *info )
+{
+    if( info == NULL )
+        return( NULL );
+    else
+        return( info->MBEDTLS_PRIVATE(name) );
+}
+
+/**
  * \brief               This function initializes a \p cipher_context as NONE.
  *
  * \param ctx           The context to be initialized. This must not be \c NULL.
diff --git a/include/mbedtls/config_psa.h b/include/mbedtls/config_psa.h
index 9080cd1..3b01b78 100644
--- a/include/mbedtls/config_psa.h
+++ b/include/mbedtls/config_psa.h
@@ -586,7 +586,7 @@
 #define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN 1
 #define PSA_WANT_ALG_RSA_PKCS1V15_SIGN 1
 #define PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW 1
-#endif /* MBEDTLSS_PKCS1_V15 */
+#endif /* MBEDTLS_PKCS1_V15 */
 #if defined(MBEDTLS_PKCS1_V21)
 #define MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP 1
 #define PSA_WANT_ALG_RSA_OAEP 1
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index 384d060..b2a2e32 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -147,13 +147,17 @@
 
 /**
  * Curve information, for use by other modules.
+ *
+ * The fields of this structure are part of the public API and can be
+ * accessed directly by applications. Future versions of the library may
+ * add extra fields or reorder existing fields.
  */
 typedef struct mbedtls_ecp_curve_info
 {
-    mbedtls_ecp_group_id MBEDTLS_PRIVATE(grp_id);    /*!< An internal identifier. */
-    uint16_t MBEDTLS_PRIVATE(tls_id);                /*!< The TLS NamedCurve identifier. */
-    uint16_t MBEDTLS_PRIVATE(bit_size);              /*!< The curve size in bits. */
-    const char *MBEDTLS_PRIVATE(name);               /*!< A human-friendly name. */
+    mbedtls_ecp_group_id grp_id;    /*!< An internal identifier. */
+    uint16_t tls_id;                /*!< The TLS NamedCurve identifier. */
+    uint16_t bit_size;              /*!< The curve size in bits. */
+    const char *name;               /*!< A human-friendly name. */
 } mbedtls_ecp_curve_info;
 
 /**
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index 683c913..adc317d 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -3173,7 +3173,7 @@
  * Maximum number of heap-allocated bytes for the purpose of
  * DTLS handshake message reassembly and future message buffering.
  *
- * This should be at least 9/8 * MBEDTLSSL_IN_CONTENT_LEN
+ * This should be at least 9/8 * MBEDTLS_SSL_IN_CONTENT_LEN
  * to account for a reassembled handshake message of maximum size,
  * together with its reassembly bitmap.
  *
diff --git a/include/mbedtls/net_sockets.h b/include/mbedtls/net_sockets.h
index c8214a2..0c754b1 100644
--- a/include/mbedtls/net_sockets.h
+++ b/include/mbedtls/net_sockets.h
@@ -94,7 +94,13 @@
  */
 typedef struct mbedtls_net_context
 {
-    int MBEDTLS_PRIVATE(fd);             /**< The underlying file descriptor                 */
+    /** The underlying file descriptor.
+     *
+     * This field is only guaranteed to be present on POSIX/Unix-like platforms.
+     * On other platforms, it may have a different type, have a different
+     * meaning, or be absent altogether.
+     */
+    int fd;
 }
 mbedtls_net_context;
 
diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h
index ded5222..5f9f29f 100644
--- a/include/mbedtls/pk.h
+++ b/include/mbedtls/pk.h
@@ -186,6 +186,10 @@
 
 /**
  * \brief           Public key information and operations
+ *
+ * \note        The library does not support custom pk info structures,
+ *              only built-in structures returned by
+ *              mbedtls_cipher_info_from_type().
  */
 typedef struct mbedtls_pk_info_t mbedtls_pk_info_t;
 
diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h
index f6f2e58..80bcd72 100644
--- a/include/mbedtls/psa_util.h
+++ b/include/mbedtls/psa_util.h
@@ -57,6 +57,9 @@
         case MBEDTLS_CIPHER_AES_128_CBC:
         case MBEDTLS_CIPHER_AES_192_CBC:
         case MBEDTLS_CIPHER_AES_256_CBC:
+        case MBEDTLS_CIPHER_AES_128_ECB:
+        case MBEDTLS_CIPHER_AES_192_ECB:
+        case MBEDTLS_CIPHER_AES_256_ECB:
             return( PSA_KEY_TYPE_AES );
 
         /* ARIA not yet supported in PSA. */
@@ -369,7 +372,7 @@
     if( curve_info == NULL )
         return( 0 );
     return( PSA_KEY_TYPE_ECC_KEY_PAIR(
-                mbedtls_ecc_group_to_psa( curve_info->MBEDTLS_PRIVATE(grp_id), bits ) ) );
+                mbedtls_ecc_group_to_psa( curve_info->grp_id, bits ) ) );
 }
 #endif /* MBEDTLS_ECP_C */
 
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 2c77dbe..c1b1836 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -626,6 +626,7 @@
     MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT,
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
     MBEDTLS_SSL_ENCRYPTED_EXTENSIONS,
+    MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY,
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
 }
 mbedtls_ssl_states;
@@ -1529,6 +1530,19 @@
     int MBEDTLS_PRIVATE(keep_current_message);   /*!< drop or reuse current message
                                      on next call to record layer? */
 
+    /* The following three variables indicate if and, if yes,
+     * what kind of alert is pending to be sent.
+     */
+    unsigned char MBEDTLS_PRIVATE(send_alert);   /*!< Determines if a fatal alert
+                                                should be sent. Values:
+                                                - \c 0 , no alert is to be sent.
+                                                - \c 1 , alert is to be sent. */
+    unsigned char MBEDTLS_PRIVATE(alert_type);   /*!< Type of alert if send_alert
+                                                 != 0 */
+    int MBEDTLS_PRIVATE(alert_reason);           /*!< The error code to be returned
+                                                 to the user once the fatal alert
+                                                 has been sent. */
+
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
     uint8_t MBEDTLS_PRIVATE(disable_datagram_packing);  /*!< Disable packing multiple records
                                         *   within a single datagram.  */
diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h
index df187cb..9a4be95 100644
--- a/include/mbedtls/x509.h
+++ b/include/mbedtls/x509.h
@@ -246,8 +246,8 @@
 /** Container for date and time (precision in seconds). */
 typedef struct mbedtls_x509_time
 {
-    int MBEDTLS_PRIVATE(year), MBEDTLS_PRIVATE(mon), MBEDTLS_PRIVATE(day);         /**< Date. */
-    int MBEDTLS_PRIVATE(hour), MBEDTLS_PRIVATE(min), MBEDTLS_PRIVATE(sec);         /**< Time. */
+    int year, mon, day;         /**< Date. */
+    int hour, min, sec;         /**< Time. */
 }
 mbedtls_x509_time;
 
diff --git a/include/mbedtls/x509_crl.h b/include/mbedtls/x509_crl.h
index 9331827..52bd43c 100644
--- a/include/mbedtls/x509_crl.h
+++ b/include/mbedtls/x509_crl.h
@@ -43,18 +43,30 @@
 /**
  * Certificate revocation list entry.
  * Contains the CA-specific serial numbers and revocation dates.
+ *
+ * Some fields of this structure are publicly readable. Do not modify
+ * them except via Mbed TLS library functions: the effect of modifying
+ * those fields or the data that those fields points to is unspecified.
  */
 typedef struct mbedtls_x509_crl_entry
 {
-    mbedtls_x509_buf MBEDTLS_PRIVATE(raw);
+    /** Direct access to the whole entry inside the containing buffer. */
+    mbedtls_x509_buf raw;
+    /** The serial number of the revoked certificate. */
+    mbedtls_x509_buf serial;
+    /** The revocation date of this entry. */
+    mbedtls_x509_time revocation_date;
+    /** Direct access to the list of CRL entry extensions
+     * (an ASN.1 constructed sequence).
+     *
+     * If there are no extensions, `entry_ext.len == 0` and
+     * `entry_ext.p == NULL`. */
+    mbedtls_x509_buf entry_ext;
 
-    mbedtls_x509_buf MBEDTLS_PRIVATE(serial);
-
-    mbedtls_x509_time MBEDTLS_PRIVATE(revocation_date);
-
-    mbedtls_x509_buf MBEDTLS_PRIVATE(entry_ext);
-
-    struct mbedtls_x509_crl_entry *MBEDTLS_PRIVATE(next);
+    /** Next element in the linked list of entries.
+     * \p NULL indicates the end of the list.
+     * Do not modify this field directly. */
+    struct mbedtls_x509_crl_entry *next;
 }
 mbedtls_x509_crl_entry;
 
@@ -64,22 +76,22 @@
  */
 typedef struct mbedtls_x509_crl
 {
-    mbedtls_x509_buf MBEDTLS_PRIVATE(raw);           /**< The raw certificate data (DER). */
-    mbedtls_x509_buf MBEDTLS_PRIVATE(tbs);           /**< The raw certificate body (DER). The part that is To Be Signed. */
+    mbedtls_x509_buf raw;           /**< The raw certificate data (DER). */
+    mbedtls_x509_buf tbs;           /**< The raw certificate body (DER). The part that is To Be Signed. */
 
-    int MBEDTLS_PRIVATE(version);            /**< CRL version (1=v1, 2=v2) */
-    mbedtls_x509_buf MBEDTLS_PRIVATE(sig_oid);       /**< CRL signature type identifier */
+    int version;            /**< CRL version (1=v1, 2=v2) */
+    mbedtls_x509_buf sig_oid;       /**< CRL signature type identifier */
 
-    mbedtls_x509_buf MBEDTLS_PRIVATE(issuer_raw);    /**< The raw issuer data (DER). */
+    mbedtls_x509_buf issuer_raw;    /**< The raw issuer data (DER). */
 
-    mbedtls_x509_name MBEDTLS_PRIVATE(issuer);       /**< The parsed issuer data (named information object). */
+    mbedtls_x509_name issuer;       /**< The parsed issuer data (named information object). */
 
-    mbedtls_x509_time MBEDTLS_PRIVATE(this_update);
-    mbedtls_x509_time MBEDTLS_PRIVATE(next_update);
+    mbedtls_x509_time this_update;
+    mbedtls_x509_time next_update;
 
-    mbedtls_x509_crl_entry MBEDTLS_PRIVATE(entry);   /**< The CRL entries containing the certificate revocation times for this CA. */
+    mbedtls_x509_crl_entry entry;   /**< The CRL entries containing the certificate revocation times for this CA. */
 
-    mbedtls_x509_buf MBEDTLS_PRIVATE(crl_ext);
+    mbedtls_x509_buf crl_ext;
 
     mbedtls_x509_buf MBEDTLS_PRIVATE(sig_oid2);
     mbedtls_x509_buf MBEDTLS_PRIVATE(sig);
@@ -87,7 +99,10 @@
     mbedtls_pk_type_t MBEDTLS_PRIVATE(sig_pk);           /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */
     void *MBEDTLS_PRIVATE(sig_opts);             /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */
 
-    struct mbedtls_x509_crl *MBEDTLS_PRIVATE(next);
+    /** Next element in the linked list of CRL.
+     * \p NULL indicates the end of the list.
+     * Do not modify this field directly. */
+    struct mbedtls_x509_crl *next;
 }
 mbedtls_x509_crl;
 
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index 49211a9..3c11a99 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -45,36 +45,40 @@
 
 /**
  * Container for an X.509 certificate. The certificate may be chained.
+ *
+ * Some fields of this structure are publicly readable. Do not modify
+ * them except via Mbed TLS library functions: the effect of modifying
+ * those fields or the data that those fields points to is unspecified.
  */
 typedef struct mbedtls_x509_crt
 {
     int MBEDTLS_PRIVATE(own_buffer);                     /**< Indicates if \c raw is owned
                                          *   by the structure or not.        */
-    mbedtls_x509_buf MBEDTLS_PRIVATE(raw);               /**< The raw certificate data (DER). */
-    mbedtls_x509_buf MBEDTLS_PRIVATE(tbs);               /**< The raw certificate body (DER). The part that is To Be Signed. */
+    mbedtls_x509_buf raw;               /**< The raw certificate data (DER). */
+    mbedtls_x509_buf tbs;               /**< The raw certificate body (DER). The part that is To Be Signed. */
 
-    int MBEDTLS_PRIVATE(version);                /**< The X.509 version. (1=v1, 2=v2, 3=v3) */
-    mbedtls_x509_buf MBEDTLS_PRIVATE(serial);            /**< Unique id for certificate issued by a specific CA. */
-    mbedtls_x509_buf MBEDTLS_PRIVATE(sig_oid);           /**< Signature algorithm, e.g. sha1RSA */
+    int version;                /**< The X.509 version. (1=v1, 2=v2, 3=v3) */
+    mbedtls_x509_buf serial;            /**< Unique id for certificate issued by a specific CA. */
+    mbedtls_x509_buf sig_oid;           /**< Signature algorithm, e.g. sha1RSA */
 
-    mbedtls_x509_buf MBEDTLS_PRIVATE(issuer_raw);        /**< The raw issuer data (DER). Used for quick comparison. */
-    mbedtls_x509_buf MBEDTLS_PRIVATE(subject_raw);       /**< The raw subject data (DER). Used for quick comparison. */
+    mbedtls_x509_buf issuer_raw;        /**< The raw issuer data (DER). Used for quick comparison. */
+    mbedtls_x509_buf subject_raw;       /**< The raw subject data (DER). Used for quick comparison. */
 
-    mbedtls_x509_name MBEDTLS_PRIVATE(issuer);           /**< The parsed issuer data (named information object). */
-    mbedtls_x509_name MBEDTLS_PRIVATE(subject);          /**< The parsed subject data (named information object). */
+    mbedtls_x509_name issuer;           /**< The parsed issuer data (named information object). */
+    mbedtls_x509_name subject;          /**< The parsed subject data (named information object). */
 
-    mbedtls_x509_time MBEDTLS_PRIVATE(valid_from);       /**< Start time of certificate validity. */
-    mbedtls_x509_time MBEDTLS_PRIVATE(valid_to);         /**< End time of certificate validity. */
+    mbedtls_x509_time valid_from;       /**< Start time of certificate validity. */
+    mbedtls_x509_time valid_to;         /**< End time of certificate validity. */
 
-    mbedtls_x509_buf MBEDTLS_PRIVATE(pk_raw);
-    mbedtls_pk_context MBEDTLS_PRIVATE(pk);              /**< Container for the public key context. */
+    mbedtls_x509_buf pk_raw;
+    mbedtls_pk_context pk;              /**< Container for the public key context. */
 
-    mbedtls_x509_buf MBEDTLS_PRIVATE(issuer_id);         /**< Optional X.509 v2/v3 issuer unique identifier. */
-    mbedtls_x509_buf MBEDTLS_PRIVATE(subject_id);        /**< Optional X.509 v2/v3 subject unique identifier. */
-    mbedtls_x509_buf MBEDTLS_PRIVATE(v3_ext);            /**< Optional X.509 v3 extensions.  */
-    mbedtls_x509_sequence MBEDTLS_PRIVATE(subject_alt_names);    /**< Optional list of raw entries of Subject Alternative Names extension (currently only dNSName and OtherName are listed). */
+    mbedtls_x509_buf issuer_id;         /**< Optional X.509 v2/v3 issuer unique identifier. */
+    mbedtls_x509_buf subject_id;        /**< Optional X.509 v2/v3 subject unique identifier. */
+    mbedtls_x509_buf v3_ext;            /**< Optional X.509 v3 extensions.  */
+    mbedtls_x509_sequence subject_alt_names;    /**< Optional list of raw entries of Subject Alternative Names extension (currently only dNSName and OtherName are listed). */
 
-    mbedtls_x509_sequence MBEDTLS_PRIVATE(certificate_policies); /**< Optional list of certificate policies (Only anyPolicy is printed and enforced, however the rest of the policies are still listed). */
+    mbedtls_x509_sequence certificate_policies; /**< Optional list of certificate policies (Only anyPolicy is printed and enforced, however the rest of the policies are still listed). */
 
     int MBEDTLS_PRIVATE(ext_types);              /**< Bit string containing detected and parsed extensions */
     int MBEDTLS_PRIVATE(ca_istrue);              /**< Optional Basic Constraint extension value: 1 if this certificate belongs to a CA, 0 otherwise. */
@@ -82,7 +86,7 @@
 
     unsigned int MBEDTLS_PRIVATE(key_usage);     /**< Optional key usage extension value: See the values in x509.h */
 
-    mbedtls_x509_sequence MBEDTLS_PRIVATE(ext_key_usage); /**< Optional list of extended key usage OIDs. */
+    mbedtls_x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */
 
     unsigned char MBEDTLS_PRIVATE(ns_cert_type); /**< Optional Netscape certificate type extension value: See the values in x509.h */
 
@@ -91,7 +95,10 @@
     mbedtls_pk_type_t MBEDTLS_PRIVATE(sig_pk);           /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */
     void *MBEDTLS_PRIVATE(sig_opts);             /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */
 
-    struct mbedtls_x509_crt *MBEDTLS_PRIVATE(next);     /**< Next certificate in the CA-chain. */
+    /** Next certificate in the linked list that constitutes the CA chain.
+     * \p NULL indicates the end of the list.
+     * Do not modify this field directly. */
+    struct mbedtls_x509_crt *next;
 }
 mbedtls_x509_crt;
 
@@ -100,6 +107,9 @@
  * OtherName ::= SEQUENCE {
  *      type-id    OBJECT IDENTIFIER,
  *      value      [0] EXPLICIT ANY DEFINED BY type-id }
+ *
+ * Future versions of the library may add new fields to this structure or
+ * to its embedded union and structure.
  */
 typedef struct mbedtls_x509_san_other_name
 {
@@ -108,7 +118,7 @@
      * To check the value of the type id, you should use
      * \p MBEDTLS_OID_CMP with a known OID mbedtls_x509_buf.
      */
-    mbedtls_x509_buf MBEDTLS_PRIVATE(type_id);                   /**< The type id. */
+    mbedtls_x509_buf type_id;                   /**< The type id. */
     union
     {
         /**
@@ -119,26 +129,30 @@
          */
         struct
         {
-            mbedtls_x509_buf MBEDTLS_PRIVATE(oid);               /**< The object identifier. */
-            mbedtls_x509_buf MBEDTLS_PRIVATE(val);               /**< The named value. */
+            mbedtls_x509_buf oid;               /**< The object identifier. */
+            mbedtls_x509_buf val;               /**< The named value. */
         }
-        MBEDTLS_PRIVATE(hardware_module_name);
+        hardware_module_name;
     }
-    MBEDTLS_PRIVATE(value);
+    value;
 }
 mbedtls_x509_san_other_name;
 
 /**
- * A structure for holding the parsed Subject Alternative Name, according to type
+ * A structure for holding the parsed Subject Alternative Name,
+ * according to type.
+ *
+ * Future versions of the library may add new fields to this structure or
+ * to its embedded union and structure.
  */
 typedef struct mbedtls_x509_subject_alternative_name
 {
-    int MBEDTLS_PRIVATE(type);                              /**< The SAN type, value of MBEDTLS_X509_SAN_XXX. */
+    int type;                              /**< The SAN type, value of MBEDTLS_X509_SAN_XXX. */
     union {
-        mbedtls_x509_san_other_name MBEDTLS_PRIVATE(other_name); /**< The otherName supported type. */
-        mbedtls_x509_buf   MBEDTLS_PRIVATE(unstructured_name); /**< The buffer for the un constructed types. Only dnsName currently supported */
+        mbedtls_x509_san_other_name other_name; /**< The otherName supported type. */
+        mbedtls_x509_buf   unstructured_name; /**< The buffer for the un constructed types. Only dnsName currently supported */
     }
-    MBEDTLS_PRIVATE(san); /**< A union of the supported SAN types */
+    san; /**< A union of the supported SAN types */
 }
 mbedtls_x509_subject_alternative_name;
 
diff --git a/include/mbedtls/x509_csr.h b/include/mbedtls/x509_csr.h
index 674f9ce..f80a1a1 100644
--- a/include/mbedtls/x509_csr.h
+++ b/include/mbedtls/x509_csr.h
@@ -42,20 +42,24 @@
 
 /**
  * Certificate Signing Request (CSR) structure.
+ *
+ * Some fields of this structure are publicly readable. Do not modify
+ * them except via Mbed TLS library functions: the effect of modifying
+ * those fields or the data that those fields point to is unspecified.
  */
 typedef struct mbedtls_x509_csr
 {
-    mbedtls_x509_buf MBEDTLS_PRIVATE(raw);           /**< The raw CSR data (DER). */
-    mbedtls_x509_buf MBEDTLS_PRIVATE(cri);           /**< The raw CertificateRequestInfo body (DER). */
+    mbedtls_x509_buf raw;           /**< The raw CSR data (DER). */
+    mbedtls_x509_buf cri;           /**< The raw CertificateRequestInfo body (DER). */
 
-    int MBEDTLS_PRIVATE(version);            /**< CSR version (1=v1). */
+    int version;            /**< CSR version (1=v1). */
 
-    mbedtls_x509_buf  MBEDTLS_PRIVATE(subject_raw);  /**< The raw subject data (DER). */
-    mbedtls_x509_name MBEDTLS_PRIVATE(subject);      /**< The parsed subject data (named information object). */
+    mbedtls_x509_buf  subject_raw;  /**< The raw subject data (DER). */
+    mbedtls_x509_name subject;      /**< The parsed subject data (named information object). */
 
-    mbedtls_pk_context MBEDTLS_PRIVATE(pk);          /**< Container for the public key context. */
+    mbedtls_pk_context pk;          /**< Container for the public key context. */
 
-    mbedtls_x509_buf MBEDTLS_PRIVATE(sig_oid);
+    mbedtls_x509_buf sig_oid;
     mbedtls_x509_buf MBEDTLS_PRIVATE(sig);
     mbedtls_md_type_t MBEDTLS_PRIVATE(sig_md);       /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */
     mbedtls_pk_type_t MBEDTLS_PRIVATE(sig_pk);       /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */
diff --git a/include/psa/crypto_builtin_composites.h b/include/psa/crypto_builtin_composites.h
index b05660f..8075caf 100644
--- a/include/psa/crypto_builtin_composites.h
+++ b/include/psa/crypto_builtin_composites.h
@@ -77,6 +77,41 @@
 
 #define MBEDTLS_PSA_MAC_OPERATION_INIT {0, {0}}
 
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) || \
+    defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) || \
+    defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
+#define MBEDTLS_PSA_BUILTIN_AEAD  1
+#endif
+
+/* Context structure for the Mbed TLS AEAD implementation. */
+typedef struct
+{
+    psa_algorithm_t MBEDTLS_PRIVATE(alg);
+    psa_key_type_t MBEDTLS_PRIVATE(key_type);
+
+    unsigned int MBEDTLS_PRIVATE(is_encrypt) : 1;
+
+    uint8_t MBEDTLS_PRIVATE(tag_length);
+
+    union
+    {
+        unsigned dummy; /* Enable easier initializing of the union. */
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
+        mbedtls_ccm_context MBEDTLS_PRIVATE(ccm);
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
+        mbedtls_gcm_context MBEDTLS_PRIVATE(gcm);
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
+        mbedtls_chachapoly_context MBEDTLS_PRIVATE(chachapoly);
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
+
+    } ctx;
+
+} mbedtls_psa_aead_operation_t;
+
+#define MBEDTLS_PSA_AEAD_OPERATION_INIT {0, 0, 0, 0, {0}}
+
 /*
  * BEYOND THIS POINT, TEST DRIVER DECLARATIONS ONLY.
  */
@@ -88,6 +123,10 @@
 #define MBEDTLS_TRANSPARENT_TEST_DRIVER_MAC_OPERATION_INIT MBEDTLS_PSA_MAC_OPERATION_INIT
 #define MBEDTLS_OPAQUE_TEST_DRIVER_MAC_OPERATION_INIT MBEDTLS_PSA_MAC_OPERATION_INIT
 
+typedef mbedtls_psa_aead_operation_t mbedtls_transparent_test_driver_aead_operation_t;
+
+#define MBEDTLS_TRANSPARENT_TEST_DRIVER_AEAD_OPERATION_INIT MBEDTLS_PSA_AEAD_OPERATION_INIT
+
 #endif /* PSA_CRYPTO_DRIVER_TEST */
 
 #endif /* PSA_CRYPTO_BUILTIN_COMPOSITES_H */
diff --git a/include/psa/crypto_driver_contexts_composites.h b/include/psa/crypto_driver_contexts_composites.h
index 239fdcb..957986c2 100644
--- a/include/psa/crypto_driver_contexts_composites.h
+++ b/include/psa/crypto_driver_contexts_composites.h
@@ -58,5 +58,13 @@
 #endif
 } psa_driver_mac_context_t;
 
+typedef union {
+    unsigned dummy; /* Make sure this union is always non-empty */
+    mbedtls_psa_aead_operation_t mbedtls_ctx;
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+    mbedtls_transparent_test_driver_aead_operation_t transparent_test_driver_ctx;
+#endif
+} psa_driver_aead_context_t;
+
 #endif /* PSA_CRYPTO_DRIVER_CONTEXTS_COMPOSITES_H */
 /* End of automatically generated file. */
diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h
index 381abf9..2689415 100644
--- a/include/psa/crypto_struct.h
+++ b/include/psa/crypto_struct.h
@@ -72,6 +72,8 @@
 
 #include "mbedtls/cmac.h"
 #include "mbedtls/gcm.h"
+#include "mbedtls/ccm.h"
+#include "mbedtls/chachapoly.h"
 
 /* Include the context definition for the compiled-in drivers for the primitive
  * algorithms. */
@@ -148,19 +150,31 @@
 
 struct psa_aead_operation_s
 {
+
+    /** Unique ID indicating which driver got assigned to do the
+     * operation. Since driver contexts are driver-specific, swapping
+     * drivers halfway through the operation is not supported.
+     * ID values are auto-generated in psa_crypto_driver_wrappers.h
+     * ID value zero means the context is not valid or not assigned to
+     * any driver (i.e. none of the driver contexts are active). */
+    unsigned int MBEDTLS_PRIVATE(id);
+
     psa_algorithm_t MBEDTLS_PRIVATE(alg);
-    unsigned int MBEDTLS_PRIVATE(key_set) : 1;
-    unsigned int MBEDTLS_PRIVATE(iv_set) : 1;
-    uint8_t MBEDTLS_PRIVATE(iv_size);
-    uint8_t MBEDTLS_PRIVATE(block_size);
-    union
-    {
-        unsigned MBEDTLS_PRIVATE(dummy); /* Enable easier initializing of the union. */
-        mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher);
-    } MBEDTLS_PRIVATE(ctx);
+    psa_key_type_t MBEDTLS_PRIVATE(key_type);
+
+    size_t MBEDTLS_PRIVATE(ad_remaining);
+    size_t MBEDTLS_PRIVATE(body_remaining);
+
+    unsigned int MBEDTLS_PRIVATE(nonce_set) : 1;
+    unsigned int MBEDTLS_PRIVATE(lengths_set) : 1;
+    unsigned int MBEDTLS_PRIVATE(ad_started) : 1;
+    unsigned int MBEDTLS_PRIVATE(body_started) : 1;
+    unsigned int MBEDTLS_PRIVATE(is_encrypt) : 1;
+
+    psa_driver_aead_context_t MBEDTLS_PRIVATE(ctx);
 };
 
-#define PSA_AEAD_OPERATION_INIT { 0, 0, 0, 0, 0, { 0 } }
+#define PSA_AEAD_OPERATION_INIT {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0}}
 static inline struct psa_aead_operation_s psa_aead_operation_init( void )
 {
     const struct psa_aead_operation_s v = PSA_AEAD_OPERATION_INIT;
diff --git a/library/cipher.c b/library/cipher.c
index 546cace..dc80189 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -1266,9 +1266,12 @@
         if( status != PSA_SUCCESS )
             return( MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED );
 
-        status = psa_cipher_set_iv( &cipher_op, iv, iv_len );
-        if( status != PSA_SUCCESS )
-            return( MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED );
+        if( ctx->cipher_info->mode != MBEDTLS_MODE_ECB )
+        {
+            status = psa_cipher_set_iv( &cipher_op, iv, iv_len );
+            if( status != PSA_SUCCESS )
+                return( MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED );
+        }
 
         status = psa_cipher_update( &cipher_op,
                                     input, ilen,
diff --git a/library/common.h b/library/common.h
index 780ce37..9b10ec8 100644
--- a/library/common.h
+++ b/library/common.h
@@ -318,4 +318,12 @@
 }
 #endif
 
+/* Fix MSVC C99 compatible issue
+ *      MSVC support __func__ from visual studio 2015( 1900 )
+ *      Use MSVC predefine macro to avoid name check fail.
+ */
+#if (defined(_MSC_VER) && ( _MSC_VER <= 1900 ))
+#define /*no-check-names*/ __func__ __FUNCTION__
+#endif
+
 #endif /* MBEDTLS_LIBRARY_COMMON_H */
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index bcbaa3d..ece64b1 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -3609,6 +3609,50 @@
 /* AEAD */
 /****************************************************************/
 
+/* Helper function to get the base algorithm from its variants. */
+static psa_algorithm_t psa_aead_get_base_algorithm( psa_algorithm_t alg )
+{
+    return PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG( alg );
+}
+
+/* Helper function to perform common nonce length checks. */
+static psa_status_t psa_aead_check_nonce_length( psa_algorithm_t alg,
+                                                 size_t nonce_length )
+{
+    psa_algorithm_t base_alg = psa_aead_get_base_algorithm( alg );
+
+#if defined(PSA_WANT_ALG_GCM)
+    if( base_alg == PSA_ALG_GCM )
+    {
+        /* Not checking max nonce size here as GCM spec allows almost
+         * arbitrarily large nonces. Please note that we do not generally
+         * recommend the usage of nonces of greater length than
+         * PSA_AEAD_NONCE_MAX_SIZE, as large nonces are hashed to a shorter
+         * size, which can then lead to collisions if you encrypt a very
+         * large number of messages.*/
+        if( nonce_length != 0 )
+            return( PSA_SUCCESS );
+    }
+#endif /* PSA_WANT_ALG_GCM */
+#if defined(PSA_WANT_ALG_CCM)
+    if( base_alg == PSA_ALG_CCM )
+    {
+        if( nonce_length >= 7 && nonce_length <= 13 )
+            return( PSA_SUCCESS );
+    }
+    else
+#endif /* PSA_WANT_ALG_CCM */
+#if defined(PSA_WANT_ALG_CHACHA20_POLY1305)
+    if( base_alg == PSA_ALG_CHACHA20_POLY1305 )
+    {
+        if( nonce_length == 12 )
+            return( PSA_SUCCESS );
+    }
+#endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */
+
+    return( PSA_ERROR_NOT_SUPPORTED );
+}
+
 psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key,
                                psa_algorithm_t alg,
                                const uint8_t *nonce,
@@ -3638,6 +3682,10 @@
       .core = slot->attr
     };
 
+    status = psa_aead_check_nonce_length( alg, nonce_length );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
     status = psa_driver_wrapper_aead_encrypt(
         &attributes, slot->key.data, slot->key.bytes,
         alg,
@@ -3649,6 +3697,7 @@
     if( status != PSA_SUCCESS && ciphertext_size != 0 )
         memset( ciphertext, 0, ciphertext_size );
 
+exit:
     psa_unlock_key_slot( slot );
 
     return( status );
@@ -3683,6 +3732,10 @@
       .core = slot->attr
     };
 
+    status = psa_aead_check_nonce_length( alg, nonce_length );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
     status = psa_driver_wrapper_aead_decrypt(
         &attributes, slot->key.data, slot->key.bytes,
         alg,
@@ -3694,11 +3747,474 @@
     if( status != PSA_SUCCESS && plaintext_size != 0 )
         memset( plaintext, 0, plaintext_size );
 
+exit:
     psa_unlock_key_slot( slot );
 
     return( status );
 }
 
+/* Set the key for a multipart authenticated operation. */
+static psa_status_t psa_aead_setup( psa_aead_operation_t *operation,
+                                    int is_encrypt,
+                                    mbedtls_svc_key_id_t key,
+                                    psa_algorithm_t alg )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_slot_t *slot = NULL;
+    psa_key_usage_t key_usage = 0;
+
+    if( !PSA_ALG_IS_AEAD( alg ) || PSA_ALG_IS_WILDCARD( alg ) )
+    {
+        status = PSA_ERROR_INVALID_ARGUMENT;
+        goto exit;
+    }
+
+    if( operation->id != 0 )
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    if( operation->nonce_set || operation->lengths_set ||
+        operation->ad_started || operation->body_started )
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    if( is_encrypt )
+        key_usage = PSA_KEY_USAGE_ENCRYPT;
+    else
+        key_usage = PSA_KEY_USAGE_DECRYPT;
+
+    status = psa_get_and_lock_key_slot_with_policy( key, &slot, key_usage,
+                                                    alg );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    psa_key_attributes_t attributes = {
+        .core = slot->attr
+    };
+
+    if( is_encrypt )
+        status = psa_driver_wrapper_aead_encrypt_setup( operation,
+                                                        &attributes,
+                                                        slot->key.data,
+                                                        slot->key.bytes,
+                                                        alg );
+    else
+        status = psa_driver_wrapper_aead_decrypt_setup( operation,
+                                                        &attributes,
+                                                        slot->key.data,
+                                                        slot->key.bytes,
+                                                        alg );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    operation->key_type = psa_get_key_type( &attributes );
+
+exit:
+    unlock_status = psa_unlock_key_slot( slot );
+
+    if( status == PSA_SUCCESS )
+    {
+        status = unlock_status;
+        operation->alg = psa_aead_get_base_algorithm( alg );
+        operation->is_encrypt = is_encrypt;
+    }
+    else
+        psa_aead_abort( operation );
+
+    return( status );
+}
+
+/* Set the key for a multipart authenticated encryption operation. */
+psa_status_t psa_aead_encrypt_setup( psa_aead_operation_t *operation,
+                                     mbedtls_svc_key_id_t key,
+                                     psa_algorithm_t alg )
+{
+    return( psa_aead_setup( operation, 1, key, alg ) );
+}
+
+/* Set the key for a multipart authenticated decryption operation. */
+psa_status_t psa_aead_decrypt_setup( psa_aead_operation_t *operation,
+                                     mbedtls_svc_key_id_t key,
+                                     psa_algorithm_t alg )
+{
+    return( psa_aead_setup( operation, 0, key, alg ) );
+}
+
+/* Generate a random nonce / IV for multipart AEAD operation */
+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 = PSA_ERROR_CORRUPTION_DETECTED;
+    size_t required_nonce_size;
+
+    *nonce_length = 0;
+
+    if( operation->id == 0 )
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    if( operation->nonce_set || !operation->is_encrypt )
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    required_nonce_size = PSA_AEAD_NONCE_LENGTH( operation->key_type,
+                                                 operation->alg );
+    if( nonce_size < required_nonce_size )
+    {
+        status = PSA_ERROR_BUFFER_TOO_SMALL;
+        goto exit;
+    }
+
+    status = psa_generate_random( nonce, required_nonce_size );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    status = psa_aead_set_nonce( operation, nonce, required_nonce_size );
+
+exit:
+    if( status == PSA_SUCCESS )
+        *nonce_length = required_nonce_size;
+    else
+        psa_aead_abort( operation );
+
+    return( status );
+}
+
+/* Set the nonce for a multipart authenticated encryption or decryption
+   operation.*/
+psa_status_t psa_aead_set_nonce( psa_aead_operation_t *operation,
+                                 const uint8_t *nonce,
+                                 size_t nonce_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+    if( operation->id == 0 )
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    if( operation->nonce_set )
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    status = psa_aead_check_nonce_length( operation->alg, nonce_length );
+    if( status != PSA_SUCCESS )
+    {
+        status = PSA_ERROR_INVALID_ARGUMENT;
+        goto exit;
+    }
+
+    status = psa_driver_wrapper_aead_set_nonce( operation, nonce,
+                                                nonce_length );
+
+exit:
+    if( status == PSA_SUCCESS )
+        operation->nonce_set = 1;
+    else
+        psa_aead_abort( operation );
+
+    return( status );
+}
+
+/* Declare the lengths of the message and additional data for multipart AEAD. */
+psa_status_t psa_aead_set_lengths( psa_aead_operation_t *operation,
+                                   size_t ad_length,
+                                   size_t plaintext_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+    if( operation->id == 0 )
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    if( operation->lengths_set || operation->ad_started ||
+        operation->body_started )
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+#if defined(PSA_WANT_ALG_GCM)
+    if( operation->alg == PSA_ALG_GCM )
+    {
+        /* Lengths can only be too large for GCM if size_t is bigger than 32
+         * bits. Without the guard this code will generate warnings on 32bit
+         * builds. */
+#if SIZE_MAX > UINT32_MAX
+        if( (( uint64_t ) ad_length ) >> 61 != 0 ||
+            (( uint64_t ) plaintext_length ) > 0xFFFFFFFE0ull )
+        {
+            status = PSA_ERROR_INVALID_ARGUMENT;
+            goto exit;
+        }
+#endif
+    }
+    else
+#endif /* PSA_WANT_ALG_GCM */
+#if defined(PSA_WANT_ALG_CCM)
+    if( operation->alg == PSA_ALG_CCM )
+    {
+        if( ad_length > 0xFF00 )
+        {
+            status = PSA_ERROR_INVALID_ARGUMENT;
+            goto exit;
+        }
+    }
+    else
+#endif /* PSA_WANT_ALG_CCM */
+#if defined(PSA_WANT_ALG_CHACHA20_POLY1305)
+    if( operation->alg == PSA_ALG_CHACHA20_POLY1305 )
+    {
+        /* No length restrictions for ChaChaPoly. */
+    }
+#endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */
+
+    status = psa_driver_wrapper_aead_set_lengths( operation, ad_length,
+                                                  plaintext_length );
+
+exit:
+    if( status == PSA_SUCCESS )
+    {
+        operation->ad_remaining = ad_length;
+        operation->body_remaining = plaintext_length;
+        operation->lengths_set = 1;
+    }
+    else
+        psa_aead_abort( operation );
+
+    return( status );
+}
+
+/* Pass additional data to an active multipart AEAD operation. */
+psa_status_t psa_aead_update_ad( psa_aead_operation_t *operation,
+                                 const uint8_t *input,
+                                 size_t input_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+    if( operation->id == 0 )
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    if( !operation->nonce_set || operation->body_started )
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    if( operation->lengths_set )
+    {
+        if( operation->ad_remaining < input_length )
+        {
+            status = PSA_ERROR_INVALID_ARGUMENT;
+            goto exit;
+        }
+
+        operation->ad_remaining -= input_length;
+    }
+
+    status = psa_driver_wrapper_aead_update_ad( operation, input,
+                                                input_length );
+
+exit:
+    if( status == PSA_SUCCESS )
+        operation->ad_started = 1;
+    else
+        psa_aead_abort( operation );
+
+    return( status );
+}
+
+/* Encrypt or decrypt a message fragment in an active multipart AEAD
+   operation.*/
+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 = PSA_ERROR_CORRUPTION_DETECTED;
+
+    *output_length = 0;
+
+    if( operation->id == 0 )
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    if( !operation->nonce_set )
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    if( operation->lengths_set )
+    {
+        /* Additional data length was supplied, but not all the additional
+           data was supplied.*/
+        if( operation->ad_remaining != 0 )
+        {
+            status = PSA_ERROR_INVALID_ARGUMENT;
+            goto exit;
+        }
+
+        /* Too much data provided. */
+        if( operation->body_remaining < input_length )
+        {
+            status = PSA_ERROR_INVALID_ARGUMENT;
+            goto exit;
+        }
+
+        operation->body_remaining -= input_length;
+    }
+
+    status = psa_driver_wrapper_aead_update( operation, input, input_length,
+                                             output, output_size,
+                                             output_length );
+
+exit:
+    if( status == PSA_SUCCESS )
+        operation->body_started = 1;
+    else
+        psa_aead_abort( operation );
+
+    return( status );
+}
+
+static psa_status_t psa_aead_final_checks( const psa_aead_operation_t *operation )
+{
+    if( operation->id == 0 || !operation->nonce_set )
+        return( PSA_ERROR_BAD_STATE );
+
+    if( operation->lengths_set && ( operation->ad_remaining != 0 ||
+                                   operation->body_remaining != 0 ) )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
+    return( PSA_SUCCESS );
+}
+
+/* Finish encrypting a message in a multipart AEAD operation. */
+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 = PSA_ERROR_CORRUPTION_DETECTED;
+
+    *ciphertext_length = 0;
+    *tag_length = tag_size;
+
+    status = psa_aead_final_checks( operation );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    if( !operation->is_encrypt )
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    status = psa_driver_wrapper_aead_finish( operation, ciphertext,
+                                             ciphertext_size,
+                                             ciphertext_length,
+                                             tag, tag_size, tag_length );
+
+exit:
+    /* In case the operation fails and the user fails to check for failure or
+     * the zero tag size, make sure the tag is set to something implausible.
+     * Even if the operation succeeds, make sure we clear the rest of the
+     * buffer to prevent potential leakage of anything previously placed in
+     * the same buffer.*/
+    if( tag != NULL )
+    {
+        if( status != PSA_SUCCESS )
+            memset( tag, '!', tag_size );
+        else if( *tag_length < tag_size )
+            memset( tag + *tag_length, '!', ( tag_size - *tag_length ) );
+    }
+
+    psa_aead_abort( operation );
+
+    return( status );
+}
+
+/* Finish authenticating and decrypting a message in a multipart AEAD
+   operation.*/
+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 = PSA_ERROR_CORRUPTION_DETECTED;
+
+    *plaintext_length = 0;
+
+    status = psa_aead_final_checks( operation );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    if( operation->is_encrypt )
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    status = psa_driver_wrapper_aead_verify( operation, plaintext,
+                                             plaintext_size,
+                                             plaintext_length,
+                                             tag, tag_length );
+
+exit:
+    psa_aead_abort( operation );
+
+    return( status );
+}
+
+/* Abort an AEAD operation. */
+psa_status_t psa_aead_abort( psa_aead_operation_t *operation )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+    if( operation->id == 0 )
+    {
+        /* The object has (apparently) been initialized but it is not (yet)
+         * in use. It's ok to call abort on such an object, and there's
+         * nothing to do. */
+        return( PSA_SUCCESS );
+    }
+
+    status = psa_driver_wrapper_aead_abort( operation );
+
+    memset( operation, 0, sizeof( *operation ) );
+
+    return( status );
+}
+
 /****************************************************************/
 /* Generators */
 /****************************************************************/
diff --git a/library/psa_crypto_aead.c b/library/psa_crypto_aead.c
index 356679c..a72865c 100644
--- a/library/psa_crypto_aead.c
+++ b/library/psa_crypto_aead.c
@@ -25,58 +25,24 @@
 #include "psa_crypto_aead.h"
 #include "psa_crypto_core.h"
 
+#include <string.h>
+#include "mbedtls/platform.h"
+#if !defined(MBEDTLS_PLATFORM_C)
+#define mbedtls_calloc calloc
+#define mbedtls_free   free
+#endif
+
 #include "mbedtls/ccm.h"
 #include "mbedtls/chachapoly.h"
 #include "mbedtls/cipher.h"
 #include "mbedtls/gcm.h"
-
-typedef struct
-{
-    union
-    {
-        unsigned dummy; /* Make the union non-empty even with no supported algorithms. */
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
-        mbedtls_ccm_context ccm;
-#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
-        mbedtls_gcm_context gcm;
-#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
-        mbedtls_chachapoly_context chachapoly;
-#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
-    } ctx;
-    psa_algorithm_t core_alg;
-    uint8_t tag_length;
-} aead_operation_t;
-
-#define AEAD_OPERATION_INIT {{0}, 0, 0}
-
-static void psa_aead_abort_internal( aead_operation_t *operation )
-{
-    switch( operation->core_alg )
-    {
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
-        case PSA_ALG_CCM:
-            mbedtls_ccm_free( &operation->ctx.ccm );
-            break;
-#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
-        case PSA_ALG_GCM:
-            mbedtls_gcm_free( &operation->ctx.gcm );
-            break;
-#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
-        case PSA_ALG_CHACHA20_POLY1305:
-            mbedtls_chachapoly_free( &operation->ctx.chachapoly );
-            break;
-#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
-    }
-}
+#include "mbedtls/error.h"
 
 static psa_status_t psa_aead_setup(
-    aead_operation_t *operation,
+    mbedtls_psa_aead_operation_t *operation,
     const psa_key_attributes_t *attributes,
     const uint8_t *key_buffer,
+    size_t key_buffer_size,
     psa_algorithm_t alg )
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
@@ -85,6 +51,8 @@
     mbedtls_cipher_id_t cipher_id;
     size_t full_tag_length = 0;
 
+    ( void ) key_buffer_size;
+
     key_bits = attributes->core.bits;
 
     cipher_info = mbedtls_cipher_info_from_psa( alg,
@@ -97,7 +65,7 @@
     {
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
         case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ):
-            operation->core_alg = PSA_ALG_CCM;
+            operation->alg = PSA_ALG_CCM;
             full_tag_length = 16;
             /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
              * The call to mbedtls_ccm_encrypt_and_tag or
@@ -116,7 +84,7 @@
 
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
         case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 0 ):
-            operation->core_alg = PSA_ALG_GCM;
+            operation->alg = PSA_ALG_GCM;
             full_tag_length = 16;
             /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
              * The call to mbedtls_gcm_crypt_and_tag or
@@ -135,7 +103,7 @@
 
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
         case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CHACHA20_POLY1305, 0 ):
-            operation->core_alg = PSA_ALG_CHACHA20_POLY1305;
+            operation->alg = PSA_ALG_CHACHA20_POLY1305;
             full_tag_length = 16;
             /* We only support the default tag length. */
             if( alg != PSA_ALG_CHACHA20_POLY1305 )
@@ -159,7 +127,9 @@
         > full_tag_length )
         return( PSA_ERROR_INVALID_ARGUMENT );
 
-    operation->tag_length = PSA_AEAD_TAG_LENGTH( attributes->core.type,
+    operation->key_type = psa_get_key_type( attributes );
+
+    operation->tag_length = PSA_AEAD_TAG_LENGTH( operation->key_type,
                                                  key_bits,
                                                  alg );
 
@@ -176,11 +146,12 @@
     uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length )
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
-    aead_operation_t operation = AEAD_OPERATION_INIT;
+    mbedtls_psa_aead_operation_t operation = MBEDTLS_PSA_AEAD_OPERATION_INIT;
     uint8_t *tag;
-    (void) key_buffer_size;
 
-    status = psa_aead_setup( &operation, attributes, key_buffer, alg );
+    status = psa_aead_setup( &operation, attributes, key_buffer,
+                             key_buffer_size, alg );
+
     if( status != PSA_SUCCESS )
         goto exit;
 
@@ -194,7 +165,7 @@
     tag = ciphertext + plaintext_length;
 
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
-    if( operation.core_alg == PSA_ALG_CCM )
+    if( operation.alg == PSA_ALG_CCM )
     {
         status = mbedtls_to_psa_error(
             mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm,
@@ -208,7 +179,7 @@
     else
 #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
-    if( operation.core_alg == PSA_ALG_GCM )
+    if( operation.alg == PSA_ALG_GCM )
     {
         status = mbedtls_to_psa_error(
             mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm,
@@ -222,9 +193,9 @@
     else
 #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
-    if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 )
+    if( operation.alg == PSA_ALG_CHACHA20_POLY1305 )
     {
-        if( nonce_length != 12 || operation.tag_length != 16 )
+        if( operation.tag_length != 16 )
         {
             status = PSA_ERROR_NOT_SUPPORTED;
             goto exit;
@@ -250,7 +221,7 @@
         *ciphertext_length = plaintext_length + operation.tag_length;
 
 exit:
-    psa_aead_abort_internal( &operation );
+    mbedtls_psa_aead_abort( &operation );
 
     return( status );
 }
@@ -286,11 +257,12 @@
     uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length )
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
-    aead_operation_t operation = AEAD_OPERATION_INIT;
+    mbedtls_psa_aead_operation_t operation = MBEDTLS_PSA_AEAD_OPERATION_INIT;
     const uint8_t *tag = NULL;
-    (void) key_buffer_size;
 
-    status = psa_aead_setup( &operation, attributes, key_buffer, alg );
+    status = psa_aead_setup( &operation, attributes, key_buffer,
+                             key_buffer_size, alg );
+
     if( status != PSA_SUCCESS )
         goto exit;
 
@@ -301,7 +273,7 @@
         goto exit;
 
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
-    if( operation.core_alg == PSA_ALG_CCM )
+    if( operation.alg == PSA_ALG_CCM )
     {
         status = mbedtls_to_psa_error(
             mbedtls_ccm_auth_decrypt( &operation.ctx.ccm,
@@ -315,7 +287,7 @@
     else
 #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
-    if( operation.core_alg == PSA_ALG_GCM )
+    if( operation.alg == PSA_ALG_GCM )
     {
         status = mbedtls_to_psa_error(
             mbedtls_gcm_auth_decrypt( &operation.ctx.gcm,
@@ -329,9 +301,9 @@
     else
 #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
-    if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 )
+    if( operation.alg == PSA_ALG_CHACHA20_POLY1305 )
     {
-        if( nonce_length != 12 || operation.tag_length != 16 )
+        if( operation.tag_length != 16 )
         {
             status = PSA_ERROR_NOT_SUPPORTED;
             goto exit;
@@ -356,12 +328,320 @@
         *plaintext_length = ciphertext_length - operation.tag_length;
 
 exit:
-    psa_aead_abort_internal( &operation );
+    mbedtls_psa_aead_abort( &operation );
 
     if( status == PSA_SUCCESS )
         *plaintext_length = ciphertext_length - operation.tag_length;
     return( status );
 }
 
+/* Set the key and algorithm for a multipart authenticated encryption
+ * operation. */
+psa_status_t mbedtls_psa_aead_encrypt_setup(
+    mbedtls_psa_aead_operation_t *operation,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
+    if( operation->alg == PSA_ALG_CCM )
+    {
+        return( PSA_ERROR_NOT_SUPPORTED );
+    }
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
+
+    status = psa_aead_setup( operation, attributes, key_buffer,
+                             key_buffer_size, alg );
+
+    if( status == PSA_SUCCESS )
+        operation->is_encrypt = 1;
+
+    return ( status );
+}
+
+/* Set the key and algorithm for a multipart authenticated decryption
+ * operation. */
+psa_status_t mbedtls_psa_aead_decrypt_setup(
+    mbedtls_psa_aead_operation_t *operation,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
+    if( operation->alg == PSA_ALG_CCM )
+    {
+        return( PSA_ERROR_NOT_SUPPORTED );
+    }
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
+
+    status = psa_aead_setup( operation, attributes, key_buffer,
+                             key_buffer_size, alg );
+
+    if( status == PSA_SUCCESS )
+        operation->is_encrypt = 0;
+
+    return ( status );
+}
+
+/* Set a nonce for the multipart AEAD operation*/
+psa_status_t mbedtls_psa_aead_set_nonce(
+    mbedtls_psa_aead_operation_t *operation,
+    const uint8_t *nonce,
+    size_t nonce_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
+    if( operation->alg == PSA_ALG_GCM )
+    {
+        status = mbedtls_to_psa_error(
+                 mbedtls_gcm_starts( &operation->ctx.gcm,
+                                     operation->is_encrypt ?
+                                     MBEDTLS_GCM_ENCRYPT : MBEDTLS_GCM_DECRYPT,
+                                     nonce,
+                                     nonce_length ) );
+    }
+    else
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
+    if( operation->alg == PSA_ALG_CHACHA20_POLY1305 )
+    {
+        /* Note - ChaChaPoly allows an 8 byte nonce, but we would have to
+         * allocate a buffer in the operation, copy the nonce to it and pad
+         * it, so for now check the nonce is 12 bytes, as
+         * mbedtls_chachapoly_starts() assumes it can read 12 bytes from the
+         * passed in buffer. */
+        if( nonce_length != 12 )
+        {
+            return( PSA_ERROR_INVALID_ARGUMENT );
+        }
+
+        status = mbedtls_to_psa_error(
+           mbedtls_chachapoly_starts( &operation->ctx.chachapoly,
+                                      nonce,
+                                      operation->is_encrypt ?
+                                      MBEDTLS_CHACHAPOLY_ENCRYPT :
+                                      MBEDTLS_CHACHAPOLY_DECRYPT ) );
+    }
+    else
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
+    {
+        ( void ) nonce;
+
+        return ( PSA_ERROR_NOT_SUPPORTED );
+    }
+
+    return( status );
+}
+
+ /* Declare the lengths of the message and additional data for AEAD. */
+psa_status_t mbedtls_psa_aead_set_lengths(
+    mbedtls_psa_aead_operation_t *operation,
+    size_t ad_length,
+    size_t plaintext_length )
+{
+    /* Nothing here yet, work is currently done in PSA Core, however support
+     * for CCM will require this function. */
+    ( void ) operation;
+    ( void ) ad_length;
+    ( void ) plaintext_length;
+
+    return ( PSA_SUCCESS );
+}
+
+/* Pass additional data to an active multipart AEAD operation. */
+psa_status_t mbedtls_psa_aead_update_ad(
+    mbedtls_psa_aead_operation_t *operation,
+    const uint8_t *input,
+    size_t input_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
+    if( operation->alg == PSA_ALG_GCM )
+    {
+        status = mbedtls_to_psa_error(
+            mbedtls_gcm_update_ad( &operation->ctx.gcm, input, input_length ) );
+    }
+    else
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
+    if( operation->alg == PSA_ALG_CHACHA20_POLY1305 )
+    {
+        status = mbedtls_to_psa_error(
+           mbedtls_chachapoly_update_aad( &operation->ctx.chachapoly,
+                                          input,
+                                          input_length ) );
+    }
+    else
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
+    {
+        ( void ) operation;
+        ( void ) input;
+        ( void ) input_length;
+
+        return ( PSA_ERROR_NOT_SUPPORTED );
+    }
+
+    return ( status );
+}
+
+/* Encrypt or decrypt a message fragment in an active multipart AEAD
+ * operation.*/
+psa_status_t mbedtls_psa_aead_update(
+    mbedtls_psa_aead_operation_t *operation,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length )
+{
+    size_t update_output_length;
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+    update_output_length = input_length;
+
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
+    if( operation->alg == PSA_ALG_GCM )
+    {
+        if( output_size < input_length )
+            return( PSA_ERROR_BUFFER_TOO_SMALL );
+
+        status =  mbedtls_to_psa_error(
+            mbedtls_gcm_update( &operation->ctx.gcm,
+                                input, input_length,
+                                output, output_size,
+                                &update_output_length ) );
+    }
+    else
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
+    if( operation->alg == PSA_ALG_CHACHA20_POLY1305 )
+    {
+        if( output_size < input_length )
+            return( PSA_ERROR_BUFFER_TOO_SMALL );
+
+        status = mbedtls_to_psa_error(
+           mbedtls_chachapoly_update( &operation->ctx.chachapoly,
+                                      input_length,
+                                      input,
+                                      output ) );
+    }
+    else
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
+    {
+        ( void ) input;
+        ( void ) input_length;
+
+        return ( PSA_ERROR_NOT_SUPPORTED );
+    }
+
+    if( status == PSA_SUCCESS )
+        *output_length = update_output_length;
+
+    return( status );
+}
+
+/* Finish encrypting a message in a multipart AEAD operation. */
+psa_status_t mbedtls_psa_aead_finish(
+    mbedtls_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 = PSA_ERROR_CORRUPTION_DETECTED;
+    size_t finish_output_size = 0;
+
+    if( tag_size < operation->tag_length )
+        return( PSA_ERROR_BUFFER_TOO_SMALL );
+
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
+    if( operation->alg == PSA_ALG_GCM )
+    {
+        if( ciphertext_size < 15 )
+            return( PSA_ERROR_BUFFER_TOO_SMALL );
+
+        status =  mbedtls_to_psa_error(
+            mbedtls_gcm_finish( &operation->ctx.gcm,
+                                ciphertext, ciphertext_size, ciphertext_length,
+                                tag, operation->tag_length ) );
+    }
+    else
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
+    if( operation->alg == PSA_ALG_CHACHA20_POLY1305 )
+    {
+        /* Belt and braces. Although the above tag_size check should have
+         * already done this, if we later start supporting smaller tag sizes
+         * for chachapoly, then passing a tag buffer smaller than 16 into here
+         * could cause a buffer overflow, so better safe than sorry. */
+        if( tag_size < 16 )
+            return( PSA_ERROR_BUFFER_TOO_SMALL );
+
+        status = mbedtls_to_psa_error(
+            mbedtls_chachapoly_finish( &operation->ctx.chachapoly,
+                                       tag ) );
+    }
+    else
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
+    {
+        ( void ) ciphertext;
+        ( void ) ciphertext_size;
+        ( void ) ciphertext_length;
+        ( void ) tag;
+        ( void ) tag_size;
+        ( void ) tag_length;
+
+        return ( PSA_ERROR_NOT_SUPPORTED );
+    }
+
+    if( status == PSA_SUCCESS )
+    {
+        /* This will be zero for all supported algorithms currently, but left
+         * here for future support. */
+        *ciphertext_length = finish_output_size;
+        *tag_length = operation->tag_length;
+    }
+
+    return ( status );
+}
+
+/* Abort an AEAD operation */
+psa_status_t mbedtls_psa_aead_abort(
+   mbedtls_psa_aead_operation_t *operation )
+{
+    switch( operation->alg )
+    {
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
+        case PSA_ALG_CCM:
+            mbedtls_ccm_free( &operation->ctx.ccm );
+            break;
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
+        case PSA_ALG_GCM:
+            mbedtls_gcm_free( &operation->ctx.gcm );
+            break;
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
+        case PSA_ALG_CHACHA20_POLY1305:
+            mbedtls_chachapoly_free( &operation->ctx.chachapoly );
+            break;
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
+    }
+
+    operation->is_encrypt = 0;
+
+    return( PSA_SUCCESS );
+}
+
 #endif /* MBEDTLS_PSA_CRYPTO_C */
 
diff --git a/library/psa_crypto_aead.h b/library/psa_crypto_aead.h
index aab0f83..e82e1cc 100644
--- a/library/psa_crypto_aead.h
+++ b/library/psa_crypto_aead.h
@@ -148,4 +148,364 @@
     const uint8_t *ciphertext, size_t ciphertext_length,
     uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length );
 
+/** Set the key for a multipart authenticated encryption operation.
+ *
+ *  \note The signature of this function is that of a PSA driver
+ *       aead_encrypt_setup entry point. This function behaves as an
+ *       aead_encrypt_setup entry point as defined in the PSA driver interface
+ *       specification for transparent drivers.
+ *
+ * If an error occurs at any step after a call to
+ * mbedtls_psa_aead_encrypt_setup(), the operation is reset by the PSA core by a
+ * call to mbedtls_psa_aead_abort(). The PSA core may call
+ * mbedtls_psa_aead_abort() at any time after the operation has been
+ * initialized, and is required to when the operation is no longer needed.
+ *
+ * \param[in,out] operation     The operation object to set up. It must have
+ *                              been initialized as per the documentation for
+ *                              #mbedtls_psa_aead_operation_t and not yet in
+ *                              use.
+ * \param[in]  attributes       The attributes of the key to use for the
+ *                              operation.
+ * \param[in]  key_buffer       The buffer containing the key context.
+ * \param      key_buffer_size  Size of the \p key_buffer buffer in bytes.
+                                It must be consistent with the size in bits
+                                recorded in \p attributes.
+ * \param alg                   The AEAD algorithm to compute
+ *                              (\c PSA_ALG_XXX value such that
+ *                              #PSA_ALG_IS_AEAD(\p alg) is true).
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         An invalid block length was supplied.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         \p alg is not supported.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ *         Failed to allocate memory for key material
+ */
+psa_status_t mbedtls_psa_aead_encrypt_setup(
+    mbedtls_psa_aead_operation_t *operation,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg );
+
+/** Set the key for a multipart authenticated decryption operation.
+ *
+ * \note The signature of this function is that of a PSA driver
+ *       aead_decrypt_setup entry point. This function behaves as an
+ *       aead_decrypt_setup entry point as defined in the PSA driver interface
+ *       specification for transparent drivers.
+ *
+ * If an error occurs at any step after a call to
+ * mbedtls_psa_aead_decrypt_setup(), the PSA core resets the operation by a
+ * call to mbedtls_psa_aead_abort(). The PSA core may call
+ * mbedtls_psa_aead_abort() at any time after the operation has been
+ * initialized, and is required to when the operation is no longer needed.
+ *
+ * \param[in,out] operation     The operation object to set up. It must have
+ *                              been initialized as per the documentation for
+ *                              #mbedtls_psa_aead_operation_t and not yet in
+ *                              use.
+ * \param[in]  attributes       The attributes of the key to use for the
+ *                              operation.
+ * \param[in]  key_buffer       The buffer containing the key context.
+ * \param      key_buffer_size  Size of the \p key_buffer buffer in bytes.
+                                It must be consistent with the size in bits
+                                recorded in \p attributes.
+ * \param alg                   The AEAD algorithm to compute
+ *                              (\c PSA_ALG_XXX value such that
+ *                              #PSA_ALG_IS_AEAD(\p alg) is true).
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         An invalid block length was supplied.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         \p alg is not supported.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ *         Failed to allocate memory for key material
+ */
+psa_status_t mbedtls_psa_aead_decrypt_setup(
+    mbedtls_psa_aead_operation_t *operation,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg );
+
+/** Set the nonce for an authenticated encryption or decryption operation.
+ *
+ * \note The signature of this function is that of a PSA driver aead_set_nonce
+ *       entry point. This function behaves as an aead_set_nonce entry point as
+ *       defined in the PSA driver interface specification for transparent
+ *       drivers.
+ *
+ * This function sets the nonce for the authenticated
+ * encryption or decryption operation.
+ *
+ * The PSA core calls mbedtls_psa_aead_encrypt_setup() or
+ * mbedtls_psa_aead_decrypt_setup() before calling this function.
+ *
+ * If this function returns an error status, the PSA core will call
+ * mbedtls_psa_aead_abort().
+ *
+ * \param[in,out] operation     Active AEAD operation.
+ * \param[in] nonce             Buffer containing the nonce to use.
+ * \param nonce_length          Size of the nonce in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         The size of \p nonce is not acceptable for the chosen algorithm.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         Algorithm previously set is not supported in this configuration of
+ *         the library.
+ */
+psa_status_t mbedtls_psa_aead_set_nonce(
+    mbedtls_psa_aead_operation_t *operation,
+    const uint8_t *nonce,
+    size_t nonce_length );
+
+/** Declare the lengths of the message and additional data for AEAD.
+ *
+ * \note The signature of this function is that of a PSA driver aead_set_lengths
+ *       entry point. This function behaves as an aead_set_lengths entry point
+ *       as defined in the PSA driver interface specification for transparent
+ *       drivers.
+ *
+ * The PSA core calls this function before calling mbedtls_psa_aead_update_ad()
+ * or mbedtls_psa_aead_update() if the algorithm for the operation requires it.
+ * If the algorithm does not require it, calling this function is optional, but
+ * if this function is called then the implementation must enforce the lengths.
+ *
+ * The PSA core may call this function before or after setting the nonce with
+ * mbedtls_psa_aead_set_nonce().
+ *
+ * - For #PSA_ALG_CCM, calling this function is required.
+ * - For the other AEAD algorithms defined in this specification, calling
+ *   this function is not required.
+ *
+ * If this function returns an error status, the PSA core calls
+ * mbedtls_psa_aead_abort().
+ *
+ * \param[in,out] operation     Active AEAD operation.
+ * \param ad_length             Size of the non-encrypted additional
+ *                              authenticated data in bytes.
+ * \param plaintext_length      Size of the plaintext to encrypt in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         At least one of the lengths is not acceptable for the chosen
+ *         algorithm.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         Algorithm previously set is not supported in this configuration of
+ *         the library.
+ */
+psa_status_t mbedtls_psa_aead_set_lengths(
+    mbedtls_psa_aead_operation_t *operation,
+    size_t ad_length,
+    size_t plaintext_length );
+
+/** Pass additional data to an active AEAD operation.
+ *
+ *  \note The signature of this function is that of a PSA driver
+ *       aead_update_ad entry point. This function behaves as an aead_update_ad
+ *       entry point as defined in the PSA driver interface specification for
+ *       transparent drivers.
+ *
+ * Additional data is authenticated, but not encrypted.
+ *
+ * The PSA core can call this function multiple times to pass successive
+ * fragments of the additional data. It will not call this function after
+ * passing data to encrypt or decrypt with mbedtls_psa_aead_update().
+ *
+ * Before calling this function, the PSA core will:
+ *    1. Call either mbedtls_psa_aead_encrypt_setup() or
+ *       mbedtls_psa_aead_decrypt_setup().
+ *    2. Set the nonce with mbedtls_psa_aead_set_nonce().
+ *
+ * If this function returns an error status, the PSA core will call
+ * mbedtls_psa_aead_abort().
+ *
+ * \param[in,out] operation     Active AEAD operation.
+ * \param[in] input             Buffer containing the fragment of
+ *                              additional data.
+ * \param input_length          Size of the \p input buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         Algorithm previously set is not supported in this configuration of
+ *         the library.
+ */
+psa_status_t mbedtls_psa_aead_update_ad(
+    mbedtls_psa_aead_operation_t *operation,
+    const uint8_t *input,
+    size_t input_length );
+
+/** Encrypt or decrypt a message fragment in an active AEAD operation.
+ *
+ *  \note The signature of this function is that of a PSA driver
+ *       aead_update entry point. This function behaves as an aead_update entry
+ *       point as defined in the PSA driver interface specification for
+ *       transparent drivers.
+ *
+ * Before calling this function, the PSA core will:
+ *    1. Call either mbedtls_psa_aead_encrypt_setup() or
+ *       mbedtls_psa_aead_decrypt_setup(). The choice of setup function
+ *       determines whether this function encrypts or decrypts its input.
+ *    2. Set the nonce with mbedtls_psa_aead_set_nonce().
+ *    3. Call mbedtls_psa_aead_update_ad() to pass all the additional data.
+ *
+ * If this function returns an error status, the PSA core will call
+ * mbedtls_psa_aead_abort().
+ *
+ * This function does not require the input to be aligned to any
+ * particular block boundary. If the implementation can only process
+ * a whole block at a time, it must consume all the input provided, but
+ * it may delay the end of the corresponding output until a subsequent
+ * call to mbedtls_psa_aead_update(), mbedtls_psa_aead_finish() provides
+ * sufficient input. The amount of data that can be delayed in this way is
+ * bounded by #PSA_AEAD_UPDATE_OUTPUT_SIZE.
+ *
+ * \param[in,out] operation     Active AEAD operation.
+ * \param[in] input             Buffer containing the message fragment to
+ *                              encrypt or decrypt.
+ * \param input_length          Size of the \p input buffer in bytes.
+ * \param[out] output           Buffer where the output is to be written.
+ * \param output_size           Size of the \p output buffer in bytes.
+ *                              This must be appropriate for the selected
+ *                                algorithm and key:
+ *                                - A sufficient output size is
+ *                                  #PSA_AEAD_UPDATE_OUTPUT_SIZE(\c key_type,
+ *                                  \c alg, \p input_length) where
+ *                                  \c key_type is the type of key and \c alg is
+ *                                  the algorithm that were used to set up the
+ *                                  operation.
+ *                                - #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p
+ *                                  input_length) evaluates to the maximum
+ *                                  output size of any supported AEAD
+ *                                  algorithm.
+ * \param[out] output_length    On success, the number of bytes
+ *                              that make up the returned output.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ *
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ *         The size of the \p output buffer is too small.
+ *         #PSA_AEAD_UPDATE_OUTPUT_SIZE(\c key_type, \c alg, \p input_length) or
+ *         #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p input_length) can be used to
+ *         determine the required buffer size.
+ */
+psa_status_t mbedtls_psa_aead_update(
+    mbedtls_psa_aead_operation_t *operation,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length );
+
+/** Finish encrypting a message in an AEAD operation.
+ *
+ *  \note The signature of this function is that of a PSA driver
+ *       aead_finish entry point. This function behaves as an aead_finish entry
+ *       point as defined in the PSA driver interface specification for
+ *       transparent drivers.
+ *
+ * The operation must have been set up by the PSA core with
+ * mbedtls_psa_aead_encrypt_setup().
+ *
+ * This function finishes the authentication of the additional data
+ * formed by concatenating the inputs passed to preceding calls to
+ * mbedtls_psa_aead_update_ad() with the plaintext formed by concatenating the
+ * inputs passed to preceding calls to mbedtls_psa_aead_update().
+ *
+ * This function has two output buffers:
+ * - \p ciphertext contains trailing ciphertext that was buffered from
+ *   preceding calls to mbedtls_psa_aead_update().
+ * - \p tag contains the authentication tag.
+ *
+ * Whether or not this function returns successfuly, the PSA core subsequently
+ * calls mbedtls_psa_aead_abort() to deactivate the operation.
+ *
+ * \param[in,out] operation     Active AEAD operation.
+ * \param[out] ciphertext       Buffer where the last part of the ciphertext
+ *                              is to be written.
+ * \param ciphertext_size       Size of the \p ciphertext buffer in bytes.
+ *                              This must be appropriate for the selected
+ *                              algorithm and key:
+ *                              - A sufficient output size is
+ *                                #PSA_AEAD_FINISH_OUTPUT_SIZE(\c key_type,
+ *                                \c alg) where \c key_type is the type of key
+ *                                and \c alg is the algorithm that were used to
+ *                                set up the operation.
+ *                              - #PSA_AEAD_FINISH_OUTPUT_MAX_SIZE evaluates to
+ *                                the maximum output size of any supported AEAD
+ *                                algorithm.
+ * \param[out] ciphertext_length On success, the number of bytes of
+ *                              returned ciphertext.
+ * \param[out] tag              Buffer where the authentication tag is
+ *                              to be written.
+ * \param tag_size              Size of the \p tag buffer in bytes.
+ *                              This must be appropriate for the selected
+ *                              algorithm and key:
+ *                              - The exact tag size is #PSA_AEAD_TAG_LENGTH(\c
+ *                                key_type, \c key_bits, \c alg) where
+ *                                \c key_type and \c key_bits are the type and
+ *                                bit-size of the key, and \c alg are the
+ *                                algorithm that were used in the call to
+ *                                mbedtls_psa_aead_encrypt_setup().
+ *                              - #PSA_AEAD_TAG_MAX_SIZE evaluates to the
+ *                                maximum tag size of any supported AEAD
+ *                                algorithm.
+ * \param[out] tag_length       On success, the number of bytes
+ *                              that make up the returned tag.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ *         The size of the \p tag buffer is too small.
+ *         #PSA_AEAD_TAG_LENGTH(\c key_type, key_bits, \c alg) or
+ *         #PSA_AEAD_TAG_MAX_SIZE can be used to determine the required \p tag
+ *         buffer size.
+ */
+psa_status_t mbedtls_psa_aead_finish(
+    mbedtls_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 );
+
+/** Abort an AEAD operation.
+ *
+ *  \note The signature of this function is that of a PSA driver
+ *       aead_abort entry point. This function behaves as an aead_abort entry
+ *       point as defined in the PSA driver interface specification for
+ *       transparent drivers.
+ *
+ * Aborting an operation frees all associated resources except for the
+ * \p operation structure itself. Once aborted, the operation object
+ * can be reused for another operation by the PSA core by it calling
+ * mbedtls_psa_aead_encrypt_setup() or mbedtls_psa_aead_decrypt_setup() again.
+ *
+ * The PSA core may call this function any time after the operation object has
+ * been initialized as described in #mbedtls_psa_aead_operation_t.
+ *
+ * In particular, calling mbedtls_psa_aead_abort() after the operation has been
+ * terminated by a call to mbedtls_psa_aead_abort() or
+ * mbedtls_psa_aead_finish() is safe and has no effect.
+ *
+ * \param[in,out] operation     Initialized AEAD operation.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ */
+psa_status_t mbedtls_psa_aead_abort(
+    mbedtls_psa_aead_operation_t *operation );
+
 #endif /* PSA_CRYPTO_AEAD */
diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c
index 4123d8a..cfc77fb 100644
--- a/library/psa_crypto_driver_wrappers.c
+++ b/library/psa_crypto_driver_wrappers.c
@@ -1565,6 +1565,381 @@
     }
 }
 
+psa_status_t psa_driver_wrapper_aead_encrypt_setup(
+   psa_aead_operation_t *operation,
+   const psa_key_attributes_t *attributes,
+   const uint8_t *key_buffer, size_t key_buffer_size,
+   psa_algorithm_t alg )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_location_t location =
+        PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+
+    switch( location )
+    {
+        case PSA_KEY_LOCATION_LOCAL_STORAGE:
+            /* Key is stored in the slot in export representation, so
+             * cycle through all known transparent accelerators */
+
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+            operation->id = PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID;
+            status = mbedtls_test_transparent_aead_encrypt_setup(
+                        &operation->ctx.transparent_test_driver_ctx,
+                        attributes, key_buffer, key_buffer_size,
+                        alg );
+
+            /* Declared with fallback == true */
+            if( status != PSA_ERROR_NOT_SUPPORTED )
+                return( status );
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+
+            /* Fell through, meaning no accelerator supports this operation */
+            operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID;
+            status = mbedtls_psa_aead_encrypt_setup(
+                        &operation->ctx.mbedtls_ctx, attributes,
+                        key_buffer, key_buffer_size,
+                        alg );
+
+            return( status );
+
+        /* Add cases for opaque driver here */
+
+        default:
+            /* Key is declared with a lifetime not known to us */
+            (void)status;
+            return( PSA_ERROR_INVALID_ARGUMENT );
+    }
+}
+
+psa_status_t psa_driver_wrapper_aead_decrypt_setup(
+   psa_aead_operation_t *operation,
+   const psa_key_attributes_t *attributes,
+   const uint8_t *key_buffer, size_t key_buffer_size,
+   psa_algorithm_t alg )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_location_t location =
+        PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+
+    switch( location )
+    {
+        case PSA_KEY_LOCATION_LOCAL_STORAGE:
+            /* Key is stored in the slot in export representation, so
+             * cycle through all known transparent accelerators */
+
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+            operation->id = PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID;
+            status = mbedtls_test_transparent_aead_decrypt_setup(
+                        &operation->ctx.transparent_test_driver_ctx,
+                        attributes,
+                        key_buffer, key_buffer_size,
+                        alg );
+
+            /* Declared with fallback == true */
+            if( status != PSA_ERROR_NOT_SUPPORTED )
+                return( status );
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+
+            /* Fell through, meaning no accelerator supports this operation */
+            operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID;
+            status = mbedtls_psa_aead_decrypt_setup(
+                        &operation->ctx.mbedtls_ctx,
+                        attributes,
+                        key_buffer, key_buffer_size,
+                        alg );
+
+            return( status );
+
+        /* Add cases for opaque driver here */
+
+        default:
+            /* Key is declared with a lifetime not known to us */
+            (void)status;
+            return( PSA_ERROR_INVALID_ARGUMENT );
+    }
+}
+
+psa_status_t psa_driver_wrapper_aead_set_nonce(
+   psa_aead_operation_t *operation,
+   const uint8_t *nonce,
+   size_t nonce_length )
+{
+    switch( operation->id )
+    {
+#if defined(MBEDTLS_PSA_BUILTIN_AEAD)
+        case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
+            return( mbedtls_psa_aead_set_nonce( &operation->ctx.mbedtls_ctx,
+                                                nonce,
+                                                nonce_length ) );
+
+#endif /* MBEDTLS_PSA_BUILTIN_AEAD */
+
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+            return( mbedtls_test_transparent_aead_set_nonce(
+                         &operation->ctx.transparent_test_driver_ctx,
+                         nonce, nonce_length ) );
+
+        /* Add cases for opaque driver here */
+
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+    }
+
+    (void)nonce;
+    (void)nonce_length;
+
+    return( PSA_ERROR_INVALID_ARGUMENT );
+}
+
+psa_status_t psa_driver_wrapper_aead_set_lengths(
+   psa_aead_operation_t *operation,
+   size_t ad_length,
+   size_t plaintext_length )
+{
+    switch( operation->id )
+    {
+#if defined(MBEDTLS_PSA_BUILTIN_AEAD)
+        case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
+            return( mbedtls_psa_aead_set_lengths( &operation->ctx.mbedtls_ctx,
+                                                  ad_length,
+                                                  plaintext_length ) );
+
+#endif /* MBEDTLS_PSA_BUILTIN_AEAD */
+
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+            return( mbedtls_test_transparent_aead_set_lengths(
+                        &operation->ctx.transparent_test_driver_ctx,
+                        ad_length, plaintext_length ) );
+
+        /* Add cases for opaque driver here */
+
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+    }
+
+    (void)ad_length;
+    (void)plaintext_length;
+
+    return( PSA_ERROR_INVALID_ARGUMENT );
+}
+
+psa_status_t psa_driver_wrapper_aead_update_ad(
+   psa_aead_operation_t *operation,
+   const uint8_t *input,
+   size_t input_length )
+{
+    switch( operation->id )
+    {
+#if defined(MBEDTLS_PSA_BUILTIN_AEAD)
+        case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
+            return( mbedtls_psa_aead_update_ad( &operation->ctx.mbedtls_ctx,
+                                                input,
+                                                input_length ) );
+
+#endif /* MBEDTLS_PSA_BUILTIN_AEAD */
+
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+            return( mbedtls_test_transparent_aead_update_ad(
+                        &operation->ctx.transparent_test_driver_ctx,
+                        input, input_length ) );
+
+        /* Add cases for opaque driver here */
+
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+    }
+
+    (void)input;
+    (void)input_length;
+
+    return( PSA_ERROR_INVALID_ARGUMENT );
+}
+
+psa_status_t psa_driver_wrapper_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 )
+{
+    switch( operation->id )
+    {
+#if defined(MBEDTLS_PSA_BUILTIN_AEAD)
+        case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
+            return( mbedtls_psa_aead_update( &operation->ctx.mbedtls_ctx,
+                                             input, input_length,
+                                             output, output_size,
+                                             output_length ) );
+
+#endif /* MBEDTLS_PSA_BUILTIN_AEAD */
+
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+            return( mbedtls_test_transparent_aead_update(
+                        &operation->ctx.transparent_test_driver_ctx,
+                        input, input_length, output, output_size,
+                        output_length ) );
+
+        /* Add cases for opaque driver here */
+
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+    }
+
+    (void)input;
+    (void)input_length;
+    (void)output;
+    (void)output_size;
+    (void)output_length;
+
+    return( PSA_ERROR_INVALID_ARGUMENT );
+}
+
+psa_status_t psa_driver_wrapper_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 )
+{
+    switch( operation->id )
+    {
+#if defined(MBEDTLS_PSA_BUILTIN_AEAD)
+        case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
+            return( mbedtls_psa_aead_finish( &operation->ctx.mbedtls_ctx,
+                                             ciphertext,
+                                             ciphertext_size,
+                                             ciphertext_length, tag,
+                                             tag_size, tag_length ) );
+
+#endif /* MBEDTLS_PSA_BUILTIN_AEAD */
+
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+            return( mbedtls_test_transparent_aead_finish(
+                        &operation->ctx.transparent_test_driver_ctx,
+                        ciphertext, ciphertext_size,
+                        ciphertext_length, tag, tag_size, tag_length ) );
+
+        /* Add cases for opaque driver here */
+
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+    }
+
+    (void)ciphertext;
+    (void)ciphertext_size;
+    (void)ciphertext_length;
+    (void)tag;
+    (void)tag_size;
+    (void)tag_length;
+
+    return( PSA_ERROR_INVALID_ARGUMENT );
+}
+
+psa_status_t psa_driver_wrapper_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 )
+{
+    switch( operation->id )
+    {
+#if defined(MBEDTLS_PSA_BUILTIN_AEAD)
+        case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
+            {
+                psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+                uint8_t check_tag[PSA_AEAD_TAG_MAX_SIZE];
+                size_t check_tag_length;
+
+                status = mbedtls_psa_aead_finish( &operation->ctx.mbedtls_ctx,
+                                                  plaintext,
+                                                  plaintext_size,
+                                                  plaintext_length,
+                                                  check_tag,
+                                                  sizeof( check_tag ),
+                                                  &check_tag_length );
+
+                if( status == PSA_SUCCESS )
+                {
+                    if( tag_length != check_tag_length ||
+                        mbedtls_psa_safer_memcmp( tag, check_tag, tag_length )
+                        != 0 )
+                        status = PSA_ERROR_INVALID_SIGNATURE;
+                }
+
+                mbedtls_platform_zeroize( check_tag, sizeof( check_tag ) );
+
+                return( status );
+            }
+
+#endif /* MBEDTLS_PSA_BUILTIN_AEAD */
+
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+            return( mbedtls_test_transparent_aead_verify(
+                        &operation->ctx.transparent_test_driver_ctx,
+                        plaintext, plaintext_size,
+                        plaintext_length, tag, tag_length ) );
+
+        /* Add cases for opaque driver here */
+
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+    }
+
+    (void)plaintext;
+    (void)plaintext_size;
+    (void)plaintext_length;
+    (void)tag;
+    (void)tag_length;
+
+    return( PSA_ERROR_INVALID_ARGUMENT );
+}
+
+psa_status_t psa_driver_wrapper_aead_abort(
+   psa_aead_operation_t *operation )
+{
+    switch( operation->id )
+    {
+#if defined(MBEDTLS_PSA_BUILTIN_AEAD)
+        case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
+            return( mbedtls_psa_aead_abort( &operation->ctx.mbedtls_ctx ) );
+
+#endif /* MBEDTLS_PSA_BUILTIN_AEAD */
+
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+            return( mbedtls_test_transparent_aead_abort(
+               &operation->ctx.transparent_test_driver_ctx ) );
+
+        /* Add cases for opaque driver here */
+
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+    }
+
+    return( PSA_ERROR_INVALID_ARGUMENT );
+}
 
 /*
  * MAC functions
diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h
index c6e3d51..0873b73 100644
--- a/library/psa_crypto_driver_wrappers.h
+++ b/library/psa_crypto_driver_wrappers.h
@@ -219,6 +219,61 @@
     const uint8_t *ciphertext, size_t ciphertext_length,
     uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length );
 
+psa_status_t psa_driver_wrapper_aead_encrypt_setup(
+    psa_aead_operation_t *operation,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer, size_t key_buffer_size,
+    psa_algorithm_t alg );
+
+psa_status_t psa_driver_wrapper_aead_decrypt_setup(
+    psa_aead_operation_t *operation,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer, size_t key_buffer_size,
+    psa_algorithm_t alg );
+
+psa_status_t psa_driver_wrapper_aead_set_nonce(
+    psa_aead_operation_t *operation,
+    const uint8_t *nonce,
+    size_t nonce_length );
+
+psa_status_t psa_driver_wrapper_aead_set_lengths(
+    psa_aead_operation_t *operation,
+    size_t ad_length,
+    size_t plaintext_length );
+
+psa_status_t psa_driver_wrapper_aead_update_ad(
+    psa_aead_operation_t *operation,
+    const uint8_t *input,
+    size_t input_length );
+
+psa_status_t psa_driver_wrapper_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 psa_driver_wrapper_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 psa_driver_wrapper_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 psa_driver_wrapper_aead_abort(
+    psa_aead_operation_t *operation );
+
 /*
  * MAC functions
  */
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 76962d3..7c44382 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -1361,6 +1361,22 @@
 
 int mbedtls_ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial );
 
+/*
+ * Send pending alert
+ */
+int mbedtls_ssl_handle_pending_alert( mbedtls_ssl_context *ssl );
+
+/*
+ * Set pending fatal alert flag.
+ */
+void mbedtls_ssl_pend_fatal_alert( mbedtls_ssl_context *ssl,
+                                   unsigned char alert_type,
+                                   int alert_reason );
+
+/* Alias of mbedtls_ssl_pend_fatal_alert */
+#define MBEDTLS_SSL_PEND_FATAL_ALERT( type, user_return_value )         \
+            mbedtls_ssl_pend_fatal_alert( ssl, type, user_return_value )
+
 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
 void mbedtls_ssl_dtls_replay_reset( mbedtls_ssl_context *ssl );
 #endif
@@ -1493,6 +1509,14 @@
 }
 
 /*
+ * Fetch TLS 1.3 handshake message header
+ */
+int mbedtls_ssl_tls1_3_fetch_handshake_msg( mbedtls_ssl_context *ssl,
+                                            unsigned hs_type,
+                                            unsigned char **buf,
+                                            size_t *buf_len );
+
+/*
  * Write TLS 1.3 handshake message header
  */
 int mbedtls_ssl_tls13_start_handshake_msg( mbedtls_ssl_context *ssl,
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index fdb647a..3795c65 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -5660,4 +5660,48 @@
     }
 }
 
+/*
+ * Send pending fatal alert.
+ * 0,   No alert message.
+ * !0,  if mbedtls_ssl_send_alert_message() returned in error, the error code it
+ *      returned, ssl->alert_reason otherwise.
+ */
+int mbedtls_ssl_handle_pending_alert( mbedtls_ssl_context *ssl )
+{
+    int ret;
+
+    /* No pending alert, return success*/
+    if( ssl->send_alert == 0 )
+        return( 0 );
+
+    ret = mbedtls_ssl_send_alert_message( ssl,
+                                MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                ssl->alert_type );
+
+    /* If mbedtls_ssl_send_alert_message() returned with MBEDTLS_ERR_SSL_WANT_WRITE,
+     * do not clear the alert to be able to send it later.
+     */
+    if( ret != MBEDTLS_ERR_SSL_WANT_WRITE )
+    {
+        ssl->send_alert = 0;
+    }
+
+    if( ret != 0 )
+        return( ret );
+
+    return( ssl->alert_reason );
+}
+
+/*
+ * Set pending fatal alert flag.
+ */
+void mbedtls_ssl_pend_fatal_alert( mbedtls_ssl_context *ssl,
+                                   unsigned char alert_type,
+                                   int alert_reason )
+{
+    ssl->send_alert = 1;
+    ssl->alert_type = alert_type;
+    ssl->alert_reason = alert_reason;
+}
+
 #endif /* MBEDTLS_SSL_TLS_C */
diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c
index bce9a1c..e998111 100644
--- a/library/ssl_ticket.c
+++ b/library/ssl_ticket.c
@@ -138,16 +138,14 @@
     ctx->ticket_lifetime = lifetime;
 
     cipher_info = mbedtls_cipher_info_from_type( cipher);
-    if( cipher_info == NULL )
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
-    if( cipher_info->mode != MBEDTLS_MODE_GCM &&
-        cipher_info->mode != MBEDTLS_MODE_CCM )
+    if( mbedtls_cipher_info_get_mode( cipher_info ) != MBEDTLS_MODE_GCM &&
+        mbedtls_cipher_info_get_mode( cipher_info ) != MBEDTLS_MODE_CCM )
     {
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
-    if( cipher_info->key_bitlen > 8 * MAX_KEY_BYTES )
+    if( mbedtls_cipher_info_get_key_bitlen( cipher_info ) > 8 * MAX_KEY_BYTES )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index bf3ab09..4d305ee 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -689,7 +689,7 @@
     unsigned char *mac_dec;
     size_t mac_key_len = 0;
     size_t iv_copy_len;
-    unsigned keylen;
+    size_t keylen;
     const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
     const mbedtls_cipher_info_t *cipher_info;
     const mbedtls_md_info_t *md_info;
@@ -789,14 +789,14 @@
      * Determine the appropriate key, IV and MAC length.
      */
 
-    keylen = cipher_info->key_bitlen / 8;
+    keylen = mbedtls_cipher_info_get_key_bitlen( cipher_info ) / 8;
 
 #if defined(MBEDTLS_GCM_C) ||                           \
     defined(MBEDTLS_CCM_C) ||                           \
     defined(MBEDTLS_CHACHAPOLY_C)
-    if( cipher_info->mode == MBEDTLS_MODE_GCM ||
-        cipher_info->mode == MBEDTLS_MODE_CCM ||
-        cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY )
+    if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_GCM ||
+        mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CCM ||
+        mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CHACHAPOLY )
     {
         size_t explicit_ivlen;
 
@@ -814,7 +814,7 @@
          *   sequence number).
          */
         transform->ivlen = 12;
-        if( cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY )
+        if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CHACHAPOLY )
             transform->fixed_ivlen = 12;
         else
             transform->fixed_ivlen = 4;
@@ -826,8 +826,8 @@
     else
 #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */
 #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
-    if( cipher_info->mode == MBEDTLS_MODE_STREAM ||
-        cipher_info->mode == MBEDTLS_MODE_CBC )
+    if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_STREAM ||
+        mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CBC )
     {
         /* Initialize HMAC contexts */
         if( ( ret = mbedtls_md_setup( &transform->md_ctx_enc, md_info, 1 ) ) != 0 ||
@@ -845,7 +845,7 @@
         transform->ivlen = cipher_info->iv_size;
 
         /* Minimum length */
-        if( cipher_info->mode == MBEDTLS_MODE_STREAM )
+        if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_STREAM )
             transform->minlen = transform->maclen;
         else
         {
@@ -1060,7 +1060,7 @@
     }
 
     if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_enc, key1,
-                               cipher_info->key_bitlen,
+                               (int) mbedtls_cipher_info_get_key_bitlen( cipher_info ),
                                MBEDTLS_ENCRYPT ) ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
@@ -1068,7 +1068,7 @@
     }
 
     if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_dec, key2,
-                               cipher_info->key_bitlen,
+                               (int) mbedtls_cipher_info_get_key_bitlen( cipher_info ),
                                MBEDTLS_DECRYPT ) ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
@@ -1076,7 +1076,7 @@
     }
 
 #if defined(MBEDTLS_CIPHER_MODE_CBC)
-    if( cipher_info->mode == MBEDTLS_MODE_CBC )
+    if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CBC )
     {
         if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_enc,
                                              MBEDTLS_PADDING_NONE ) ) != 0 )
@@ -5172,6 +5172,10 @@
     if( ret != 0 )
         return( ret );
 
+    ret = mbedtls_ssl_handle_pending_alert( ssl );
+    if( ret != 0 )
+        goto cleanup;
+
 #if defined(MBEDTLS_SSL_CLI_C)
     if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
     {
@@ -5201,6 +5205,19 @@
     }
 #endif
 
+    if( ret != 0 )
+    {
+        /* handshake_step return error. And it is same
+         * with alert_reason.
+         */
+        if( ssl->send_alert )
+        {
+            ret = mbedtls_ssl_handle_pending_alert( ssl );
+            goto cleanup;
+        }
+    }
+
+cleanup:
     return( ret );
 }
 
diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c
index 13e932c..633bb8d 100644
--- a/library/ssl_tls13_client.c
+++ b/library/ssl_tls13_client.c
@@ -701,6 +701,7 @@
 
 /*
  * Write ClientHello handshake message.
+ * Handler for MBEDTLS_SSL_CLIENT_HELLO
  */
 static int ssl_tls13_write_client_hello( mbedtls_ssl_context *ssl )
 {
@@ -736,11 +737,121 @@
     return ret;
 }
 
+/*
+ * Handler for MBEDTLS_SSL_SERVER_HELLO
+ */
+static int ssl_tls1_3_process_server_hello( mbedtls_ssl_context *ssl )
+{
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS );
+    return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_ENCRYPTED_EXTENSIONS
+ */
+static int ssl_tls1_3_process_encrypted_extensions( mbedtls_ssl_context *ssl )
+{
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CERTIFICATE_REQUEST );
+    return( 0 );
+}
+
+/*
+ * Handler for  MBEDTLS_SSL_CERTIFICATE_REQUEST
+ */
+static int ssl_tls1_3_process_certificate_request( mbedtls_ssl_context *ssl )
+{
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_CERTIFICATE );
+    return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_SERVER_CERTIFICATE
+ */
+static int ssl_tls1_3_process_server_certificate( mbedtls_ssl_context *ssl )
+{
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CERTIFICATE_VERIFY );
+    return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_CERTIFICATE_VERIFY
+ */
+static int ssl_tls1_3_process_certificate_verify( mbedtls_ssl_context *ssl )
+{
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_FINISHED );
+    return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_SERVER_FINISHED
+ */
+static int ssl_tls1_3_process_server_finished( mbedtls_ssl_context *ssl )
+{
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE );
+    return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_CLIENT_CERTIFICATE
+ */
+static int ssl_tls1_3_write_client_certificate( mbedtls_ssl_context *ssl )
+{
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY );
+    return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY
+ */
+static int ssl_tls1_3_write_client_certificate_verify( mbedtls_ssl_context *ssl )
+{
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_FINISHED );
+    return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_CLIENT_FINISHED
+ */
+static int ssl_tls1_3_write_client_finished( mbedtls_ssl_context *ssl )
+{
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_FLUSH_BUFFERS );
+    return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_FLUSH_BUFFERS
+ */
+static int ssl_tls1_3_flush_buffers( mbedtls_ssl_context *ssl )
+{
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP );
+    return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_HANDSHAKE_WRAPUP
+ */
+static int ssl_tls1_3_handshake_wrapup( mbedtls_ssl_context *ssl )
+{
+    ((void) ssl);
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+    return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+}
+
 int mbedtls_ssl_tls13_handshake_client_step( mbedtls_ssl_context *ssl )
 {
     int ret = 0;
 
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "tls1_3 client state: %d", ssl->state ) );
 
     switch( ssl->state )
     {
@@ -754,9 +865,47 @@
             break;
 
         case MBEDTLS_SSL_SERVER_HELLO:
-            // Stop here : we haven't finished whole flow
-            ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
-            mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS );
+            ret = ssl_tls1_3_process_server_hello( ssl );
+            break;
+
+        case MBEDTLS_SSL_ENCRYPTED_EXTENSIONS:
+            ret = ssl_tls1_3_process_encrypted_extensions( ssl );
+            break;
+
+        case MBEDTLS_SSL_CERTIFICATE_REQUEST:
+            ret = ssl_tls1_3_process_certificate_request( ssl );
+            break;
+
+        case MBEDTLS_SSL_SERVER_CERTIFICATE:
+            ret = ssl_tls1_3_process_server_certificate( ssl );
+            break;
+
+        case MBEDTLS_SSL_CERTIFICATE_VERIFY:
+            ret = ssl_tls1_3_process_certificate_verify( ssl );
+            break;
+
+        case MBEDTLS_SSL_SERVER_FINISHED:
+            ret = ssl_tls1_3_process_server_finished( ssl );
+            break;
+
+        case MBEDTLS_SSL_CLIENT_CERTIFICATE:
+            ret = ssl_tls1_3_write_client_certificate( ssl );
+            break;
+
+        case MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY:
+            ret = ssl_tls1_3_write_client_certificate_verify( ssl );
+            break;
+
+        case MBEDTLS_SSL_CLIENT_FINISHED:
+            ret = ssl_tls1_3_write_client_finished( ssl );
+            break;
+
+        case MBEDTLS_SSL_FLUSH_BUFFERS:
+            ret = ssl_tls1_3_flush_buffers( ssl );
+            break;
+
+        case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
+            ret = ssl_tls1_3_handshake_wrapup( ssl );
             break;
 
         default:
diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c
index c8f6dc7..b3a4a09 100644
--- a/library/ssl_tls13_generic.c
+++ b/library/ssl_tls13_generic.c
@@ -28,6 +28,44 @@
 
 #include "ssl_misc.h"
 
+int mbedtls_ssl_tls1_3_fetch_handshake_msg( mbedtls_ssl_context *ssl,
+                                            unsigned hs_type,
+                                            unsigned char **buf,
+                                            size_t *buflen )
+{
+    int ret;
+
+    if( ( ret = mbedtls_ssl_read_record( ssl, 0 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+        goto cleanup;
+    }
+
+    if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ||
+        ssl->in_msg[0]  != hs_type )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Receive unexpected handshake message." ) );
+        MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
+                                      MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+        ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
+        goto cleanup;
+    }
+
+    /*
+     * Jump handshake header (4 bytes, see Section 4 of RFC 8446).
+     *    ...
+     *    HandshakeType msg_type;
+     *    uint24 length;
+     *    ...
+     */
+    *buf    = ssl->in_msg   + 4;
+    *buflen = ssl->in_hslen - 4;
+
+cleanup:
+
+    return( ret );
+}
+
 int mbedtls_ssl_tls13_start_handshake_msg( mbedtls_ssl_context *ssl,
                                            unsigned hs_type,
                                            unsigned char **buf,
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index 0dcd7ed..86f44cb 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -23,11 +23,15 @@
 
 #if defined(MBEDTLS_SSL_SRV_C)
 
+#include "mbedtls/debug.h"
+
 #include "ssl_misc.h"
 
 int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl )
 {
     ((void) ssl);
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "tls1_3 server state: %d", ssl->state ) );
+
     return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
 }
 
diff --git a/programs/aes/crypt_and_hash.c b/programs/aes/crypt_and_hash.c
index a8026a3..5ed2ece 100644
--- a/programs/aes/crypt_and_hash.c
+++ b/programs/aes/crypt_and_hash.c
@@ -124,7 +124,7 @@
         while( *list )
         {
             cipher_info = mbedtls_cipher_info_from_type( *list );
-            mbedtls_printf( "  %s\n", cipher_info->MBEDTLS_PRIVATE(name) );
+            mbedtls_printf( "  %s\n", mbedtls_cipher_info_get_name( cipher_info ) );
             list++;
         }
 
@@ -309,7 +309,9 @@
 
         }
 
-        if( mbedtls_cipher_setkey( &cipher_ctx, digest, cipher_info->MBEDTLS_PRIVATE(key_bitlen),
+        if( mbedtls_cipher_setkey( &cipher_ctx,
+                                   digest,
+                                   (int) mbedtls_cipher_info_get_key_bitlen( cipher_info ),
                            MBEDTLS_ENCRYPT ) != 0 )
         {
             mbedtls_fprintf( stderr, "mbedtls_cipher_setkey() returned error\n");
@@ -408,7 +410,7 @@
         /*
          * Check the file size.
          */
-        if( cipher_info->MBEDTLS_PRIVATE(mode) != MBEDTLS_MODE_GCM &&
+        if( mbedtls_cipher_info_get_mode( cipher_info ) != MBEDTLS_MODE_GCM &&
             ( ( filesize - mbedtls_md_get_size( md_info ) ) %
                 mbedtls_cipher_get_block_size( &cipher_ctx ) ) != 0 )
         {
@@ -448,7 +450,9 @@
             mbedtls_md_finish( &md_ctx, digest );
         }
 
-        if( mbedtls_cipher_setkey( &cipher_ctx, digest, cipher_info->MBEDTLS_PRIVATE(key_bitlen),
+        if( mbedtls_cipher_setkey( &cipher_ctx,
+                                   digest,
+                                   (int) mbedtls_cipher_info_get_key_bitlen( cipher_info ),
                            MBEDTLS_DECRYPT ) != 0 )
         {
             mbedtls_fprintf( stderr, "mbedtls_cipher_setkey() returned error\n" );
diff --git a/programs/pkey/ecdsa.c b/programs/pkey/ecdsa.c
index 6b6e951..550a230 100644
--- a/programs/pkey/ecdsa.c
+++ b/programs/pkey/ecdsa.c
@@ -51,7 +51,7 @@
 #define ECPARAMS    MBEDTLS_ECP_DP_SECP192R1
 
 #if !defined(ECPARAMS)
-#define ECPARAMS    mbedtls_ecp_curve_list()->MBEDTLS_PRIVATE(grp_id)
+#define ECPARAMS    mbedtls_ecp_curve_list()->grp_id
 #endif
 
 #if !defined(MBEDTLS_ECDSA_C) || !defined(MBEDTLS_SHA256_C) || \
diff --git a/programs/pkey/gen_key.c b/programs/pkey/gen_key.c
index 4043dfa..7535eee 100644
--- a/programs/pkey/gen_key.c
+++ b/programs/pkey/gen_key.c
@@ -86,7 +86,7 @@
 #endif
 
 #if defined(MBEDTLS_ECP_C)
-#define DFL_EC_CURVE            mbedtls_ecp_curve_list()->MBEDTLS_PRIVATE(grp_id)
+#define DFL_EC_CURVE            mbedtls_ecp_curve_list()->grp_id
 #else
 #define DFL_EC_CURVE            0
 #endif
@@ -219,9 +219,9 @@
 #if defined(MBEDTLS_ECP_C)
         mbedtls_printf( " available ec_curve values:\n" );
         curve_info = mbedtls_ecp_curve_list();
-        mbedtls_printf( "    %s (default)\n", curve_info->MBEDTLS_PRIVATE(name) );
-        while( ( ++curve_info )->MBEDTLS_PRIVATE(name) != NULL )
-            mbedtls_printf( "    %s\n", curve_info->MBEDTLS_PRIVATE(name) );
+        mbedtls_printf( "    %s (default)\n", curve_info->name );
+        while( ( ++curve_info )->name != NULL )
+            mbedtls_printf( "    %s\n", curve_info->name );
 #endif /* MBEDTLS_ECP_C */
         goto exit;
     }
@@ -270,7 +270,7 @@
         {
             if( ( curve_info = mbedtls_ecp_curve_info_from_name( q ) ) == NULL )
                 goto usage;
-            opt.ec_curve = curve_info->MBEDTLS_PRIVATE(grp_id);
+            opt.ec_curve = curve_info->grp_id;
         }
 #endif
         else if( strcmp( p, "filename" ) == 0 )
@@ -391,7 +391,7 @@
     {
         mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( key );
         mbedtls_printf( "curve: %s\n",
-                mbedtls_ecp_curve_info_from_grp_id( ecp->MBEDTLS_PRIVATE(grp).id )->MBEDTLS_PRIVATE(name) );
+                mbedtls_ecp_curve_info_from_grp_id( ecp->MBEDTLS_PRIVATE(grp).id )->name );
         mbedtls_mpi_write_file( "X_Q:   ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), 16, NULL );
         mbedtls_mpi_write_file( "Y_Q:   ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), 16, NULL );
         mbedtls_mpi_write_file( "D:     ", &ecp->MBEDTLS_PRIVATE(d)  , 16, NULL );
diff --git a/programs/ssl/dtls_server.c b/programs/ssl/dtls_server.c
index f257049..5d1cccb 100644
--- a/programs/ssl/dtls_server.c
+++ b/programs/ssl/dtls_server.c
@@ -226,7 +226,7 @@
                                    mbedtls_ssl_cache_set );
 #endif
 
-    mbedtls_ssl_conf_ca_chain( &conf, srvcert.MBEDTLS_PRIVATE(next), NULL );
+    mbedtls_ssl_conf_ca_chain( &conf, srvcert.next, NULL );
    if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 )
     {
         printf( " failed\n  ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
diff --git a/programs/ssl/mini_client.c b/programs/ssl/mini_client.c
index 1e0bef6..97bfe68 100644
--- a/programs/ssl/mini_client.c
+++ b/programs/ssl/mini_client.c
@@ -246,13 +246,13 @@
     addr.sin_addr.s_addr = *((char *) &ret) == ret ? ADDR_LE : ADDR_BE;
     ret = 0;
 
-    if( ( server_fd.MBEDTLS_PRIVATE(fd) = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
+    if( ( server_fd.fd = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
     {
         ret = socket_failed;
         goto exit;
     }
 
-    if( connect( server_fd.MBEDTLS_PRIVATE(fd),
+    if( connect( server_fd.fd,
                 (const struct sockaddr *) &addr, sizeof( addr ) ) < 0 )
     {
         ret = connect_failed;
diff --git a/programs/ssl/ssl_fork_server.c b/programs/ssl/ssl_fork_server.c
index 542a334..694fc3b 100644
--- a/programs/ssl/ssl_fork_server.c
+++ b/programs/ssl/ssl_fork_server.c
@@ -190,7 +190,7 @@
     mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
     mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
 
-    mbedtls_ssl_conf_ca_chain( &conf, srvcert.MBEDTLS_PRIVATE(next), NULL );
+    mbedtls_ssl_conf_ca_chain( &conf, srvcert.next, NULL );
     if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 )
     {
         mbedtls_printf( " failed!  mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c
index ace657c..95557fb 100644
--- a/programs/ssl/ssl_server.c
+++ b/programs/ssl/ssl_server.c
@@ -212,7 +212,7 @@
                                    mbedtls_ssl_cache_set );
 #endif
 
-    mbedtls_ssl_conf_ca_chain( &conf, srvcert.MBEDTLS_PRIVATE(next), NULL );
+    mbedtls_ssl_conf_ca_chain( &conf, srvcert.next, NULL );
     if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
diff --git a/programs/x509/cert_app.c b/programs/x509/cert_app.c
index aab15db..3d8f37b 100644
--- a/programs/x509/cert_app.c
+++ b/programs/x509/cert_app.c
@@ -331,7 +331,7 @@
 
             mbedtls_printf( "%s\n", buf );
 
-            cur = cur->MBEDTLS_PRIVATE(next);
+            cur = cur->next;
         }
 
         /*
diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c
index 9a20d63..763f868 100644
--- a/programs/x509/cert_write.c
+++ b/programs/x509/cert_write.c
@@ -514,7 +514,7 @@
         }
 
         ret = mbedtls_x509_dn_gets( issuer_name, sizeof(issuer_name),
-                                 &issuer_crt.MBEDTLS_PRIVATE(subject) );
+                                 &issuer_crt.subject );
         if( ret < 0 )
         {
             mbedtls_strerror( ret, buf, 1024 );
@@ -548,7 +548,7 @@
         }
 
         ret = mbedtls_x509_dn_gets( subject_name, sizeof(subject_name),
-                                 &csr.MBEDTLS_PRIVATE(subject) );
+                                 &csr.subject );
         if( ret < 0 )
         {
             mbedtls_strerror( ret, buf, 1024 );
@@ -558,7 +558,7 @@
         }
 
         opt.subject_name = subject_name;
-        subject_key = &csr.MBEDTLS_PRIVATE(pk);
+        subject_key = &csr.pk;
 
         mbedtls_printf( " ok\n" );
     }
@@ -602,7 +602,7 @@
     //
     if( strlen( opt.issuer_crt ) )
     {
-        if( mbedtls_pk_check_pair( &issuer_crt.MBEDTLS_PRIVATE(pk), issuer_key,
+        if( mbedtls_pk_check_pair( &issuer_crt.pk, issuer_key,
                                    mbedtls_ctr_drbg_random, &ctr_drbg ) != 0 )
         {
             mbedtls_printf( " failed\n  !  issuer_key does not match "
diff --git a/tests/Makefile b/tests/Makefile
index 449fca2..db642c7 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -5,6 +5,9 @@
 WARNING_CFLAGS ?= -Wall -Wextra -Wformat=2 -Wno-format-nonliteral
 LDFLAGS ?=
 
+# Set this to -v to see the details of failing test cases
+TEST_FLAGS ?= $(if $(filter-out 0 OFF Off off NO No no FALSE False false N n,$(CTEST_OUTPUT_ON_FAILURE)),-v,)
+
 default: all
 
 # Include public header files from ../include, test-specific header files
@@ -195,7 +198,7 @@
 
 # Test suites caught by SKIP_TEST_SUITES are built but not executed.
 check: $(BINARIES)
-	perl scripts/run-test-suites.pl --skip=$(SKIP_TEST_SUITES)
+	perl scripts/run-test-suites.pl $(TEST_FLAGS) --skip=$(SKIP_TEST_SUITES)
 
 test: check
 
diff --git a/tests/configs/user-config-for-test.h b/tests/configs/user-config-for-test.h
new file mode 100644
index 0000000..444a4bf
--- /dev/null
+++ b/tests/configs/user-config-for-test.h
@@ -0,0 +1,57 @@
+/* MBEDTLS_USER_CONFIG_FILE for testing.
+ * Only used for a few test configurations.
+ *
+ * Typical usage (note multiple levels of quoting):
+ *     make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/user-config-for-test.h\"'"
+ */
+
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#if defined(PSA_CRYPTO_DRIVER_TEST_ALL)
+
+/* Enable the use of the test driver in the library, and build the generic
+ * part of the test driver. */
+#define PSA_CRYPTO_DRIVER_TEST
+
+/* Use the accelerator driver for all cryptographic mechanisms for which
+ * the test driver implemented. */
+#define MBEDTLS_PSA_ACCEL_KEY_TYPE_AES
+#define MBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA
+#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR
+#define MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR
+#define MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING
+#define MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7
+#define MBEDTLS_PSA_ACCEL_ALG_CTR
+#define MBEDTLS_PSA_ACCEL_ALG_CFB
+#define MBEDTLS_PSA_ACCEL_ALG_ECDSA
+#define MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA
+#define MBEDTLS_PSA_ACCEL_ALG_MD5
+#define MBEDTLS_PSA_ACCEL_ALG_OFB
+#define MBEDTLS_PSA_ACCEL_ALG_RIPEMD160
+#define MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN
+#define MBEDTLS_PSA_ACCEL_ALG_RSA_PSS
+#define MBEDTLS_PSA_ACCEL_ALG_SHA_1
+#define MBEDTLS_PSA_ACCEL_ALG_SHA_224
+#define MBEDTLS_PSA_ACCEL_ALG_SHA_256
+#define MBEDTLS_PSA_ACCEL_ALG_SHA_384
+#define MBEDTLS_PSA_ACCEL_ALG_SHA_512
+#define MBEDTLS_PSA_ACCEL_ALG_XTS
+#define MBEDTLS_PSA_ACCEL_ALG_CMAC
+#define MBEDTLS_PSA_ACCEL_ALG_HMAC
+
+#endif  /* PSA_CRYPTO_DRIVER_TEST_ALL */
diff --git a/tests/include/test/drivers/aead.h b/tests/include/test/drivers/aead.h
index 0830229..2421560 100644
--- a/tests/include/test/drivers/aead.h
+++ b/tests/include/test/drivers/aead.h
@@ -30,12 +30,23 @@
      * function call. */
     psa_status_t forced_status;
     /* Count the amount of times AEAD driver functions are called. */
-    unsigned long hits;
+    unsigned long hits_encrypt;
+    unsigned long hits_decrypt;
+    unsigned long hits_encrypt_setup;
+    unsigned long hits_decrypt_setup;
+    unsigned long hits_set_nonce;
+    unsigned long hits_set_lengths;
+    unsigned long hits_update_ad;
+    unsigned long hits_update;
+    unsigned long hits_finish;
+    unsigned long hits_verify;
+    unsigned long hits_abort;
+
     /* Status returned by the last AEAD driver function call. */
     psa_status_t driver_status;
 } mbedtls_test_driver_aead_hooks_t;
 
-#define MBEDTLS_TEST_DRIVER_AEAD_INIT { 0, 0, 0 }
+#define MBEDTLS_TEST_DRIVER_AEAD_INIT { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
 static inline mbedtls_test_driver_aead_hooks_t
     mbedtls_test_driver_aead_hooks_init( void )
 {
@@ -63,5 +74,60 @@
     const uint8_t *ciphertext, size_t ciphertext_length,
     uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length );
 
+psa_status_t mbedtls_test_transparent_aead_encrypt_setup(
+    mbedtls_psa_aead_operation_t *operation,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer, size_t key_buffer_size,
+    psa_algorithm_t alg );
+
+psa_status_t mbedtls_test_transparent_aead_decrypt_setup(
+    mbedtls_psa_aead_operation_t *operation,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer, size_t key_buffer_size,
+    psa_algorithm_t alg );
+
+psa_status_t mbedtls_test_transparent_aead_set_nonce(
+    mbedtls_psa_aead_operation_t *operation,
+    const uint8_t *nonce,
+    size_t nonce_length );
+
+psa_status_t mbedtls_test_transparent_aead_set_lengths(
+    mbedtls_psa_aead_operation_t *operation,
+    size_t ad_length,
+    size_t plaintext_length );
+
+psa_status_t mbedtls_test_transparent_aead_update_ad(
+    mbedtls_psa_aead_operation_t *operation,
+    const uint8_t *input,
+    size_t input_length );
+
+psa_status_t mbedtls_test_transparent_aead_update(
+   mbedtls_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 mbedtls_test_transparent_aead_finish(
+   mbedtls_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 mbedtls_test_transparent_aead_verify(
+   mbedtls_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 mbedtls_test_transparent_aead_abort(
+   mbedtls_psa_aead_operation_t *operation );
+
 #endif /* PSA_CRYPTO_DRIVER_TEST */
 #endif /* PSA_CRYPTO_TEST_DRIVERS_AEAD_H */
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index c050f61..1bcc2e4 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -175,10 +175,10 @@
 
     # if MAKEFLAGS is not set add the -j option to speed up invocations of make
     if [ -z "${MAKEFLAGS+set}" ]; then
-        export MAKEFLAGS="-j"
+        export MAKEFLAGS="-j$(all_sh_nproc)"
     fi
 
-    # Include more verbose output for failing tests run by CMake
+    # Include more verbose output for failing tests run by CMake or make
     export CTEST_OUTPUT_ON_FAILURE=1
 
     # CFLAGS and LDFLAGS for Asan builds that don't use CMake
@@ -343,6 +343,18 @@
 trap 'fatal_signal INT' INT
 trap 'fatal_signal TERM' TERM
 
+# Number of processors on this machine. Used as the default setting
+# for parallel make.
+all_sh_nproc ()
+{
+    {
+        nproc || # Linux
+        sysctl -n hw.ncpuonline || # NetBSD, OpenBSD
+        sysctl -n hw.ncpu || # FreeBSD
+        echo 1
+    } 2>/dev/null
+}
+
 msg()
 {
     if [ -n "${current_component:-}" ]; then
@@ -841,7 +853,7 @@
 
 component_check_names () {
     msg "Check: declared and exported names (builds the library)" # < 3s
-    tests/scripts/check-names.sh -v
+    tests/scripts/check_names.py -v
 }
 
 component_check_test_cases () {
@@ -1560,31 +1572,8 @@
     scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_KEY_TYPE_DES
     scripts/config.py unset MBEDTLS_DES_C
 
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    loc_cflags="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_AES"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CTR"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CFB"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_ECDSA"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD5"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_OFB"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RIPEMD160"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PSS"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_1"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_224"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_256"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_384"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_512"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_XTS"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CMAC"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_HMAC"
+    loc_cflags="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST_ALL"
+    loc_cflags="${loc_cflags} '-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/user-config-for-test.h\"'"
     loc_cflags="${loc_cflags} -I../tests/include -O2"
 
     make CC=gcc CFLAGS="$loc_cflags" LDFLAGS="$ASAN_CFLAGS"
@@ -2237,31 +2226,8 @@
     scripts/config.py full
     scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
     scripts/config.py set MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    loc_cflags="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_AES"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CTR"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CFB"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_ECDSA"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD5"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_OFB"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RIPEMD160"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PSS"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_1"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_224"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_256"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_384"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_512"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_XTS"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CMAC"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_HMAC"
+    loc_cflags="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST_ALL"
+    loc_cflags="${loc_cflags} '-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/user-config-for-test.h\"'"
     loc_cflags="${loc_cflags} -I../tests/include -O2"
 
     make CC=gcc CFLAGS="${loc_cflags}" LDFLAGS="$ASAN_CFLAGS"
diff --git a/tests/scripts/check-names.sh b/tests/scripts/check-names.sh
deleted file mode 100755
index 2a06adc..0000000
--- a/tests/scripts/check-names.sh
+++ /dev/null
@@ -1,129 +0,0 @@
-#!/bin/sh
-#
-# Copyright The Mbed TLS Contributors
-# SPDX-License-Identifier: Apache-2.0
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -eu
-
-if [ $# -ne 0 ] && [ "$1" = "--help" ]; then
-    cat <<EOF
-$0 [-v]
-This script confirms that the naming of all symbols and identifiers in mbed
-TLS are consistent with the house style and are also self-consistent.
-
-  -v    If the script fails unexpectedly, print a command trace.
-EOF
-    exit
-fi
-
-trace=
-if [ $# -ne 0 ] && [ "$1" = "-v" ]; then
-  shift
-  trace='-x'
-  exec 2>check-names.err
-  trap 'echo "FAILED UNEXPECTEDLY, status=$?";
-        cat check-names.err' EXIT
-  set -x
-fi
-
-printf "Analysing source code...\n"
-
-sh $trace tests/scripts/list-macros.sh
-tests/scripts/list-enum-consts.pl
-sh $trace tests/scripts/list-identifiers.sh
-sh $trace tests/scripts/list-symbols.sh
-
-FAIL=0
-
-printf "\nExported symbols declared in header: "
-UNDECLARED=$( diff exported-symbols identifiers | sed -n -e 's/^< //p' )
-if [ "x$UNDECLARED" = "x" ]; then
-    echo "PASS"
-else
-    echo "FAIL"
-    echo "$UNDECLARED"
-    FAIL=1
-fi
-
-diff macros identifiers | sed -n -e 's/< //p' > actual-macros
-
-for THING in actual-macros enum-consts; do
-    printf 'Names of %s: ' "$THING"
-    test -r $THING
-    BAD=$( grep -E -v '^(MBEDTLS|PSA)_[0-9A-Z_]*[0-9A-Z]$' $THING || true )
-    UNDERSCORES=$( grep -E '.*__.*' $THING || true )
-
-    if [ "x$BAD" = "x" ] && [ "x$UNDERSCORES" = "x" ]; then
-        echo "PASS"
-    else
-        echo "FAIL"
-        echo "$BAD"
-        echo "$UNDERSCORES"
-        FAIL=1
-    fi
-done
-
-for THING in identifiers; do
-    printf 'Names of %s: ' "$THING"
-    test -r $THING
-    BAD=$( grep -E -v '^(mbedtls|psa)_[0-9a-z_]*[0-9a-z]$' $THING || true )
-    if [ "x$BAD" = "x" ]; then
-        echo "PASS"
-    else
-        echo "FAIL"
-        echo "$BAD"
-        FAIL=1
-    fi
-done
-
-printf "Likely typos: "
-sort -u actual-macros enum-consts > _caps
-HEADERS=$( ls include/mbedtls/*.h include/psa/*.h | egrep -v 'compat-2\.x\.h' )
-HEADERS="$HEADERS library/*.h"
-HEADERS="$HEADERS 3rdparty/everest/include/everest/everest.h 3rdparty/everest/include/everest/x25519.h"
-LIBRARY="$( ls library/*.c )"
-LIBRARY="$LIBRARY 3rdparty/everest/library/everest.c 3rdparty/everest/library/x25519.c"
-NL='
-'
-cat $HEADERS $LIBRARY \
-    | grep -v -e '//no-check-names' -e '#error' \
-    | sed -n 's/MBED..._[A-Z0-9_]*/\'"$NL"'&\'"$NL"/gp \
-    | grep MBEDTLS | sort -u > _MBEDTLS_XXX
-TYPOS=$( diff _caps _MBEDTLS_XXX | sed -n 's/^> //p' \
-            | egrep -v 'XXX|__|_$|^MBEDTLS_.*CONFIG_FILE$' || true )
-rm _MBEDTLS_XXX _caps
-if [ "x$TYPOS" = "x" ]; then
-    echo "PASS"
-else
-    echo "FAIL"
-    echo "$TYPOS"
-    FAIL=1
-fi
-
-if [ -n "$trace" ]; then
-  set +x
-  trap - EXIT
-  rm check-names.err
-fi
-
-printf "\nOverall: "
-if [ "$FAIL" -eq 0 ]; then
-    rm macros actual-macros enum-consts identifiers exported-symbols
-    echo "PASSED"
-    exit 0
-else
-    echo "FAILED"
-    exit 1
-fi
diff --git a/tests/scripts/check_names.py b/tests/scripts/check_names.py
new file mode 100755
index 0000000..a9aa118
--- /dev/null
+++ b/tests/scripts/check_names.py
@@ -0,0 +1,865 @@
+#!/usr/bin/env python3
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+This script confirms that the naming of all symbols and identifiers in Mbed TLS
+are consistent with the house style and are also self-consistent. It only runs
+on Linux and macOS since it depends on nm.
+
+It contains two major Python classes, CodeParser and NameChecker. They both have
+a comprehensive "run-all" function (comprehensive_parse() and perform_checks())
+but the individual functions can also be used for specific needs.
+
+CodeParser makes heavy use of regular expressions to parse the code, and is
+dependent on the current code formatting. Many Python C parser libraries require
+preprocessed C code, which means no macro parsing. Compiler tools are also not
+very helpful when we want the exact location in the original source (which
+becomes impossible when e.g. comments are stripped).
+
+NameChecker performs the following checks:
+
+- All exported and available symbols in the library object files, are explicitly
+  declared in the header files. This uses the nm command.
+- All macros, constants, and identifiers (function names, struct names, etc)
+  follow the required regex pattern.
+- Typo checking: All words that begin with MBED exist as macros or constants.
+
+The script returns 0 on success, 1 on test failure, and 2 if there is a script
+error. It must be run from Mbed TLS root.
+"""
+
+import abc
+import argparse
+import glob
+import textwrap
+import os
+import sys
+import traceback
+import re
+import enum
+import shutil
+import subprocess
+import logging
+
+# Naming patterns to check against. These are defined outside the NameCheck
+# class for ease of modification.
+MACRO_PATTERN = r"^(MBEDTLS|PSA)_[0-9A-Z_]*[0-9A-Z]$"
+CONSTANTS_PATTERN = MACRO_PATTERN
+IDENTIFIER_PATTERN = r"^(mbedtls|psa)_[0-9a-z_]*[0-9a-z]$"
+
+class Match(): # pylint: disable=too-few-public-methods
+    """
+    A class representing a match, together with its found position.
+
+    Fields:
+    * filename: the file that the match was in.
+    * line: the full line containing the match.
+    * line_no: the line number.
+    * pos: a tuple of (start, end) positions on the line where the match is.
+    * name: the match itself.
+    """
+    def __init__(self, filename, line, line_no, pos, name):
+        # pylint: disable=too-many-arguments
+        self.filename = filename
+        self.line = line
+        self.line_no = line_no
+        self.pos = pos
+        self.name = name
+
+    def __str__(self):
+        """
+        Return a formatted code listing representation of the erroneous line.
+        """
+        gutter = format(self.line_no, "4d")
+        underline = self.pos[0] * " " + (self.pos[1] - self.pos[0]) * "^"
+
+        return (
+            " {0} |\n".format(" " * len(gutter)) +
+            " {0} | {1}".format(gutter, self.line) +
+            " {0} | {1}\n".format(" " * len(gutter), underline)
+        )
+
+class Problem(abc.ABC): # pylint: disable=too-few-public-methods
+    """
+    An abstract parent class representing a form of static analysis error.
+    It extends an Abstract Base Class, which means it is not instantiable, and
+    it also mandates certain abstract methods to be implemented in subclasses.
+    """
+    # Class variable to control the quietness of all problems
+    quiet = False
+    def __init__(self):
+        self.textwrapper = textwrap.TextWrapper()
+        self.textwrapper.width = 80
+        self.textwrapper.initial_indent = "    > "
+        self.textwrapper.subsequent_indent = "      "
+
+    def __str__(self):
+        """
+        Unified string representation method for all Problems.
+        """
+        if self.__class__.quiet:
+            return self.quiet_output()
+        return self.verbose_output()
+
+    @abc.abstractmethod
+    def quiet_output(self):
+        """
+        The output when --quiet is enabled.
+        """
+        pass
+
+    @abc.abstractmethod
+    def verbose_output(self):
+        """
+        The default output with explanation and code snippet if appropriate.
+        """
+        pass
+
+class SymbolNotInHeader(Problem): # pylint: disable=too-few-public-methods
+    """
+    A problem that occurs when an exported/available symbol in the object file
+    is not explicitly declared in header files. Created with
+    NameCheck.check_symbols_declared_in_header()
+
+    Fields:
+    * symbol_name: the name of the symbol.
+    """
+    def __init__(self, symbol_name):
+        self.symbol_name = symbol_name
+        Problem.__init__(self)
+
+    def quiet_output(self):
+        return "{0}".format(self.symbol_name)
+
+    def verbose_output(self):
+        return self.textwrapper.fill(
+            "'{0}' was found as an available symbol in the output of nm, "
+            "however it was not declared in any header files."
+            .format(self.symbol_name))
+
+class PatternMismatch(Problem): # pylint: disable=too-few-public-methods
+    """
+    A problem that occurs when something doesn't match the expected pattern.
+    Created with NameCheck.check_match_pattern()
+
+    Fields:
+    * pattern: the expected regex pattern
+    * match: the Match object in question
+    """
+    def __init__(self, pattern, match):
+        self.pattern = pattern
+        self.match = match
+        Problem.__init__(self)
+
+
+    def quiet_output(self):
+        return (
+            "{0}:{1}:{2}"
+            .format(self.match.filename, self.match.line_no, self.match.name)
+        )
+
+    def verbose_output(self):
+        return self.textwrapper.fill(
+            "{0}:{1}: '{2}' does not match the required pattern '{3}'."
+            .format(
+                self.match.filename,
+                self.match.line_no,
+                self.match.name,
+                self.pattern
+            )
+        ) + "\n" + str(self.match)
+
+class Typo(Problem): # pylint: disable=too-few-public-methods
+    """
+    A problem that occurs when a word using MBED doesn't appear to be defined as
+    constants nor enum values. Created with NameCheck.check_for_typos()
+
+    Fields:
+    * match: the Match object of the MBED name in question.
+    """
+    def __init__(self, match):
+        self.match = match
+        Problem.__init__(self)
+
+    def quiet_output(self):
+        return (
+            "{0}:{1}:{2}"
+            .format(self.match.filename, self.match.line_no, self.match.name)
+        )
+
+    def verbose_output(self):
+        return self.textwrapper.fill(
+            "{0}:{1}: '{2}' looks like a typo. It was not found in any "
+            "macros or any enums. If this is not a typo, put "
+            "//no-check-names after it."
+            .format(self.match.filename, self.match.line_no, self.match.name)
+        ) + "\n" + str(self.match)
+
+class CodeParser():
+    """
+    Class for retrieving files and parsing the code. This can be used
+    independently of the checks that NameChecker performs, for example for
+    list_internal_identifiers.py.
+    """
+    def __init__(self, log):
+        self.log = log
+        self.check_repo_path()
+
+        # Memo for storing "glob expression": set(filepaths)
+        self.files = {}
+
+        # Globally excluded filenames
+        self.excluded_files = ["**/bn_mul", "**/compat-2.x.h"]
+
+    @staticmethod
+    def check_repo_path():
+        """
+        Check that the current working directory is the project root, and throw
+        an exception if not.
+        """
+        if not all(os.path.isdir(d) for d in ["include", "library", "tests"]):
+            raise Exception("This script must be run from Mbed TLS root")
+
+    def comprehensive_parse(self):
+        """
+        Comprehensive ("default") function to call each parsing function and
+        retrieve various elements of the code, together with the source location.
+
+        Returns a dict of parsed item key to the corresponding List of Matches.
+        """
+        self.log.info("Parsing source code...")
+        self.log.debug(
+            "The following files are excluded from the search: {}"
+            .format(str(self.excluded_files))
+        )
+
+        all_macros = self.parse_macros([
+            "include/mbedtls/*.h",
+            "include/psa/*.h",
+            "library/*.h",
+            "tests/include/test/drivers/*.h",
+            "3rdparty/everest/include/everest/everest.h",
+            "3rdparty/everest/include/everest/x25519.h"
+        ])
+        enum_consts = self.parse_enum_consts([
+            "include/mbedtls/*.h",
+            "library/*.h",
+            "3rdparty/everest/include/everest/everest.h",
+            "3rdparty/everest/include/everest/x25519.h"
+        ])
+        identifiers = self.parse_identifiers([
+            "include/mbedtls/*.h",
+            "include/psa/*.h",
+            "library/*.h",
+            "3rdparty/everest/include/everest/everest.h",
+            "3rdparty/everest/include/everest/x25519.h"
+        ])
+        mbed_words = self.parse_mbed_words([
+            "include/mbedtls/*.h",
+            "include/psa/*.h",
+            "library/*.h",
+            "3rdparty/everest/include/everest/everest.h",
+            "3rdparty/everest/include/everest/x25519.h",
+            "library/*.c",
+            "3rdparty/everest/library/everest.c",
+            "3rdparty/everest/library/x25519.c"
+        ])
+        symbols = self.parse_symbols()
+
+        # Remove identifier macros like mbedtls_printf or mbedtls_calloc
+        identifiers_justname = [x.name for x in identifiers]
+        actual_macros = []
+        for macro in all_macros:
+            if macro.name not in identifiers_justname:
+                actual_macros.append(macro)
+
+        self.log.debug("Found:")
+        # Aligns the counts on the assumption that none exceeds 4 digits
+        self.log.debug("  {:4} Total Macros".format(len(all_macros)))
+        self.log.debug("  {:4} Non-identifier Macros".format(len(actual_macros)))
+        self.log.debug("  {:4} Enum Constants".format(len(enum_consts)))
+        self.log.debug("  {:4} Identifiers".format(len(identifiers)))
+        self.log.debug("  {:4} Exported Symbols".format(len(symbols)))
+        return {
+            "macros": actual_macros,
+            "enum_consts": enum_consts,
+            "identifiers": identifiers,
+            "symbols": symbols,
+            "mbed_words": mbed_words
+        }
+
+    def get_files(self, include_wildcards, exclude_wildcards):
+        """
+        Get all files that match any of the UNIX-style wildcards. While the
+        check_names script is designed only for use on UNIX/macOS (due to nm),
+        this function alone would work fine on Windows even with forward slashes
+        in the wildcard.
+
+        Args:
+        * include_wildcards: a List of shell-style wildcards to match filepaths.
+        * exclude_wildcards: a List of shell-style wildcards to exclude.
+
+        Returns a List of relative filepaths.
+        """
+        accumulator = set()
+
+        # exclude_wildcards may be None. Also, consider the global exclusions.
+        exclude_wildcards = (exclude_wildcards or []) + self.excluded_files
+
+        # Internal function to hit the memoisation cache or add to it the result
+        # of a glob operation. Used both for inclusion and exclusion since the
+        # only difference between them is whether they perform set union or
+        # difference on the return value of this function.
+        def hit_cache(wildcard):
+            if wildcard not in self.files:
+                self.files[wildcard] = set(glob.glob(wildcard, recursive=True))
+            return self.files[wildcard]
+
+        for include_wildcard in include_wildcards:
+            accumulator = accumulator.union(hit_cache(include_wildcard))
+
+        for exclude_wildcard in exclude_wildcards:
+            accumulator = accumulator.difference(hit_cache(exclude_wildcard))
+
+        return list(accumulator)
+
+    def parse_macros(self, include, exclude=None):
+        """
+        Parse all macros defined by #define preprocessor directives.
+
+        Args:
+        * include: A List of glob expressions to look for files through.
+        * exclude: A List of glob expressions for excluding files.
+
+        Returns a List of Match objects for the found macros.
+        """
+        macro_regex = re.compile(r"# *define +(?P<macro>\w+)")
+        exclusions = (
+            "asm", "inline", "EMIT", "_CRT_SECURE_NO_DEPRECATE", "MULADDC_"
+        )
+
+        files = self.get_files(include, exclude)
+        self.log.debug("Looking for macros in {} files".format(len(files)))
+
+        macros = []
+        for header_file in files:
+            with open(header_file, "r", encoding="utf-8") as header:
+                for line_no, line in enumerate(header):
+                    for macro in macro_regex.finditer(line):
+                        if macro.group("macro").startswith(exclusions):
+                            continue
+
+                        macros.append(Match(
+                            header_file,
+                            line,
+                            line_no,
+                            macro.span("macro"),
+                            macro.group("macro")))
+
+        return macros
+
+    def parse_mbed_words(self, include, exclude=None):
+        """
+        Parse all words in the file that begin with MBED, in and out of macros,
+        comments, anything.
+
+        Args:
+        * include: A List of glob expressions to look for files through.
+        * exclude: A List of glob expressions for excluding files.
+
+        Returns a List of Match objects for words beginning with MBED.
+        """
+        # Typos of TLS are common, hence the broader check below than MBEDTLS.
+        mbed_regex = re.compile(r"\bMBED.+?_[A-Z0-9_]*")
+        exclusions = re.compile(r"// *no-check-names|#error")
+
+        files = self.get_files(include, exclude)
+        self.log.debug("Looking for MBED words in {} files".format(len(files)))
+
+        mbed_words = []
+        for filename in files:
+            with open(filename, "r", encoding="utf-8") as fp:
+                for line_no, line in enumerate(fp):
+                    if exclusions.search(line):
+                        continue
+
+                    for name in mbed_regex.finditer(line):
+                        mbed_words.append(Match(
+                            filename,
+                            line,
+                            line_no,
+                            name.span(0),
+                            name.group(0)))
+
+        return mbed_words
+
+    def parse_enum_consts(self, include, exclude=None):
+        """
+        Parse all enum value constants that are declared.
+
+        Args:
+        * include: A List of glob expressions to look for files through.
+        * exclude: A List of glob expressions for excluding files.
+
+        Returns a List of Match objects for the findings.
+        """
+        files = self.get_files(include, exclude)
+        self.log.debug("Looking for enum consts in {} files".format(len(files)))
+
+        # Emulate a finite state machine to parse enum declarations.
+        # OUTSIDE_KEYWORD = outside the enum keyword
+        # IN_BRACES = inside enum opening braces
+        # IN_BETWEEN = between enum keyword and opening braces
+        states = enum.Enum("FSM", ["OUTSIDE_KEYWORD", "IN_BRACES", "IN_BETWEEN"])
+        enum_consts = []
+        for header_file in files:
+            state = states.OUTSIDE_KEYWORD
+            with open(header_file, "r", encoding="utf-8") as header:
+                for line_no, line in enumerate(header):
+                    # Match typedefs and brackets only when they are at the
+                    # beginning of the line -- if they are indented, they might
+                    # be sub-structures within structs, etc.
+                    if (state == states.OUTSIDE_KEYWORD and
+                            re.search(r"^(typedef +)?enum +{", line)):
+                        state = states.IN_BRACES
+                    elif (state == states.OUTSIDE_KEYWORD and
+                          re.search(r"^(typedef +)?enum", line)):
+                        state = states.IN_BETWEEN
+                    elif (state == states.IN_BETWEEN and
+                          re.search(r"^{", line)):
+                        state = states.IN_BRACES
+                    elif (state == states.IN_BRACES and
+                          re.search(r"^}", line)):
+                        state = states.OUTSIDE_KEYWORD
+                    elif (state == states.IN_BRACES and
+                          not re.search(r"^ *#", line)):
+                        enum_const = re.search(r"^ *(?P<enum_const>\w+)", line)
+                        if not enum_const:
+                            continue
+
+                        enum_consts.append(Match(
+                            header_file,
+                            line,
+                            line_no,
+                            enum_const.span("enum_const"),
+                            enum_const.group("enum_const")))
+
+        return enum_consts
+
+    def parse_identifiers(self, include, exclude=None):
+        """
+        Parse all lines of a header where a function/enum/struct/union/typedef
+        identifier is declared, based on some regex and heuristics. Highly
+        dependent on formatting style.
+
+        Args:
+        * include: A List of glob expressions to look for files through.
+        * exclude: A List of glob expressions for excluding files.
+
+        Returns a List of Match objects with identifiers.
+        """
+        identifier_regex = re.compile(
+            # Match " something(a" or " *something(a". Functions.
+            # Assumptions:
+            # - function definition from return type to one of its arguments is
+            #   all on one line
+            # - function definition line only contains alphanumeric, asterisk,
+            #   underscore, and open bracket
+            r".* \**(\w+) *\( *\w|"
+            # Match "(*something)(".
+            r".*\( *\* *(\w+) *\) *\(|"
+            # Match names of named data structures.
+            r"(?:typedef +)?(?:struct|union|enum) +(\w+)(?: *{)?$|"
+            # Match names of typedef instances, after closing bracket.
+            r"}? *(\w+)[;[].*"
+        )
+        # The regex below is indented for clarity.
+        exclusion_lines = re.compile(
+            r"^("
+                r"extern +\"C\"|" # pylint: disable=bad-continuation
+                r"(typedef +)?(struct|union|enum)( *{)?$|"
+                r"} *;?$|"
+                r"$|"
+                r"//|"
+                r"#"
+            r")"
+        )
+
+        files = self.get_files(include, exclude)
+        self.log.debug("Looking for identifiers in {} files".format(len(files)))
+
+        identifiers = []
+        for header_file in files:
+            with open(header_file, "r", encoding="utf-8") as header:
+                in_block_comment = False
+                # The previous line variable is used for concatenating lines
+                # when identifiers are formatted and spread across multiple
+                # lines.
+                previous_line = ""
+
+                for line_no, line in enumerate(header):
+                    # Skip parsing this line if a block comment ends on it,
+                    # but don't skip if it has just started -- there is a chance
+                    # it ends on the same line.
+                    if re.search(r"/\*", line):
+                        in_block_comment = not in_block_comment
+                    if re.search(r"\*/", line):
+                        in_block_comment = not in_block_comment
+                        continue
+
+                    if in_block_comment:
+                        previous_line = ""
+                        continue
+
+                    if exclusion_lines.search(line):
+                        previous_line = ""
+                        continue
+
+                    # If the line contains only space-separated alphanumeric
+                    # characters (or underscore, asterisk, or, open bracket),
+                    # and nothing else, high chance it's a declaration that
+                    # continues on the next line
+                    if re.search(r"^([\w\*\(]+\s+)+$", line):
+                        previous_line += line
+                        continue
+
+                    # If previous line seemed to start an unfinished declaration
+                    # (as above), concat and treat them as one.
+                    if previous_line:
+                        line = previous_line.strip() + " " + line.strip() + "\n"
+                        previous_line = ""
+
+                    # Skip parsing if line has a space in front = heuristic to
+                    # skip function argument lines (highly subject to formatting
+                    # changes)
+                    if line[0] == " ":
+                        continue
+
+                    identifier = identifier_regex.search(line)
+
+                    if not identifier:
+                        continue
+
+                    # Find the group that matched, and append it
+                    for group in identifier.groups():
+                        if not group:
+                            continue
+
+                        identifiers.append(Match(
+                            header_file,
+                            line,
+                            line_no,
+                            identifier.span(),
+                            group))
+
+        return identifiers
+
+    def parse_symbols(self):
+        """
+        Compile the Mbed TLS libraries, and parse the TLS, Crypto, and x509
+        object files using nm to retrieve the list of referenced symbols.
+        Exceptions thrown here are rethrown because they would be critical
+        errors that void several tests, and thus needs to halt the program. This
+        is explicitly done for clarity.
+
+        Returns a List of unique symbols defined and used in the libraries.
+        """
+        self.log.info("Compiling...")
+        symbols = []
+
+        # Back up the config and atomically compile with the full configratuion.
+        shutil.copy(
+            "include/mbedtls/mbedtls_config.h",
+            "include/mbedtls/mbedtls_config.h.bak"
+        )
+        try:
+            # Use check=True in all subprocess calls so that failures are raised
+            # as exceptions and logged.
+            subprocess.run(
+                ["python3", "scripts/config.py", "full"],
+                universal_newlines=True,
+                check=True
+            )
+            my_environment = os.environ.copy()
+            my_environment["CFLAGS"] = "-fno-asynchronous-unwind-tables"
+            # Run make clean separately to lib to prevent unwanted behavior when
+            # make is invoked with parallelism.
+            subprocess.run(
+                ["make", "clean"],
+                universal_newlines=True,
+                check=True
+            )
+            subprocess.run(
+                ["make", "lib"],
+                env=my_environment,
+                universal_newlines=True,
+                stdout=subprocess.PIPE,
+                stderr=subprocess.STDOUT,
+                check=True
+            )
+
+            # Perform object file analysis using nm
+            symbols = self.parse_symbols_from_nm([
+                "library/libmbedcrypto.a",
+                "library/libmbedtls.a",
+                "library/libmbedx509.a"
+            ])
+
+            subprocess.run(
+                ["make", "clean"],
+                universal_newlines=True,
+                check=True
+            )
+        except subprocess.CalledProcessError as error:
+            self.log.debug(error.output)
+            raise error
+        finally:
+            # Put back the original config regardless of there being errors.
+            # Works also for keyboard interrupts.
+            shutil.move(
+                "include/mbedtls/mbedtls_config.h.bak",
+                "include/mbedtls/mbedtls_config.h"
+            )
+
+        return symbols
+
+    def parse_symbols_from_nm(self, object_files):
+        """
+        Run nm to retrieve the list of referenced symbols in each object file.
+        Does not return the position data since it is of no use.
+
+        Args:
+        * object_files: a List of compiled object filepaths to search through.
+
+        Returns a List of unique symbols defined and used in any of the object
+        files.
+        """
+        nm_undefined_regex = re.compile(r"^\S+: +U |^$|^\S+:$")
+        nm_valid_regex = re.compile(r"^\S+( [0-9A-Fa-f]+)* . _*(?P<symbol>\w+)")
+        exclusions = ("FStar", "Hacl")
+
+        symbols = []
+
+        # Gather all outputs of nm
+        nm_output = ""
+        for lib in object_files:
+            nm_output += subprocess.run(
+                ["nm", "-og", lib],
+                universal_newlines=True,
+                stdout=subprocess.PIPE,
+                stderr=subprocess.STDOUT,
+                check=True
+            ).stdout
+
+        for line in nm_output.splitlines():
+            if not nm_undefined_regex.search(line):
+                symbol = nm_valid_regex.search(line)
+                if (symbol and not symbol.group("symbol").startswith(exclusions)):
+                    symbols.append(symbol.group("symbol"))
+                else:
+                    self.log.error(line)
+
+        return symbols
+
+class NameChecker():
+    """
+    Representation of the core name checking operation performed by this script.
+    """
+    def __init__(self, parse_result, log):
+        self.parse_result = parse_result
+        self.log = log
+
+    def perform_checks(self, quiet=False):
+        """
+        A comprehensive checker that performs each check in order, and outputs
+        a final verdict.
+
+        Args:
+        * quiet: whether to hide detailed problem explanation.
+        """
+        self.log.info("=============")
+        Problem.quiet = quiet
+        problems = 0
+        problems += self.check_symbols_declared_in_header()
+
+        pattern_checks = [
+            ("macros", MACRO_PATTERN),
+            ("enum_consts", CONSTANTS_PATTERN),
+            ("identifiers", IDENTIFIER_PATTERN)
+        ]
+        for group, check_pattern in pattern_checks:
+            problems += self.check_match_pattern(group, check_pattern)
+
+        problems += self.check_for_typos()
+
+        self.log.info("=============")
+        if problems > 0:
+            self.log.info("FAIL: {0} problem(s) to fix".format(str(problems)))
+            if quiet:
+                self.log.info("Remove --quiet to see explanations.")
+            else:
+                self.log.info("Use --quiet for minimal output.")
+            return 1
+        else:
+            self.log.info("PASS")
+            return 0
+
+    def check_symbols_declared_in_header(self):
+        """
+        Perform a check that all detected symbols in the library object files
+        are properly declared in headers.
+        Assumes parse_names_in_source() was called before this.
+
+        Returns the number of problems that need fixing.
+        """
+        problems = []
+
+        for symbol in self.parse_result["symbols"]:
+            found_symbol_declared = False
+            for identifier_match in self.parse_result["identifiers"]:
+                if symbol == identifier_match.name:
+                    found_symbol_declared = True
+                    break
+
+            if not found_symbol_declared:
+                problems.append(SymbolNotInHeader(symbol))
+
+        self.output_check_result("All symbols in header", problems)
+        return len(problems)
+
+    def check_match_pattern(self, group_to_check, check_pattern):
+        """
+        Perform a check that all items of a group conform to a regex pattern.
+        Assumes parse_names_in_source() was called before this.
+
+        Args:
+        * group_to_check: string key to index into self.parse_result.
+        * check_pattern: the regex to check against.
+
+        Returns the number of problems that need fixing.
+        """
+        problems = []
+
+        for item_match in self.parse_result[group_to_check]:
+            if not re.search(check_pattern, item_match.name):
+                problems.append(PatternMismatch(check_pattern, item_match))
+            # Double underscore should not be used for names
+            if re.search(r".*__.*", item_match.name):
+                problems.append(
+                    PatternMismatch("no double underscore allowed", item_match))
+
+        self.output_check_result(
+            "Naming patterns of {}".format(group_to_check),
+            problems)
+        return len(problems)
+
+    def check_for_typos(self):
+        """
+        Perform a check that all words in the soure code beginning with MBED are
+        either defined as macros, or as enum constants.
+        Assumes parse_names_in_source() was called before this.
+
+        Returns the number of problems that need fixing.
+        """
+        problems = []
+
+        # Set comprehension, equivalent to a list comprehension wrapped by set()
+        all_caps_names = {
+            match.name
+            for match
+            in self.parse_result["macros"] + self.parse_result["enum_consts"]}
+        typo_exclusion = re.compile(r"XXX|__|_$|^MBEDTLS_.*CONFIG_FILE$")
+
+        for name_match in self.parse_result["mbed_words"]:
+            found = name_match.name in all_caps_names
+
+            # Since MBEDTLS_PSA_ACCEL_XXX defines are defined by the
+            # PSA driver, they will not exist as macros. However, they
+            # should still be checked for typos using the equivalent
+            # BUILTINs that exist.
+            if "MBEDTLS_PSA_ACCEL_" in name_match.name:
+                found = name_match.name.replace(
+                    "MBEDTLS_PSA_ACCEL_",
+                    "MBEDTLS_PSA_BUILTIN_") in all_caps_names
+
+            if not found and not typo_exclusion.search(name_match.name):
+                problems.append(Typo(name_match))
+
+        self.output_check_result("Likely typos", problems)
+        return len(problems)
+
+    def output_check_result(self, name, problems):
+        """
+        Write out the PASS/FAIL status of a performed check depending on whether
+        there were problems.
+
+        Args:
+        * name: the name of the test
+        * problems: a List of encountered Problems
+        """
+        if problems:
+            self.log.info("{}: FAIL\n".format(name))
+            for problem in problems:
+                self.log.warning(str(problem))
+        else:
+            self.log.info("{}: PASS".format(name))
+
+def main():
+    """
+    Perform argument parsing, and create an instance of CodeParser and
+    NameChecker to begin the core operation.
+    """
+    parser = argparse.ArgumentParser(
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        description=(
+            "This script confirms that the naming of all symbols and identifiers "
+            "in Mbed TLS are consistent with the house style and are also "
+            "self-consistent.\n\n"
+            "Expected to be run from the MbedTLS root directory.")
+    )
+    parser.add_argument(
+        "-v", "--verbose",
+        action="store_true",
+        help="show parse results"
+    )
+    parser.add_argument(
+        "-q", "--quiet",
+        action="store_true",
+        help="hide unnecessary text, explanations, and highlighs"
+    )
+
+    args = parser.parse_args()
+
+    # Configure the global logger, which is then passed to the classes below
+    log = logging.getLogger()
+    log.setLevel(logging.DEBUG if args.verbose else logging.INFO)
+    log.addHandler(logging.StreamHandler())
+
+    try:
+        code_parser = CodeParser(log)
+        parse_result = code_parser.comprehensive_parse()
+    except Exception: # pylint: disable=broad-except
+        traceback.print_exc()
+        sys.exit(2)
+
+    name_checker = NameChecker(parse_result, log)
+    return_code = name_checker.perform_checks(quiet=args.quiet)
+
+    sys.exit(return_code)
+
+if __name__ == "__main__":
+    main()
diff --git a/tests/scripts/list-enum-consts.pl b/tests/scripts/list-enum-consts.pl
deleted file mode 100755
index 6d93693..0000000
--- a/tests/scripts/list-enum-consts.pl
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/env perl
-#
-# Copyright The Mbed TLS Contributors
-# SPDX-License-Identifier: Apache-2.0
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-use warnings;
-use strict;
-
-use utf8;
-use open qw(:std utf8);
-
--d 'include/mbedtls' or die "$0: must be run from root\n";
-
-@ARGV = grep { ! /compat-2\.x\.h/ } <include/mbedtls/*.h>;
-push @ARGV, "3rdparty/everest/include/everest/everest.h";
-push @ARGV, "3rdparty/everest/include/everest/x25519.h";
-push @ARGV, glob("library/*.h");
-
-my @consts;
-my $state = 'out';
-while (<>)
-{
-    if( $state eq 'out' and /^(typedef )?enum \{/ ) {
-        $state = 'in';
-    } elsif( $state eq 'out' and /^(typedef )?enum/ ) {
-        $state = 'start';
-    } elsif( $state eq 'start' and /{/ ) {
-        $state = 'in';
-    } elsif( $state eq 'in' and /}/ ) {
-        $state = 'out';
-    } elsif( $state eq 'in' and not /^#/) {
-        s/=.*//; s!/\*.*!!; s/,.*//; s/\s+//g; chomp;
-        push @consts, $_ if $_;
-    }
-}
-
-open my $fh, '>', 'enum-consts' or die;
-print $fh "$_\n" for sort @consts;
-close $fh or die;
-
-printf "%8d enum-consts\n", scalar @consts;
diff --git a/tests/scripts/list-identifiers.sh b/tests/scripts/list-identifiers.sh
index 9698fc8..9b93080 100755
--- a/tests/scripts/list-identifiers.sh
+++ b/tests/scripts/list-identifiers.sh
@@ -1,8 +1,11 @@
 #!/bin/bash
 #
 # Create a file named identifiers containing identifiers from internal header
-# files or all header files, based on --internal flag.
+# files, based on the --internal flag.
 # Outputs the line count of the file to stdout.
+# A very thin wrapper around list_internal_identifiers.py for backwards
+# compatibility.
+# Must be run from Mbed TLS root.
 #
 # Usage: list-identifiers.sh [ -i | --internal ]
 #
@@ -24,7 +27,7 @@
 set -eu
 
 if [ -d include/mbedtls ]; then :; else
-    echo "$0: must be run from root" >&2
+    echo "$0: Must be run from Mbed TLS root" >&2
     exit 1
 fi
 
@@ -47,32 +50,17 @@
 
 if [ $INTERNAL ]
 then
-    HEADERS=$( ls include/mbedtls/*_internal.h library/*.h | egrep -v 'compat-2\.x\.h' )
+    tests/scripts/list_internal_identifiers.py
+    wc -l identifiers
 else
-    HEADERS=$( ls include/mbedtls/*.h include/psa/*.h library/*.h | egrep -v 'compat-2\.x\.h' )
-    HEADERS="$HEADERS 3rdparty/everest/include/everest/everest.h 3rdparty/everest/include/everest/x25519.h"
+    cat <<EOF
+Sorry, this script has to be called with --internal.
+
+This script exists solely for backwards compatibility with the previous
+iteration of list-identifiers.sh, of which only the --internal option remains in
+use. It is a thin wrapper around list_internal_identifiers.py.
+
+check-names.sh, which used to depend on this script, has been replaced with
+check_names.py and is now self-complete.
+EOF
 fi
-
-rm -f identifiers
-
-grep '^[^ /#{]' $HEADERS | \
-    sed -e 's/^[^:]*://' | \
-    egrep -v '^(extern "C"|(typedef )?(struct|union|enum)( {)?$|};?$)' \
-    > _decls
-
-if true; then
-sed -n -e 's/.* \**\([a-zA-Z_][a-zA-Z0-9_]*\)(.*/\1/p' \
-       -e 's/.*(\*\(.*\))(.*/\1/p' _decls
-grep -v '(' _decls | sed -e 's/\([a-zA-Z0-9_]*\)[;[].*/\1/' -e 's/.* \**//'
-fi > _identifiers
-
-if [ $( wc -l < _identifiers ) -eq $( wc -l < _decls ) ]; then
-    rm _decls
-    egrep -v '^(u?int(16|32|64)_t)$' _identifiers | sort > identifiers
-    rm _identifiers
-else
-    echo "$0: oops, lost some identifiers" 2>&1
-    exit 1
-fi
-
-wc -l identifiers
diff --git a/tests/scripts/list-macros.sh b/tests/scripts/list-macros.sh
deleted file mode 100755
index 2e62359..0000000
--- a/tests/scripts/list-macros.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-#
-# Copyright The Mbed TLS Contributors
-# SPDX-License-Identifier: Apache-2.0
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -eu
-
-if [ -d include/mbedtls ]; then :; else
-    echo "$0: must be run from root" >&2
-    exit 1
-fi
-
-HEADERS=$( ls include/mbedtls/*.h include/psa/*.h tests/include/test/drivers/*.h | egrep -v 'compat-2\.x\.h' )
-HEADERS="$HEADERS library/*.h"
-HEADERS="$HEADERS 3rdparty/everest/include/everest/everest.h 3rdparty/everest/include/everest/x25519.h"
-
-sed -n -e 's/.*#define \([a-zA-Z0-9_]*\).*/\1/p' $HEADERS \
-    | egrep -v '^(asm|inline|EMIT|_CRT_SECURE_NO_DEPRECATE)$|^MULADDC_' \
-    | sort -u > macros
-
-# For include/mbedtls/config_psa.h need to ignore the MBEDTLS_xxx define
-# in that file since they may not be defined in include/psa/crypto_config.h
-# This line renames the potentially missing defines to ones that should
-# be present.
-sed -ne 's/^MBEDTLS_PSA_BUILTIN_/MBEDTLS_PSA_ACCEL_/p' <macros >>macros
-
-wc -l macros
diff --git a/tests/scripts/list-symbols.sh b/tests/scripts/list-symbols.sh
deleted file mode 100755
index 4a5d035..0000000
--- a/tests/scripts/list-symbols.sh
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/bin/sh
-#
-# Copyright The Mbed TLS Contributors
-# SPDX-License-Identifier: Apache-2.0
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -eu
-
-if [ -d include/mbedtls ]; then :; else
-    echo "$0: must be run from root" >&2
-    exit 1
-fi
-
-if grep -i cmake Makefile >/dev/null; then
-    echo "$0: not compatible with cmake" >&2
-    exit 1
-fi
-
-cp include/mbedtls/mbedtls_config.h include/mbedtls/mbedtls_config.h.bak
-scripts/config.py full
-make clean
-make_ret=
-CFLAGS=-fno-asynchronous-unwind-tables make lib \
-      >list-symbols.make.log 2>&1 ||
-  {
-    make_ret=$?
-    echo "Build failure: CFLAGS=-fno-asynchronous-unwind-tables make lib"
-    cat list-symbols.make.log >&2
-  }
-rm list-symbols.make.log
-mv include/mbedtls/mbedtls_config.h.bak include/mbedtls/mbedtls_config.h
-if [ -n "$make_ret" ]; then
-    exit "$make_ret"
-fi
-
-if uname | grep -F Darwin >/dev/null; then
-    nm -gUj library/libmbed*.a 2>/dev/null | sed -n -e 's/^_//p' | grep -v -e ^FStar -e ^Hacl
-elif uname | grep -F Linux >/dev/null; then
-    nm -og library/libmbed*.a | grep -v '^[^ ]*: *U \|^$\|^[^ ]*:$' | sed 's/^[^ ]* . //' | grep -v -e ^FStar -e ^Hacl
-fi | sort > exported-symbols
-make clean
-
-wc -l exported-symbols
diff --git a/tests/scripts/list_internal_identifiers.py b/tests/scripts/list_internal_identifiers.py
new file mode 100755
index 0000000..779a16f
--- /dev/null
+++ b/tests/scripts/list_internal_identifiers.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python3
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+This script generates a file called identifiers that contains all Mbed TLS
+identifiers found on internal headers. This is the equivalent of what was
+previously `list-identifiers.sh --internal`, and is useful for generating an
+exclusion file list for ABI/API checking, since we do not promise compatibility
+for them.
+
+It uses the CodeParser class from check_names.py to perform the parsing.
+
+The script returns 0 on success, 1 if there is a script error.
+Must be run from Mbed TLS root.
+"""
+
+import argparse
+import logging
+from check_names import CodeParser
+
+def main():
+    parser = argparse.ArgumentParser(
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        description=(
+            "This script writes a list of parsed identifiers in internal "
+            "headers to \"identifiers\". This is useful for generating a list "
+            "of names to exclude from API/ABI compatibility checking. "))
+
+    parser.parse_args()
+
+    name_check = CodeParser(logging.getLogger())
+    result = name_check.parse_identifiers([
+        "include/mbedtls/*_internal.h",
+        "library/*.h"
+    ])
+    result.sort(key=lambda x: x.name)
+
+    identifiers = ["{}\n".format(match.name) for match in result]
+    with open("identifiers", "w", encoding="utf-8") as f:
+        f.writelines(identifiers)
+
+if __name__ == "__main__":
+    main()
diff --git a/tests/src/drivers/test_driver_aead.c b/tests/src/drivers/test_driver_aead.c
index ce9ce37..6befe7c 100644
--- a/tests/src/drivers/test_driver_aead.c
+++ b/tests/src/drivers/test_driver_aead.c
@@ -21,6 +21,7 @@
 
 #if defined(MBEDTLS_PSA_CRYPTO_DRIVERS) && defined(PSA_CRYPTO_DRIVER_TEST)
 #include "psa_crypto_aead.h"
+#include "psa_crypto_core.h"
 
 #include "test/drivers/aead.h"
 
@@ -36,7 +37,7 @@
     const uint8_t *plaintext, size_t plaintext_length,
     uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length )
 {
-    mbedtls_test_driver_aead_hooks.hits++;
+    mbedtls_test_driver_aead_hooks.hits_encrypt++;
 
     if( mbedtls_test_driver_aead_hooks.forced_status != PSA_SUCCESS )
     {
@@ -67,7 +68,7 @@
     const uint8_t *ciphertext, size_t ciphertext_length,
     uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length )
 {
-    mbedtls_test_driver_aead_hooks.hits++;
+    mbedtls_test_driver_aead_hooks.hits_decrypt++;
 
     if( mbedtls_test_driver_aead_hooks.forced_status != PSA_SUCCESS )
     {
@@ -89,4 +90,229 @@
     return( mbedtls_test_driver_aead_hooks.driver_status );
 }
 
+psa_status_t mbedtls_test_transparent_aead_encrypt_setup(
+    mbedtls_transparent_test_driver_aead_operation_t *operation,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer, size_t key_buffer_size,
+    psa_algorithm_t alg )
+{
+    mbedtls_test_driver_aead_hooks.hits_encrypt_setup++;
+
+    if( mbedtls_test_driver_aead_hooks.forced_status != PSA_SUCCESS )
+    {
+         mbedtls_test_driver_aead_hooks.driver_status =
+             mbedtls_test_driver_aead_hooks.forced_status;
+    }
+    else
+    {
+        mbedtls_test_driver_aead_hooks.driver_status =
+            mbedtls_psa_aead_encrypt_setup( operation, attributes, key_buffer,
+                                            key_buffer_size, alg );
+    }
+
+    return( mbedtls_test_driver_aead_hooks.driver_status );
+}
+
+psa_status_t mbedtls_test_transparent_aead_decrypt_setup(
+    mbedtls_transparent_test_driver_aead_operation_t *operation,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer, size_t key_buffer_size,
+    psa_algorithm_t alg )
+{
+    mbedtls_test_driver_aead_hooks.hits_decrypt_setup++;
+
+    if( mbedtls_test_driver_aead_hooks.forced_status != PSA_SUCCESS )
+    {
+         mbedtls_test_driver_aead_hooks.driver_status =
+             mbedtls_test_driver_aead_hooks.forced_status;
+    }
+    else
+    {
+        mbedtls_test_driver_aead_hooks.driver_status =
+            mbedtls_psa_aead_decrypt_setup( operation, attributes, key_buffer,
+                                            key_buffer_size, alg );
+    }
+
+    return( mbedtls_test_driver_aead_hooks.driver_status );
+}
+
+psa_status_t mbedtls_test_transparent_aead_set_nonce(
+    mbedtls_transparent_test_driver_aead_operation_t *operation,
+    const uint8_t *nonce,
+    size_t nonce_length )
+{
+    mbedtls_test_driver_aead_hooks.hits_set_nonce++;
+
+    if( mbedtls_test_driver_aead_hooks.forced_status != PSA_SUCCESS )
+    {
+         mbedtls_test_driver_aead_hooks.driver_status =
+             mbedtls_test_driver_aead_hooks.forced_status;
+    }
+    else
+    {
+        mbedtls_test_driver_aead_hooks.driver_status =
+            mbedtls_psa_aead_set_nonce( operation, nonce, nonce_length );
+    }
+
+    return( mbedtls_test_driver_aead_hooks.driver_status );
+}
+
+psa_status_t mbedtls_test_transparent_aead_set_lengths(
+    mbedtls_transparent_test_driver_aead_operation_t *operation,
+    size_t ad_length,
+    size_t plaintext_length )
+{
+    mbedtls_test_driver_aead_hooks.hits_set_lengths++;
+
+    if( mbedtls_test_driver_aead_hooks.forced_status != PSA_SUCCESS )
+    {
+         mbedtls_test_driver_aead_hooks.driver_status =
+             mbedtls_test_driver_aead_hooks.forced_status;
+    }
+    else
+    {
+        mbedtls_test_driver_aead_hooks.driver_status =
+            mbedtls_psa_aead_set_lengths( operation, ad_length,
+                                          plaintext_length );
+    }
+
+    return( mbedtls_test_driver_aead_hooks.driver_status );
+}
+
+psa_status_t mbedtls_test_transparent_aead_update_ad(
+    mbedtls_transparent_test_driver_aead_operation_t *operation,
+    const uint8_t *input,
+    size_t input_length )
+{
+    mbedtls_test_driver_aead_hooks.hits_update_ad++;
+
+    if( mbedtls_test_driver_aead_hooks.forced_status != PSA_SUCCESS )
+    {
+         mbedtls_test_driver_aead_hooks.driver_status =
+             mbedtls_test_driver_aead_hooks.forced_status;
+    }
+    else
+    {
+        mbedtls_test_driver_aead_hooks.driver_status =
+            mbedtls_psa_aead_update_ad( operation, input, input_length );
+    }
+
+    return( mbedtls_test_driver_aead_hooks.driver_status );
+}
+
+psa_status_t mbedtls_test_transparent_aead_update(
+   mbedtls_transparent_test_driver_aead_operation_t *operation,
+   const uint8_t *input,
+   size_t input_length,
+   uint8_t *output,
+   size_t output_size,
+   size_t *output_length )
+{
+    mbedtls_test_driver_aead_hooks.hits_update++;
+
+    if( mbedtls_test_driver_aead_hooks.forced_status != PSA_SUCCESS )
+    {
+         mbedtls_test_driver_aead_hooks.driver_status =
+             mbedtls_test_driver_aead_hooks.forced_status;
+    }
+    else
+    {
+        mbedtls_test_driver_aead_hooks.driver_status =
+            mbedtls_psa_aead_update( operation, input, input_length, output,
+                                    output_size, output_length );
+    }
+
+    return( mbedtls_test_driver_aead_hooks.driver_status );
+}
+
+psa_status_t mbedtls_test_transparent_aead_finish(
+   mbedtls_transparent_test_driver_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 )
+{
+   mbedtls_test_driver_aead_hooks.hits_finish++;
+
+    if( mbedtls_test_driver_aead_hooks.forced_status != PSA_SUCCESS )
+    {
+         mbedtls_test_driver_aead_hooks.driver_status =
+             mbedtls_test_driver_aead_hooks.forced_status;
+    }
+    else
+    {
+        mbedtls_test_driver_aead_hooks.driver_status =
+            mbedtls_psa_aead_finish( operation, ciphertext, ciphertext_size,
+                                     ciphertext_length, tag, tag_size,
+                                     tag_length );
+    }
+
+    return( mbedtls_test_driver_aead_hooks.driver_status );
+}
+
+psa_status_t mbedtls_test_transparent_aead_verify(
+   mbedtls_transparent_test_driver_aead_operation_t *operation,
+   uint8_t *plaintext,
+   size_t plaintext_size,
+   size_t *plaintext_length,
+   const uint8_t *tag,
+   size_t tag_length )
+{
+   mbedtls_test_driver_aead_hooks.hits_verify++;
+
+    if( mbedtls_test_driver_aead_hooks.forced_status != PSA_SUCCESS )
+    {
+         mbedtls_test_driver_aead_hooks.driver_status =
+             mbedtls_test_driver_aead_hooks.forced_status;
+    }
+    else
+    {
+       uint8_t check_tag[PSA_AEAD_TAG_MAX_SIZE];
+       size_t check_tag_length;
+
+       mbedtls_test_driver_aead_hooks.driver_status =
+          mbedtls_psa_aead_finish( operation,
+                                   plaintext,
+                                   plaintext_size,
+                                   plaintext_length,
+                                   check_tag,
+                                   sizeof( check_tag ),
+                                   &check_tag_length );
+
+       if( mbedtls_test_driver_aead_hooks.driver_status == PSA_SUCCESS )
+       {
+          if( tag_length != check_tag_length ||
+              mbedtls_psa_safer_memcmp( tag, check_tag, tag_length )
+              != 0 )
+             mbedtls_test_driver_aead_hooks.driver_status =
+                                                    PSA_ERROR_INVALID_SIGNATURE;
+       }
+
+       mbedtls_platform_zeroize( check_tag, sizeof( check_tag ) );
+    }
+
+    return( mbedtls_test_driver_aead_hooks.driver_status );
+}
+
+psa_status_t mbedtls_test_transparent_aead_abort(
+   mbedtls_transparent_test_driver_aead_operation_t *operation )
+{
+   mbedtls_test_driver_aead_hooks.hits_abort++;
+
+    if( mbedtls_test_driver_aead_hooks.forced_status != PSA_SUCCESS )
+    {
+         mbedtls_test_driver_aead_hooks.driver_status =
+             mbedtls_test_driver_aead_hooks.forced_status;
+    }
+    else
+    {
+        mbedtls_test_driver_aead_hooks.driver_status =
+            mbedtls_psa_aead_abort( operation );
+    }
+
+    return( mbedtls_test_driver_aead_hooks.driver_status );
+}
+
 #endif /* MBEDTLS_PSA_CRYPTO_DRIVERS && PSA_CRYPTO_DRIVER_TEST */
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 39499d4..66c6485 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -8660,29 +8660,53 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
 run_test    "TLS1.3: handshake dispatch test: tls1_3 only" \
-            "$P_SRV min_version=tls1_3 max_version=tls1_3" \
-            "$P_CLI min_version=tls1_3 max_version=tls1_3" \
+            "$P_SRV debug_level=2 min_version=tls1_3 max_version=tls1_3" \
+            "$P_CLI debug_level=2 min_version=tls1_3 max_version=tls1_3" \
             1 \
-            -s "SSL - The requested feature is not available" \
-            -c "SSL - The requested feature is not available"
+            -s "tls1_3 server state: 0"     \
+            -c "tls1_3 client state: 0"
 
 requires_openssl_tls1_3
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
 run_test    "TLS1.3: Test client hello msg work - openssl" \
             "$O_NEXT_SRV -tls1_3 -msg" \
-            "$P_CLI min_version=tls1_3 max_version=tls1_3" \
+            "$P_CLI debug_level=2 min_version=tls1_3 max_version=tls1_3" \
             1 \
             -c "SSL - The requested feature is not available" \
-            -s "ServerHello"
+            -s "ServerHello"                \
+            -c "tls1_3 client state: 0"     \
+            -c "tls1_3 client state: 2"     \
+            -c "tls1_3 client state: 19"    \
+            -c "tls1_3 client state: 5"     \
+            -c "tls1_3 client state: 3"     \
+            -c "tls1_3 client state: 9"     \
+            -c "tls1_3 client state: 13"    \
+            -c "tls1_3 client state: 7"     \
+            -c "tls1_3 client state: 20"    \
+            -c "tls1_3 client state: 11"    \
+            -c "tls1_3 client state: 14"    \
+            -c "tls1_3 client state: 15"
 
 requires_gnutls_tls1_3
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
 run_test    "TLS1.3: Test client hello msg work - gnutls" \
             "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 --debug=4" \
-            "$P_CLI min_version=tls1_3 max_version=tls1_3" \
+            "$P_CLI debug_level=2 min_version=tls1_3 max_version=tls1_3" \
             1 \
             -c "SSL - The requested feature is not available" \
-            -s "SERVER HELLO was queued"
+            -s "SERVER HELLO was queued"    \
+            -c "tls1_3 client state: 0"     \
+            -c "tls1_3 client state: 2"     \
+            -c "tls1_3 client state: 19"    \
+            -c "tls1_3 client state: 5"     \
+            -c "tls1_3 client state: 3"     \
+            -c "tls1_3 client state: 9"     \
+            -c "tls1_3 client state: 13"    \
+            -c "tls1_3 client state: 7"     \
+            -c "tls1_3 client state: 20"    \
+            -c "tls1_3 client state: 11"    \
+            -c "tls1_3 client state: 14"    \
+            -c "tls1_3 client state: 15"
 
 # Test heap memory usage after handshake
 requires_config_enabled MBEDTLS_MEMORY_DEBUG
diff --git a/tests/suites/test_suite_cipher.aes.data b/tests/suites/test_suite_cipher.aes.data
index 4dbdd52..c8fbca2 100644
--- a/tests/suites/test_suite_cipher.aes.data
+++ b/tests/suites/test_suite_cipher.aes.data
@@ -1798,6 +1798,102 @@
 depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
 test_vec_crypt:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"5c9d844ed46f9885085e5d6a4f94c7d7":"014730f80ac625fe84f026c60bfd547d":0:1
 
+AES-128-ECB crypt Encrypt NIST KAT #1 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_ENCRYPT:"00000000000000000000000000000000":"":"80000000000000000000000000000000":"3ad78e726c1ec02b7ebfe92b23d9ec34":0:1
+
+AES-128-ECB crypt Encrypt NIST KAT #2 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_ENCRYPT:"ffffffffffffffffffffffffffffe000":"":"00000000000000000000000000000000":"323994cfb9da285a5d9642e1759b224a":0:1
+
+AES-128-ECB crypt Encrypt NIST KAT #3 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_ENCRYPT:"10a58869d74be5a374cf867cfb473859":"":"00000000000000000000000000000000":"6d251e6944b051e04eaa6fb4dbf78465":0:1
+
+AES-128-ECB crypt Encrypt NIST KAT #4 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_ENCRYPT:"00000000000000000000000000000000":"":"f34481ec3cc627bacd5dc3fb08f273e6":"0336763e966d92595a567cc9ce537f5e":0:1
+
+AES-128-ECB crypt Decrypt NIST KAT #1 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"00000000000000000000000000000000":"":"3ad78e726c1ec02b7ebfe92b23d9ec34":"80000000000000000000000000000000":0:1
+
+AES-128-ECB crypt Decrypt NIST KAT #2 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"ffffc000000000000000000000000000":"":"df556a33438db87bc41b1752c55e5e49":"00000000000000000000000000000000":0:1
+
+AES-128-ECB crypt Decrypt NIST KAT #3 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"10a58869d74be5a374cf867cfb473859":"":"6d251e6944b051e04eaa6fb4dbf78465":"00000000000000000000000000000000":0:1
+
+AES-128-ECB crypt Decrypt NIST KAT #4 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"00000000000000000000000000000000":"":"0336763e966d92595a567cc9ce537f5e":"f34481ec3cc627bacd5dc3fb08f273e6":0:1
+
+AES-192-ECB crypt Encrypt NIST KAT #1 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_ENCRYPT:"000000000000000000000000000000000000000000000000":"":"80000000000000000000000000000000":"6cd02513e8d4dc986b4afe087a60bd0c":0:1
+
+AES-192-ECB crypt Encrypt NIST KAT #2 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_ENCRYPT:"ff0000000000000000000000000000000000000000000000":"":"00000000000000000000000000000000":"833f71258d53036b02952c76c744f5a1":0:1
+
+AES-192-ECB crypt Encrypt NIST KAT #3 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_ENCRYPT:"e9f065d7c13573587f7875357dfbb16c53489f6a4bd0f7cd":"":"00000000000000000000000000000000":"0956259c9cd5cfd0181cca53380cde06":0:1
+
+AES-192-ECB crypt Encrypt NIST KAT #4 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_ENCRYPT:"000000000000000000000000000000000000000000000000":"":"1b077a6af4b7f98229de786d7516b639":"275cfc0413d8ccb70513c3859b1d0f72":0:1
+
+AES-192-ECB crypt Decrypt NIST KAT #1 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"000000000000000000000000000000000000000000000000":"":"6cd02513e8d4dc986b4afe087a60bd0c":"80000000000000000000000000000000":0:1
+
+AES-192-ECB crypt Decrypt NIST KAT #2 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"ffe000000000000000000000000000000000000000000000":"":"7ababc4b3f516c9aafb35f4140b548f9":"00000000000000000000000000000000":0:1
+
+AES-192-ECB crypt Decrypt NIST KAT #3 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"e9f065d7c13573587f7875357dfbb16c53489f6a4bd0f7cd":"":"0956259c9cd5cfd0181cca53380cde06":"00000000000000000000000000000000":0:1
+
+AES-192-ECB crypt Decrypt NIST KAT #4 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"000000000000000000000000000000000000000000000000":"":"275cfc0413d8ccb70513c3859b1d0f72":"1b077a6af4b7f98229de786d7516b639":0:1
+
+AES-256-ECB crypt Encrypt NIST KAT #1 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_ENCRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"":"80000000000000000000000000000000":"ddc6bf790c15760d8d9aeb6f9a75fd4e":0:1
+
+AES-256-ECB crypt Encrypt NIST KAT #2 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_ENCRYPT:"ff00000000000000000000000000000000000000000000000000000000000000":"":"00000000000000000000000000000000":"ec52a212f80a09df6317021bc2a9819e":0:1
+
+AES-256-ECB crypt Encrypt NIST KAT #3 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_ENCRYPT:"c47b0294dbbbee0fec4757f22ffeee3587ca4730c3d33b691df38bab076bc558":"":"00000000000000000000000000000000":"46f2fb342d6f0ab477476fc501242c5f":0:1
+
+AES-256-ECB crypt Encrypt NIST KAT #4 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_ENCRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"":"014730f80ac625fe84f026c60bfd547d":"5c9d844ed46f9885085e5d6a4f94c7d7":0:1
+
+AES-256-ECB crypt Decrypt NIST KAT #1 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"":"ddc6bf790c15760d8d9aeb6f9a75fd4e":"80000000000000000000000000000000":0:1
+
+AES-256-ECB crypt Decrypt NIST KAT #2 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"ffe0000000000000000000000000000000000000000000000000000000000000":"":"d1ccb9b1337002cbac42c520b5d67722":"00000000000000000000000000000000":0:1
+
+AES-256-ECB crypt Decrypt NIST KAT #3 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"c47b0294dbbbee0fec4757f22ffeee3587ca4730c3d33b691df38bab076bc558":"":"46f2fb342d6f0ab477476fc501242c5f":"00000000000000000000000000000000":0:1
+
+AES-256-ECB crypt Decrypt NIST KAT #4 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"":"5c9d844ed46f9885085e5d6a4f94c7d7":"014730f80ac625fe84f026c60bfd547d":0:1
+
 Cipher Corner Case behaviours
 depends_on:MBEDTLS_AES_C
 cipher_special_behaviours:
diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function
index 674349f..c809d9a 100644
--- a/tests/suites/test_suite_cipher.function
+++ b/tests/suites/test_suite_cipher.function
@@ -13,6 +13,59 @@
 #define MBEDTLS_CIPHER_AUTH_CRYPT
 #endif
 
+/* Check the internal consistency of a cipher info structure, and
+ * check it against mbedtls_cipher_info_from_xxx(). */
+static int check_cipher_info( mbedtls_cipher_type_t type,
+                              const mbedtls_cipher_info_t *info )
+{
+    size_t key_bitlen;
+
+    TEST_ASSERT( info != NULL );
+    TEST_EQUAL( type, mbedtls_cipher_info_get_type( info ) );
+    TEST_EQUAL( type, info->type );
+    TEST_ASSERT( mbedtls_cipher_info_from_type( type ) == info );
+
+    TEST_EQUAL( info->mode, mbedtls_cipher_info_get_mode( info ) );
+
+    /* Insist that get_name() return the string from the structure and
+     * not a copy. A copy would have an unknown storage duration. */
+    TEST_ASSERT( mbedtls_cipher_info_get_name( info ) == info->name );
+    TEST_ASSERT( mbedtls_cipher_info_from_string( info->name ) == info );
+
+    key_bitlen = mbedtls_cipher_info_get_key_bitlen( info );
+    if( info->type == MBEDTLS_CIPHER_NULL )
+        TEST_ASSERT( key_bitlen == 0 );
+    else if( info->mode == MBEDTLS_MODE_XTS )
+    {
+        TEST_ASSERT( key_bitlen == 256 ||
+                     key_bitlen == 384 ||
+                     key_bitlen == 512 );
+    }
+    else if( ! strncmp( info->name, "DES-EDE3-", 9 ) )
+    {
+        TEST_ASSERT( key_bitlen == 192 );
+    }
+    else if( ! strncmp( info->name, "DES-EDE-", 8 ) )
+    {
+        TEST_ASSERT( key_bitlen == 128 );
+    }
+    else if( ! strncmp( info->name, "DES-", 4 ) )
+    {
+        TEST_ASSERT( key_bitlen == 64 );
+    }
+    else
+    {
+        TEST_ASSERT( key_bitlen == 128 ||
+                     key_bitlen == 192 ||
+                     key_bitlen == 256 );
+    }
+
+    return( 1 );
+
+exit:
+    return( 0 );
+}
+
 #if defined(MBEDTLS_CIPHER_AUTH_CRYPT)
 /* Helper for resetting key/direction
  *
@@ -81,7 +134,13 @@
     const int *cipher_type;
 
     for( cipher_type = mbedtls_cipher_list(); *cipher_type != 0; cipher_type++ )
-        TEST_ASSERT( mbedtls_cipher_info_from_type( *cipher_type ) != NULL );
+    {
+        const mbedtls_cipher_info_t *info =
+            mbedtls_cipher_info_from_type( *cipher_type );
+        mbedtls_test_set_step( *cipher_type );
+        if( ! check_cipher_info( *cipher_type, info ) )
+            goto exit;
+    }
 }
 /* END_CASE */
 
@@ -309,6 +368,8 @@
     cipher_info = mbedtls_cipher_info_from_type( cipher_id );
     TEST_ASSERT( NULL != cipher_info );
     TEST_ASSERT( mbedtls_cipher_info_from_string( cipher_string ) == cipher_info );
+    TEST_ASSERT( strcmp( mbedtls_cipher_info_get_name( cipher_info ),
+                         cipher_string ) == 0 );
 
     /* Initialise enc and dec contexts */
     TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx_dec, cipher_info ) );
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index d9eafc0..063629e 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -2482,6 +2482,22 @@
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
 aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 18 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
 
+PSA AEAD decrypt: AES-CCM, invalid nonce length 6
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c090693056":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_NOT_SUPPORTED
+
+PSA AEAD decrypt: AES-CCM, invalid nonce length 14
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd97200":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_NOT_SUPPORTED
+
+PSA AEAD decrypt: AES-CCM_8, invalid nonce length 6
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 8 ):"48c090693056":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_NOT_SUPPORTED
+
+PSA AEAD decrypt: AES-CCM_8, invalid nonce length 14
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 8 ):"48c0906930561e0ab0ef4cd97200":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_NOT_SUPPORTED
+
 PSA AEAD encrypt/decrypt, AES-GCM, 19 bytes #1
 depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
 aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":PSA_ALG_GCM:"000102030405060708090A0B0C0D0E0F":"000102030405060708090A0B":"0C0D0E0F101112131415161718191A1B1C1D1E":PSA_SUCCESS
@@ -2634,6 +2650,14 @@
 depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
 aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 2 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
 
+PSA AEAD decrypt: AES-GCM, nonce=0 (bad)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"":PSA_ERROR_NOT_SUPPORTED
+
+PSA AEAD decrypt: AES-GCM, nonce=0 (bad), TAG=12
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 12 ):"":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"":PSA_ERROR_NOT_SUPPORTED
+
 PSA AEAD decrypt: AES-GCM, invalid tag length 18
 depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
 aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 18 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
@@ -2738,6 +2762,18 @@
 depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
 aead_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"070000004041424344454647":"":"a0784d7a4716f3feb4f64e7f4b39bf04":"":PSA_SUCCESS
 
+PSA AEAD decrypt: ChaCha20-Poly1305 (nonce=8, not supported)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"0700000040414243":"":"a0784d7a4716f3feb4f64e7f4b39bf04":"":PSA_ERROR_NOT_SUPPORTED
+
+PSA AEAD decrypt: ChaCha20-Poly1305 (nonce=11, too short)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"0700000040414243444546":"":"a0784d7a4716f3feb4f64e7f4b39bf04":"":PSA_ERROR_NOT_SUPPORTED
+
+PSA AEAD decrypt: ChaCha20-Poly1305 (nonce=13, too long)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"07000000404142434445464700":"":"a0784d7a4716f3feb4f64e7f4b39bf04":"":PSA_ERROR_NOT_SUPPORTED
+
 PSA AEAD encrypt/decrypt: invalid algorithm (CTR)
 depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
 aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CTR:"000102030405060708090A0B0C0D0E0F":"":"":PSA_ERROR_NOT_SUPPORTED
@@ -2746,6 +2782,614 @@
 depends_on:MBEDTLS_CHACHA20_C
 aead_encrypt_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_STREAM_CIPHER:"":"":"":PSA_ERROR_NOT_SUPPORTED
 
+PSA Multipart AEAD encrypt, AES-GCM, 128 bytes #1
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":0:"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96"
+
+PSA Multipart AEAD encrypt, AES-GCM, 128 bytes #1 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":1:"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96"
+
+PSA Multipart AEAD encrypt, AES-GCM, 128 bytes #2
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"fe96eab10ff48c7942025422583d0377":PSA_ALG_GCM:"97ce3f848276783599c6875de324361e":"127628b6dcbce6fc8a8ef60798eb67b2088415635119697d20bb878c24d9c6f9c29e148521cb5e0feff892c7855d4f1c0bfb32ad33420976714dce87a0bbc18e4378bd1ef35197d0ca73051148f1199010f63caf122df5f71ad8d9c71df3eb2fbe3b2529d0ba657570358d3776f687bdb9c96d5e0e9e00c4b42d5d7a268d6a08":"194c8bbbfae4a671386b8cd38f390f46f9df6b8661b470c310921a1c858a938045834bb10380037fbf5f5e00688554537be0fcafe8270b9b59068fa056ab1268fc166c2d729243a06650a171c929c7845c85330c04568d62977eedf3b1ba9dca13bdb8f9522817c8cb99e635e37465ec1c9f6f148d51437aa9f994a62e1bd013":0:"12495120056ca3cac70d583603a476821bac6c57c9733b81cfb83538dc9e850f8bdf46065069591c23ebcbc6d1e2523375fb7efc80c09507fa25477ed07cee54fc4eb90168b3ef988f651fc40652474a644b1b311decf899660aef2347bb081af48950f06ebf799911e37120de94c55c20e5f0a77119be06e2b6e557f872fa0f6bac793bdc2190a195122c98544ccf56"
+
+PSA Multipart AEAD encrypt, AES-GCM, 128 bytes #2 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"fe96eab10ff48c7942025422583d0377":PSA_ALG_GCM:"97ce3f848276783599c6875de324361e":"127628b6dcbce6fc8a8ef60798eb67b2088415635119697d20bb878c24d9c6f9c29e148521cb5e0feff892c7855d4f1c0bfb32ad33420976714dce87a0bbc18e4378bd1ef35197d0ca73051148f1199010f63caf122df5f71ad8d9c71df3eb2fbe3b2529d0ba657570358d3776f687bdb9c96d5e0e9e00c4b42d5d7a268d6a08":"194c8bbbfae4a671386b8cd38f390f46f9df6b8661b470c310921a1c858a938045834bb10380037fbf5f5e00688554537be0fcafe8270b9b59068fa056ab1268fc166c2d729243a06650a171c929c7845c85330c04568d62977eedf3b1ba9dca13bdb8f9522817c8cb99e635e37465ec1c9f6f148d51437aa9f994a62e1bd013":1:"12495120056ca3cac70d583603a476821bac6c57c9733b81cfb83538dc9e850f8bdf46065069591c23ebcbc6d1e2523375fb7efc80c09507fa25477ed07cee54fc4eb90168b3ef988f651fc40652474a644b1b311decf899660aef2347bb081af48950f06ebf799911e37120de94c55c20e5f0a77119be06e2b6e557f872fa0f6bac793bdc2190a195122c98544ccf56"
+
+PSA Multipart AEAD encrypt, AES-GCM, 128 bytes #1, T=4
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 4 ):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":0:"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847f"
+
+PSA Multipart AEAD encrypt, AES-GCM, 128 bytes #1, T=4 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 4 ):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":1:"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847f"
+
+PSA Multipart AEAD encrypt, AES-GCM, 128 bytes #1, T=15
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":0:"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a"
+
+PSA Multipart AEAD encrypt, AES-GCM, 128 bytes #1, T=15 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":1:"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a"
+
+PSA Multipart AEAD encrypt, AES-GCM, 128 bytes #1, T=16
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":0:"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96"
+
+PSA Multipart AEAD encrypt, AES-GCM, 128 bytes #1, T=16 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":1:"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=24, IV=12, IN=0, AAD=0, TAG=16,
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"ab2265b4c168955561f04315":"":"":0:"f149e2b5f0adaa9842ca5f45b768a8fc"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=24, IV=12, IN=0, AAD=0, TAG=16, (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"ab2265b4c168955561f04315":"":"":1:"f149e2b5f0adaa9842ca5f45b768a8fc"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=24, IV=12, IN=0, AAD=16, TAG=16,
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"41c5da8667ef725220ffe39ae0ac590ac9fca729ab60ada0":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"05ad13a5e2c2ab667e1a6fbc":"8b5c124bef6e2f0fe4d8c95cd5fa4cf1":"":0:"204bdb1bd62154bf08922aaa54eed705"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=24, IV=12, IN=0, AAD=16, TAG=16, (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"41c5da8667ef725220ffe39ae0ac590ac9fca729ab60ada0":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"05ad13a5e2c2ab667e1a6fbc":"8b5c124bef6e2f0fe4d8c95cd5fa4cf1":"":1:"204bdb1bd62154bf08922aaa54eed705"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=24, IV=12, IN=0, AAD=20, TAG=16,
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"093ef7551ebbff8eb0c0a8a4a62b198f0c2e838de10eeeee":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"e656e93930ed5210ba3f0322":"3da22dacfd11b21b0a713157f60aec0cd22f1add":"":0:"1b2d2764573e20ae640bf29d48e5fe05"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=24, IV=12, IN=0, AAD=20, TAG=16, (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"093ef7551ebbff8eb0c0a8a4a62b198f0c2e838de10eeeee":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"e656e93930ed5210ba3f0322":"3da22dacfd11b21b0a713157f60aec0cd22f1add":"":1:"1b2d2764573e20ae640bf29d48e5fe05"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=24, IV=12, IN=0, AAD=48, TAG=15,
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"31389612d244c9792a510eca3f9c94f9f48c97ed67ae965a":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"df6b54ec8b58114df5b09279":"0863bec42ee93385efbec665adfc46dafcd793f29e859e3b531c15b168f1888dd13e905cd7d5bc03f9f1f6495717df62":"":0:"77e5682a49243d5b9016eb1adafa2d"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=24, IV=12, IN=0, AAD=48, TAG=15, (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"31389612d244c9792a510eca3f9c94f9f48c97ed67ae965a":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"df6b54ec8b58114df5b09279":"0863bec42ee93385efbec665adfc46dafcd793f29e859e3b531c15b168f1888dd13e905cd7d5bc03f9f1f6495717df62":"":1:"77e5682a49243d5b9016eb1adafa2d"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=24, IV=12, IN=16, AAD=0, TAG=16,
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"fbc0b4c56a714c83217b2d1bcadd2ed2e9efb0dcac6cc19f":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"5f4b43e811da9c470d6a9b01":"":"d2ae38c4375954835d75b8e4c2f9bbb4":0:"69482957e6be5c54882d00314e0259cf191e9f29bef63a26860c1e020a21137e"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=24, IV=12, IN=16, AAD=0, TAG=16, (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"fbc0b4c56a714c83217b2d1bcadd2ed2e9efb0dcac6cc19f":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"5f4b43e811da9c470d6a9b01":"":"d2ae38c4375954835d75b8e4c2f9bbb4":1:"69482957e6be5c54882d00314e0259cf191e9f29bef63a26860c1e020a21137e"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=24, IV=12, IN=16, AAD=0, TAG=8,
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"c50ac59e50556e47b834380018c0dc0380af9df3bf6714e6":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 8 ):"f303bf4b6cfbba7104cd9436":"":"d3f3f57033df30c22860231334b099cb":0:"2269c72d77f2b6f9d57da1820ec5a5d3d62d4491e3e4e9e7"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=24, IV=12, IN=16, AAD=0, TAG=8, (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"c50ac59e50556e47b834380018c0dc0380af9df3bf6714e6":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 8 ):"f303bf4b6cfbba7104cd9436":"":"d3f3f57033df30c22860231334b099cb":1:"2269c72d77f2b6f9d57da1820ec5a5d3d62d4491e3e4e9e7"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=24, IV=12, IN=16, AAD=16, TAG=14,
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"8ef391e4b7a2fe05b959be27823357080f963ed2f64b9e59":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 14 ):"0080052a2a5bb0e95222a419":"290322092d57479e20f6281e331d95a9":"e7fb0631eebf9bdba87045b33650c4ce":0:"88d674044031414af7ba9da8b89dd68e69897d99d8e1706f38c613896c18"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=24, IV=12, IN=16, AAD=16, TAG=14, (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"8ef391e4b7a2fe05b959be27823357080f963ed2f64b9e59":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 14 ):"0080052a2a5bb0e95222a419":"290322092d57479e20f6281e331d95a9":"e7fb0631eebf9bdba87045b33650c4ce":1:"88d674044031414af7ba9da8b89dd68e69897d99d8e1706f38c613896c18"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=24, IV=12, IN=16, AAD=16, TAG=4,
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"1cb5a0db778d3eb430b2816ceef9e455f519a8977b074183":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 4 ):"c1df5e9e2e3165c54242a306":"7134e5ddc396c2a8a7da23906c8f7b40":"636871d4c0aae3da7b55abd8b5f21297":0:"14eb02562aa1d963d0033626cdc8a5c8972f4bdf"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=24, IV=12, IN=16, AAD=16, TAG=4, (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"1cb5a0db778d3eb430b2816ceef9e455f519a8977b074183":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 4 ):"c1df5e9e2e3165c54242a306":"7134e5ddc396c2a8a7da23906c8f7b40":"636871d4c0aae3da7b55abd8b5f21297":1:"14eb02562aa1d963d0033626cdc8a5c8972f4bdf"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=24, IV=12, IN=16, AAD=20, TAG=13,
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"45148f42669f8ab8fad689d9b9180e39d7ea8fc95696297e":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 13 ):"5afcb134acc78b4eb9d11e79":"aec409e5fd82e50b824ebc1f45e75188d80615c6":"3d952be11deb421b56e0ce9d7ce99553":0:"077c0d53869869e191df116fd7baa8a293d2b577a29b0953c91b5d3b9d"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=24, IV=12, IN=16, AAD=20, TAG=13, (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"45148f42669f8ab8fad689d9b9180e39d7ea8fc95696297e":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 13 ):"5afcb134acc78b4eb9d11e79":"aec409e5fd82e50b824ebc1f45e75188d80615c6":"3d952be11deb421b56e0ce9d7ce99553":1:"077c0d53869869e191df116fd7baa8a293d2b577a29b0953c91b5d3b9d"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=24, IV=12, IN=16, AAD=48, TAG=15,
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"5255428457fe75e64447971ec5af0d13c5b60a07ee2d07b0":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"40cb6ebafc202f82223db097":"b2da2bd05ab1f3e39613efc8d80c5d0f240ee08f6abad5791649e9c1d0f48fa3dc59c1e535d1db1a4d3fa2263f5a1117":"fdd8a462c86d4365c8bfee0e25fc8a62":0:"9ca4a6d08267038f6f7999c84105bb5eaf8f7b3b9310ec688e033088a03482"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=24, IV=12, IN=16, AAD=48, TAG=15, (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"5255428457fe75e64447971ec5af0d13c5b60a07ee2d07b0":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"40cb6ebafc202f82223db097":"b2da2bd05ab1f3e39613efc8d80c5d0f240ee08f6abad5791649e9c1d0f48fa3dc59c1e535d1db1a4d3fa2263f5a1117":"fdd8a462c86d4365c8bfee0e25fc8a62":1:"9ca4a6d08267038f6f7999c84105bb5eaf8f7b3b9310ec688e033088a03482"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=32, IV=12, IN=0, AAD=0, TAG=16,
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"b52c505a37d78eda5dd34f20c22540ea1b58963cf8e5bf8ffa85f9f2492505b4":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"516c33929df5a3284ff463d7":"":"":0:"bdc1ac884d332457a1d2664f168c76f0"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=32, IV=12, IN=0, AAD=0, TAG=16, (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"b52c505a37d78eda5dd34f20c22540ea1b58963cf8e5bf8ffa85f9f2492505b4":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"516c33929df5a3284ff463d7":"":"":1:"bdc1ac884d332457a1d2664f168c76f0"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=32, IV=12, IN=0, AAD=0, TAG=12,
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"98ebf7a58db8b8371d9069171190063cc1fdc1927e49a3385f890d41a838619c":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 12 ):"3e6db953bd4e641de644e50a":"":"":0:"2fb9c3e41fff24ef07437c47"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=32, IV=12, IN=0, AAD=0, TAG=12, (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"98ebf7a58db8b8371d9069171190063cc1fdc1927e49a3385f890d41a838619c":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 12 ):"3e6db953bd4e641de644e50a":"":"":1:"2fb9c3e41fff24ef07437c47"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=32, IV=12, IN=0, AAD=20, TAG=16,
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"886cff5f3e6b8d0e1ad0a38fcdb26de97e8acbe79f6bed66959a598fa5047d65":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"3a8efa1cd74bbab5448f9945":"519fee519d25c7a304d6c6aa1897ee1eb8c59655":"":0:"f6d47505ec96c98a42dc3ae719877b87"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=32, IV=12, IN=0, AAD=20, TAG=16, (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"886cff5f3e6b8d0e1ad0a38fcdb26de97e8acbe79f6bed66959a598fa5047d65":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"3a8efa1cd74bbab5448f9945":"519fee519d25c7a304d6c6aa1897ee1eb8c59655":"":1:"f6d47505ec96c98a42dc3ae719877b87"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=32, IV=12, IN=0, AAD=20, TAG=13,
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"a7c928738b89c3258b910ac31bc465338b2e133b143fd52d9c9859eb1d01f2a0":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 13 ):"a483a7e94fbb2d694d3c4a8d":"bdb613cd3c2f0edd37b3ed43041bacb949ee51fa":"":0:"5233f95bdcf5d666fb957acdcb"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=32, IV=12, IN=0, AAD=20, TAG=13, (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"a7c928738b89c3258b910ac31bc465338b2e133b143fd52d9c9859eb1d01f2a0":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 13 ):"a483a7e94fbb2d694d3c4a8d":"bdb613cd3c2f0edd37b3ed43041bacb949ee51fa":"":1:"5233f95bdcf5d666fb957acdcb"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=32, IV=12, IN=0, AAD=48, TAG=15,
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"16a5b58a1dbb273a8fc6a4af722d46dbb898dd86ab128cb93d8388a8647a80a3":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"59e0c40d6675923cf5e004d5":"5b4b4ffc9c66bd394abeed3f03b695b949b3b69a42198cc3bfad971174915df913b967ccf36ee1f001f54efbcd117b68":"":0:"d57e27914ecb4a764359d3c0f8d4d6"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=32, IV=12, IN=0, AAD=48, TAG=15, (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"16a5b58a1dbb273a8fc6a4af722d46dbb898dd86ab128cb93d8388a8647a80a3":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"59e0c40d6675923cf5e004d5":"5b4b4ffc9c66bd394abeed3f03b695b949b3b69a42198cc3bfad971174915df913b967ccf36ee1f001f54efbcd117b68":"":1:"d57e27914ecb4a764359d3c0f8d4d6"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=32, IV=12, IN=0, AAD=48, TAG=4,
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"5dd13092dd695b90ab835ed6343031c4cdb710d32f4d3804d72b46d921fcfa18":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 4 ):"1de4bd816c8ec6bffc1e6453":"1b63d6278702abacf8b6c2faf542a808659fd5da03cdc1061a8593ea8ce9fc8ff54ffef6ebf3e15f7a832b4ae750a6ce":"":0:"72901467"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=32, IV=12, IN=0, AAD=48, TAG=4, (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"5dd13092dd695b90ab835ed6343031c4cdb710d32f4d3804d72b46d921fcfa18":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 4 ):"1de4bd816c8ec6bffc1e6453":"1b63d6278702abacf8b6c2faf542a808659fd5da03cdc1061a8593ea8ce9fc8ff54ffef6ebf3e15f7a832b4ae750a6ce":"":1:"72901467"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=32, IV=12, IN=16, AAD=0, TAG=15,
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"ef9f9284cf599eac3b119905a7d18851e7e374cf63aea04358586b0f757670f8":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"b6ac8e4963f49207ffd6374c":"":"722ee47da4b77424733546c2d400c4e5":0:"1224dfefb72a20d49e09256908874979882eafea22adf8dbed06a2265f907b"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=32, IV=12, IN=16, AAD=0, TAG=15, (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"ef9f9284cf599eac3b119905a7d18851e7e374cf63aea04358586b0f757670f8":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"b6ac8e4963f49207ffd6374c":"":"722ee47da4b77424733546c2d400c4e5":1:"1224dfefb72a20d49e09256908874979882eafea22adf8dbed06a2265f907b"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=32, IV=12, IN=16, AAD=0, TAG=12,
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"b33b0e4c5b9f7ef77cec1a29ed5844bda3853238bdf7766e7645029931f169f0":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 12 ):"f226d65e8654fdf5193ed721":"":"bcf48ddcfe9d011a1003973d68d2d78a":0:"d2eb20898a301b5d8e69e9926272021393af01abb6a970047a7fc010"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=32, IV=12, IN=16, AAD=0, TAG=12, (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"b33b0e4c5b9f7ef77cec1a29ed5844bda3853238bdf7766e7645029931f169f0":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 12 ):"f226d65e8654fdf5193ed721":"":"bcf48ddcfe9d011a1003973d68d2d78a":1:"d2eb20898a301b5d8e69e9926272021393af01abb6a970047a7fc010"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=32, IV=12, IN=16, AAD=16, TAG=14,
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"c6e126a65faec77ab62318e30d8a50c39a664670039a66ae5a6874201bc68f9f":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 14 ):"0ba5193b2d3a8378d67163ce":"5844b289dc74327f9fd93f7aae1c3d39":"c37aada3d4408e880d47e41df77da9b9":0:"b5cd7563989b460a2fe187e90c41fc3179c73d0d1e3a4484909969de93b0"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=32, IV=12, IN=16, AAD=16, TAG=14, (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"c6e126a65faec77ab62318e30d8a50c39a664670039a66ae5a6874201bc68f9f":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 14 ):"0ba5193b2d3a8378d67163ce":"5844b289dc74327f9fd93f7aae1c3d39":"c37aada3d4408e880d47e41df77da9b9":1:"b5cd7563989b460a2fe187e90c41fc3179c73d0d1e3a4484909969de93b0"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=32, IV=12, IN=16, AAD=48, TAG=15,
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"2e6942d537f1a98444c2f9dbdb5d8db42a503a00a17b57d516399569e044a703":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"7eb67721581ed52cfcfc2c4d":"a96cc73451502c7278b467ac85d5fc14fc1a2f51bc685645b173f0cd9af02d383095de063e6eaa50374ce9bc951e9e61":"e5f410fe939e79b7ad33fbd3aaf5856f":0:"727f5e19a5582e5782bbbe73517f0c04c492319abf12b03b380724ff1483a3"
+
+PSA Multipart AEAD encrypt, AES-GCM, CAVS 14.0, KEY=32, IV=12, IN=16, AAD=48, TAG=15, (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_encrypt:PSA_KEY_TYPE_AES:"2e6942d537f1a98444c2f9dbdb5d8db42a503a00a17b57d516399569e044a703":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"7eb67721581ed52cfcfc2c4d":"a96cc73451502c7278b467ac85d5fc14fc1a2f51bc685645b173f0cd9af02d383095de063e6eaa50374ce9bc951e9e61":"e5f410fe939e79b7ad33fbd3aaf5856f":1:"727f5e19a5582e5782bbbe73517f0c04c492319abf12b03b380724ff1483a3"
+
+PSA Multipart AEAD decrypt, AES - GCM, 144 bytes #1
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":0:"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826"
+
+PSA Multipart AEAD decrypt, AES - GCM, 144 bytes #1 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":1:"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826"
+
+PSA Multipart AEAD decrypt, AES - GCM, 144 bytes #2
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"fe96eab10ff48c7942025422583d0377":PSA_ALG_GCM:"97ce3f848276783599c6875de324361e":"127628b6dcbce6fc8a8ef60798eb67b2088415635119697d20bb878c24d9c6f9c29e148521cb5e0feff892c7855d4f1c0bfb32ad33420976714dce87a0bbc18e4378bd1ef35197d0ca73051148f1199010f63caf122df5f71ad8d9c71df3eb2fbe3b2529d0ba657570358d3776f687bdb9c96d5e0e9e00c4b42d5d7a268d6a08":"12495120056ca3cac70d583603a476821bac6c57c9733b81cfb83538dc9e850f8bdf46065069591c23ebcbc6d1e2523375fb7efc80c09507fa25477ed07cee54fc4eb90168b3ef988f651fc40652474a644b1b311decf899660aef2347bb081af48950f06ebf799911e37120de94c55c20e5f0a77119be06e2b6e557f872fa0f6bac793bdc2190a195122c98544ccf56":0:"194c8bbbfae4a671386b8cd38f390f46f9df6b8661b470c310921a1c858a938045834bb10380037fbf5f5e00688554537be0fcafe8270b9b59068fa056ab1268fc166c2d729243a06650a171c929c7845c85330c04568d62977eedf3b1ba9dca13bdb8f9522817c8cb99e635e37465ec1c9f6f148d51437aa9f994a62e1bd013"
+
+PSA Multipart AEAD decrypt, AES - GCM, 144 bytes #2 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"fe96eab10ff48c7942025422583d0377":PSA_ALG_GCM:"97ce3f848276783599c6875de324361e":"127628b6dcbce6fc8a8ef60798eb67b2088415635119697d20bb878c24d9c6f9c29e148521cb5e0feff892c7855d4f1c0bfb32ad33420976714dce87a0bbc18e4378bd1ef35197d0ca73051148f1199010f63caf122df5f71ad8d9c71df3eb2fbe3b2529d0ba657570358d3776f687bdb9c96d5e0e9e00c4b42d5d7a268d6a08":"12495120056ca3cac70d583603a476821bac6c57c9733b81cfb83538dc9e850f8bdf46065069591c23ebcbc6d1e2523375fb7efc80c09507fa25477ed07cee54fc4eb90168b3ef988f651fc40652474a644b1b311decf899660aef2347bb081af48950f06ebf799911e37120de94c55c20e5f0a77119be06e2b6e557f872fa0f6bac793bdc2190a195122c98544ccf56":1:"194c8bbbfae4a671386b8cd38f390f46f9df6b8661b470c310921a1c858a938045834bb10380037fbf5f5e00688554537be0fcafe8270b9b59068fa056ab1268fc166c2d729243a06650a171c929c7845c85330c04568d62977eedf3b1ba9dca13bdb8f9522817c8cb99e635e37465ec1c9f6f148d51437aa9f994a62e1bd013"
+
+PSA Multipart AEAD decrypt, AES - GCM, 144 bytes, T = 4
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,4):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847f":0:"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826"
+
+PSA Multipart AEAD decrypt, AES - GCM, 144 bytes, T = 4 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,4):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847f":1:"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826"
+
+PSA Multipart AEAD decrypt, AES - GCM, 144 bytes, T = 15
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,15):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a":0:"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826"
+
+PSA Multipart AEAD decrypt, AES - GCM, 144 bytes, T = 15 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,15):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a":1:"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826"
+
+PSA Multipart AEAD decrypt, AES-GCM, 144 bytes, T=16
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":0:"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826"
+
+PSA Multipart AEAD decrypt, AES-GCM, 144 bytes, T=16 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":1:"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=24, IV=12, IN=0, AAD=0, TAG=16
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"0e5d6e68f82f32bea3f0b69498c1a31ef6d955cd3d27a2a8":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"caf72ee1e62e1001e8cfbc63":"":"db1a74ffb5f7de26f5742e0942b1b9cb":0:""
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=24, IV=12, IN=0, AAD=0, TAG=16 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"0e5d6e68f82f32bea3f0b69498c1a31ef6d955cd3d27a2a8":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"caf72ee1e62e1001e8cfbc63":"":"db1a74ffb5f7de26f5742e0942b1b9cb":1:""
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=24, IV=12, IN=0, AAD=48, TAG=14
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"e79fb7defce4f650402e6b521170686d3eb2a0b9514f3a64":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 14 ):"40e0d2d836c0519e7042419b":"41c5b5d971c0723bc1b63a259fe7e06c2961de1241bc34c13965f43636e4da3da8c75ed5956abe3a42f3039af005925a":"434ff68f2436f48418fd69f52158":0:""
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=24, IV=12, IN=0, AAD=48, TAG=14 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"e79fb7defce4f650402e6b521170686d3eb2a0b9514f3a64":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 14 ):"40e0d2d836c0519e7042419b":"41c5b5d971c0723bc1b63a259fe7e06c2961de1241bc34c13965f43636e4da3da8c75ed5956abe3a42f3039af005925a":"434ff68f2436f48418fd69f52158":1:""
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=24, IV=12, IN=16, AAD=0, TAG=15
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"e41d1f533d5b342ffe434b94b1372683bfd5d9d8cb79f9ee":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"5fe11a596dfcd3a305c1d711":"":"1847f64fff986476d1d2f758692f856da4a0ff98c0c1101694c84fd86680c9":0:"b03c2c20f758a93a8d1220232ad87098"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=24, IV=12, IN=16, AAD=0, TAG=15 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"e41d1f533d5b342ffe434b94b1372683bfd5d9d8cb79f9ee":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"5fe11a596dfcd3a305c1d711":"":"1847f64fff986476d1d2f758692f856da4a0ff98c0c1101694c84fd86680c9":1:"b03c2c20f758a93a8d1220232ad87098"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=24, IV=12, IN=16, AAD=20, TAG=15
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"8e7da473c057a2a4669a0d22bf9b7c9913fba48930ca0c9b":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"f9ff8ef80d76c50f9ca0e9ff":"f141bae18a1b54f065554fd34aa02c91c90f505c":"5deb093b6e7c766a64bb9d5170af1ff8bf130b64eebdce06a9bdb2cf1da15a":0:"b22b2dcdcc18adc30d16297b84b459d8"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=24, IV=12, IN=16, AAD=20, TAG=15 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"8e7da473c057a2a4669a0d22bf9b7c9913fba48930ca0c9b":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"f9ff8ef80d76c50f9ca0e9ff":"f141bae18a1b54f065554fd34aa02c91c90f505c":"5deb093b6e7c766a64bb9d5170af1ff8bf130b64eebdce06a9bdb2cf1da15a":1:"b22b2dcdcc18adc30d16297b84b459d8"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=24, IV=12, IN=16, AAD=48, TAG=12
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"01bf150add51bb11623e3bfbebd62a7ea81c5b192b8eb6de":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 12 ):"dfacbc6791b785d324c646b7":"e35412a625324257bef35399a7eacca34fec2d2d24166e6bb3e94d96f5c57599ded45e2a74503f07116caa1692398a07":"77579db3c6da769e17731faac4732d7cce65d960a49f94f6b583e54a":0:"7e5fd8b595ddc4753676107951d900e2"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=24, IV=12, IN=16, AAD=48, TAG=12 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"01bf150add51bb11623e3bfbebd62a7ea81c5b192b8eb6de":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 12 ):"dfacbc6791b785d324c646b7":"e35412a625324257bef35399a7eacca34fec2d2d24166e6bb3e94d96f5c57599ded45e2a74503f07116caa1692398a07":"77579db3c6da769e17731faac4732d7cce65d960a49f94f6b583e54a":1:"7e5fd8b595ddc4753676107951d900e2"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=24, IV=12, IN=16, AAD=48, TAG=8
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"551266c4ed166fe1c43761927801ed50cb9c0b3864fc97df":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 8 ):"e711afbeccd567f866340abb":"562d1697237ebc563941076d459727dfa094eb9ac00d30ed5836825d163dd27517c7660a01056b2d868c7fc5d0343830":"2b54cc27f6ee71882e8b1ead207d2b042d262e87eac97b58":0:"37245449db8f72b1ecdb420f629d3d80"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=24, IV=12, IN=16, AAD=48, TAG=8 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"551266c4ed166fe1c43761927801ed50cb9c0b3864fc97df":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 8 ):"e711afbeccd567f866340abb":"562d1697237ebc563941076d459727dfa094eb9ac00d30ed5836825d163dd27517c7660a01056b2d868c7fc5d0343830":"2b54cc27f6ee71882e8b1ead207d2b042d262e87eac97b58":1:"37245449db8f72b1ecdb420f629d3d80"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=24, IV=12, IN=13, AAD=0, TAG=15
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"78fa4a2a5b5b1b1d9580ea527f2e1653e9336e15cc5462f5":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"98b774f7110e0bea624b487f":"":"a642aabed8b99e15e297ee705a40c3e2e506cb889727b327b7e044a8":0:"496909523f574b205d757659c5"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=24, IV=12, IN=13, AAD=0, TAG=15 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"78fa4a2a5b5b1b1d9580ea527f2e1653e9336e15cc5462f5":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"98b774f7110e0bea624b487f":"":"a642aabed8b99e15e297ee705a40c3e2e506cb889727b327b7e044a8":1:"496909523f574b205d757659c5"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=24, IV=12, IN=13, AAD=16, TAG=15
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"61f4c2e55d729c4657e503dfe2b604e2853675dbdeb0982a":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"0c4d5548aa2d8d54964e1e63":"5affdf8886dabb14790aff3dbfcbdd80":"0d4eacc3db304f46cb7a9eba6ec105bf86d9dc0639b7cebbd5260f47":0:"b6e056de521a27266dffbc0d96"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=24, IV=12, IN=13, AAD=16, TAG=15 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"61f4c2e55d729c4657e503dfe2b604e2853675dbdeb0982a":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"0c4d5548aa2d8d54964e1e63":"5affdf8886dabb14790aff3dbfcbdd80":"0d4eacc3db304f46cb7a9eba6ec105bf86d9dc0639b7cebbd5260f47":1:"b6e056de521a27266dffbc0d96"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=24, IV=12, IN=13, AAD=20, TAG=13
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"73245c4f115a74fe71d6fefb9094c57c75f28033a3c7372b":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 13 ):"536a82485999b93b0bb7ef24":"64dcad870a42eeec0730fd7a7e4154638a85d739":"29333e87bfe65d0e37da2936f695824d4e3f37fab3b8e2b868f6":0:"f6d56f8c86f27d957fa63aea22"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=24, IV=12, IN=13, AAD=20, TAG=13 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"73245c4f115a74fe71d6fefb9094c57c75f28033a3c7372b":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 13 ):"536a82485999b93b0bb7ef24":"64dcad870a42eeec0730fd7a7e4154638a85d739":"29333e87bfe65d0e37da2936f695824d4e3f37fab3b8e2b868f6":1:"f6d56f8c86f27d957fa63aea22"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=24, IV=12, IN=13, AAD=48, TAG=4
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"9002e74638e09dd1f091439518e1460cdd5905bd9e1a37ae":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 4 ):"76c81a95d24be5c8bac63b50":"aa3ae4531aaac8f3eb07f748712c55a680bc8df5cf845edc66d09049500b41688b8023f5746879b45bdd586af29c4ede":"31bf37acbc53ca3fdbc9e5eaaebbb85a7f":0:"bd94b34511bc65ae47684805cb"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=24, IV=12, IN=13, AAD=48, TAG=4 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"9002e74638e09dd1f091439518e1460cdd5905bd9e1a37ae":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 4 ):"76c81a95d24be5c8bac63b50":"aa3ae4531aaac8f3eb07f748712c55a680bc8df5cf845edc66d09049500b41688b8023f5746879b45bdd586af29c4ede":"31bf37acbc53ca3fdbc9e5eaaebbb85a7f":1:"bd94b34511bc65ae47684805cb"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=32, IV=12, IN=0, AAD=0, TAG=16
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"f5a2b27c74355872eb3ef6c5feafaa740e6ae990d9d48c3bd9bb8235e589f010":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"58d2240f580a31c1d24948e9":"":"15e051a5e4a5f5da6cea92e2ebee5bac":0:""
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=32, IV=12, IN=0, AAD=0, TAG=16 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"f5a2b27c74355872eb3ef6c5feafaa740e6ae990d9d48c3bd9bb8235e589f010":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"58d2240f580a31c1d24948e9":"":"15e051a5e4a5f5da6cea92e2ebee5bac":1:""
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=32, IV=12, IN=0, AAD=16, TAG=15
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"3395a1485315c5b5e6353acb05ae9499c440a2e9f5c57494662f827235ea314c":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"3b7e632571602456b49880f0":"f283f80226dacb69c8af089ec6b59e81":"84c8beff4b0d160ee68ac613097f51":0:""
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=32, IV=12, IN=0, AAD=16, TAG=15 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"3395a1485315c5b5e6353acb05ae9499c440a2e9f5c57494662f827235ea314c":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"3b7e632571602456b49880f0":"f283f80226dacb69c8af089ec6b59e81":"84c8beff4b0d160ee68ac613097f51":1:""
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=32, IV=12, IN=0, AAD=20, TAG=15
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"4dc46ca55c1c1fcb4720c274c0e675c2ac5bf93d8dd5e951ca9f6b61f884edc9":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"6473ab77dc885127422f5594":"e2cf8172ab4cf77eba45cd2c8ff939b938080a90":"8d6351f18d873242204c20144e2b83":0:""
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=32, IV=12, IN=0, AAD=20, TAG=15 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"4dc46ca55c1c1fcb4720c274c0e675c2ac5bf93d8dd5e951ca9f6b61f884edc9":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"6473ab77dc885127422f5594":"e2cf8172ab4cf77eba45cd2c8ff939b938080a90":"8d6351f18d873242204c20144e2b83":1:""
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=32, IV=12, IN=0, AAD=48, TAG=14
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"a7f95798434f9a0fe6fd8acd30b8bad96dbdcfacee4594f01cbf26479be7d154":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 14 ):"9ef5a77b02137b46e8461d09":"5595a16fa12d4dcdba6b128480dce2d39c1211c3fb6068cde6013f6a80dfcda5eb92af8879e40ee9c177fd0e446fc8ca":"3bfd3d99fe2063e8ef8255519fe0":0:""
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=32, IV=12, IN=0, AAD=48, TAG=14 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"a7f95798434f9a0fe6fd8acd30b8bad96dbdcfacee4594f01cbf26479be7d154":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 14 ):"9ef5a77b02137b46e8461d09":"5595a16fa12d4dcdba6b128480dce2d39c1211c3fb6068cde6013f6a80dfcda5eb92af8879e40ee9c177fd0e446fc8ca":"3bfd3d99fe2063e8ef8255519fe0":1:""
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=32, IV=12, IN=16, AAD=0, TAG=16
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"4c8ebfe1444ec1b2d503c6986659af2c94fafe945f72c1e8486a5acfedb8a0f8":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"473360e0ad24889959858995":"":"d2c78110ac7e8f107c0df0570bd7c90cc26a379b6d98ef2852ead8ce83a833a7":0:"7789b41cb3ee548814ca0b388c10b343"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=32, IV=12, IN=16, AAD=0, TAG=16 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"4c8ebfe1444ec1b2d503c6986659af2c94fafe945f72c1e8486a5acfedb8a0f8":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 16 ):"473360e0ad24889959858995":"":"d2c78110ac7e8f107c0df0570bd7c90cc26a379b6d98ef2852ead8ce83a833a7":1:"7789b41cb3ee548814ca0b388c10b343"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=32, IV=12, IN=16, AAD=0, TAG=4
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"57805f98aae1b8b64bb49756529ab8181b3ada674a90c55422e9eb26c48bcd7b":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 4 ):"9735945d8ca161777206632a":"":"58375442ab1c0e6a8952c83d128d9fc5f45bb315":0:"4860116a6d2deb9bf794bfd6ac5bbbd6"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=32, IV=12, IN=16, AAD=0, TAG=4 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"57805f98aae1b8b64bb49756529ab8181b3ada674a90c55422e9eb26c48bcd7b":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 4 ):"9735945d8ca161777206632a":"":"58375442ab1c0e6a8952c83d128d9fc5f45bb315":1:"4860116a6d2deb9bf794bfd6ac5bbbd6"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=32, IV=12, IN=16, AAD=16, TAG=8
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"f913bb823a1d0c10b0b72d56866907b893f2266f15de1abc17f93600824db55a":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 8 ):"d4fe686a14592b6ca1bd6b42":"e35d880c1c53688eb83869de9dd8a473":"35af9b502ea6b56269f896bf98affdd59c2aa418b38bc7fd":0:"ff426dd751190ff826e8b4a0792d746e"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=32, IV=12, IN=16, AAD=16, TAG=8 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"f913bb823a1d0c10b0b72d56866907b893f2266f15de1abc17f93600824db55a":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 8 ):"d4fe686a14592b6ca1bd6b42":"e35d880c1c53688eb83869de9dd8a473":"35af9b502ea6b56269f896bf98affdd59c2aa418b38bc7fd":1:"ff426dd751190ff826e8b4a0792d746e"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=32, IV=12, IN=16, AAD=20, TAG=14
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"74e9d9d7cd0728cea94e169af485f21f9d2447e022f16008f803dcf5c4f7cc0c":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 14 ):"ecba39edc96667da726122c0":"ae9ab021f86f5b81bb2e0fcbd4b855e1501e9f82":"e5745ce0e02dbba05363b548c3ac7047eacca7e61db6f72fc9b9e5bdb2bb":0:"0a0b284515694188b6b6c15bc8a09036"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=32, IV=12, IN=16, AAD=20, TAG=14 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"74e9d9d7cd0728cea94e169af485f21f9d2447e022f16008f803dcf5c4f7cc0c":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 14 ):"ecba39edc96667da726122c0":"ae9ab021f86f5b81bb2e0fcbd4b855e1501e9f82":"e5745ce0e02dbba05363b548c3ac7047eacca7e61db6f72fc9b9e5bdb2bb":1:"0a0b284515694188b6b6c15bc8a09036"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=32, IV=12, IN=13, AAD=0, TAG=14
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"60667fce64b8c7169ddf45f335e46951248f69abc4e0f4f292d0ffe3dfd5219f":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 14 ):"1057322a39f08ef761c3c8fc":"":"501b033c841acb430c52d88fe9cb44c751f2f1641d1e801a534ac8":0:"f386b28e7eb4c2fb8eb5dc66a2"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=32, IV=12, IN=13, AAD=0, TAG=14 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"60667fce64b8c7169ddf45f335e46951248f69abc4e0f4f292d0ffe3dfd5219f":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 14 ):"1057322a39f08ef761c3c8fc":"":"501b033c841acb430c52d88fe9cb44c751f2f1641d1e801a534ac8":1:"f386b28e7eb4c2fb8eb5dc66a2"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=32, IV=12, IN=13, AAD=20, TAG=15
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"e67590da399cbcdcddcc56110562ade8665b50287a8ab38e8b9ee7520531b560":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"2c36ab6b686a66fba1805196":"823493d42f4f60b2d1433ad75eccaafd7e7c7d12":"cff6b6f03c67152f3ce1030653d9bd9a6559f5b04b48d77c2a1fc364":0:"da1c61fbfcdb73445ad4c7d889"
+
+PSA Multipart AEAD decrypt, CAVS14.0, AES-GCM, KEY=32, IV=12, IN=13, AAD=20, TAG=15 (lengths set)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_decrypt:PSA_KEY_TYPE_AES:"e67590da399cbcdcddcc56110562ade8665b50287a8ab38e8b9ee7520531b560":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 15 ):"2c36ab6b686a66fba1805196":"823493d42f4f60b2d1433ad75eccaafd7e7c7d12":"cff6b6f03c67152f3ce1030653d9bd9a6559f5b04b48d77c2a1fc364":1:"da1c61fbfcdb73445ad4c7d889"
+
+PSA Multipart AEAD encrypt: ChaCha20-Poly1305 (RFC7539)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_encrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":0:"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd0600691"
+
+PSA Multipart AEAD encrypt: ChaCha20-Poly1305 (RFC7539) (lengths set)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_encrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":1:"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd0600691"
+
+PSA Multipart AEAD encrypt: ChaCha20-Poly1305 (zero-length input)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_encrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"070000004041424344454647":"":"":0:"a0784d7a4716f3feb4f64e7f4b39bf04"
+
+PSA Multipart AEAD encrypt: ChaCha20-Poly1305 (zero-length input) (lengths set)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_encrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"070000004041424344454647":"":"":1:"a0784d7a4716f3feb4f64e7f4b39bf04"
+
+PSA Multipart AEAD decrypt: ChaCha20 - Poly1305 (RFC7539, good tag)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd0600691":0:"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e"
+
+PSA Multipart AEAD decrypt: ChaCha20 - Poly1305 (RFC7539, good tag) (lengths set)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd0600691":1:"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e"
+
+PSA Multipart AEAD decrypt: ChaCha20 - Poly1305 (good tag, zero - length input)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"070000004041424344454647":"":"a0784d7a4716f3feb4f64e7f4b39bf04":0:""
+
+PSA Multipart AEAD decrypt: ChaCha20 - Poly1305 (good tag, zero - length input) (lengths set)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"070000004041424344454647":"":"a0784d7a4716f3feb4f64e7f4b39bf04":1:""
+
+PSA Multipart AEAD verify, AES - GCM, invalid signature
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_verify:PSA_KEY_TYPE_AES:"fe96eab10ff48c7942025422583d0377":PSA_ALG_GCM:"97ce3f848276783599c6875de324361e":"127628b6dcbce6fc8a8ef60798eb67b2088415635119697d20bb878c24d9c6f9c29e148521cb5e0feff892c7855d4f1c0bfb32ad33420976714dce87a0bbc18e4378bd1ef35197d0ca73051148f1199010f63caf122df5f71ad8d9c71df3eb2fbe3b2529d0ba657570358d3776f687bdb9c96d5e0e9e00c4b42d5d7a268d6a08":"12195120056ca3cac70d583603a476821bac6c57c9733b81cfb83538dc9e850f8bdf46065069591c23ebcbc6d1e2523375fb7efc80c09507fa25477ed07cee54fc4eb90168b3ef988f651fc40652474a644b1b311decf899660aef2347bb081af48950f06ebf799911e37120de94c55c20e5f0a77119be06e2b6e557f872fa0f":"6bac793bdc2190a195122c98544ccf56":1:PSA_ERROR_INVALID_SIGNATURE
+
+PSA Multipart AEAD verify, AES - GCM, T = 15 but passing 16 bytes
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_verify:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,15):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c87281":"4365847fe0b7b7fbed325953df344a96":1:PSA_ERROR_INVALID_SIGNATURE
+
+PSA Multipart AEAD verify, AES - GCM, T = 15 but passing 14 bytes
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_verify:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,15):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c87281":"4365847fe0b7b7fbed325953df34":1:PSA_ERROR_INVALID_SIGNATURE
+
+PSA Multipart AEAD verify, AES - GCM, T = 15 but passing 0 bytes (valid buffer)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_verify:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,15):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c87281":"":1:PSA_ERROR_INVALID_SIGNATURE
+
+PSA Multipart AEAD verify, AES - GCM, T = 15 but passing 0 bytes (NULL buffer)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_verify:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,15):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c87281":"":0:PSA_ERROR_INVALID_SIGNATURE
+
+PSA Multipart AEAD verify: AES - GCM, invalid tag length 0
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_verify:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,0):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"":1:PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart AEAD verify: AES - GCM, invalid tag length 2
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_verify:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,2):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd":"10b6":1:PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart AEAD verify: ChaCha20 - Poly1305 (RFC7539, bad tag)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_verify:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"1ae10b594f09e26a7e902ecbd0600690":1:PSA_ERROR_INVALID_SIGNATURE
+
+PSA Multipart Nonce Generation, AES - GCM, NONCE = (Req 12 / Expect 12)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_generate_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_GCM:12:12:"290322092d57479e20f6281e331d95a9":"e7fb0631eebf9bdba87045b33650c4ce":PSA_SUCCESS
+
+PSA Multipart Nonce Generation, AES - GCM, NONCE = (Req 11 / Expect 0)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_generate_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_GCM:11:0:"290322092d57479e20f6281e331d95a9":"e7fb0631eebf9bdba87045b33650c4ce":PSA_ERROR_BUFFER_TOO_SMALL
+
+PSA Multipart Nonce Generation, AES - GCM, NONCE = (Req 0 / Expect 0)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_generate_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_GCM:0:0:"":"":PSA_ERROR_BUFFER_TOO_SMALL
+
+PSA Multipart Nonce Generation, AES - GCM, NONCE = (Req 16 / Expect 12)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_generate_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_GCM:16:12:"290322092d57479e20f6281e331d95a9":"e7fb0631eebf9bdba87045b33650c4ce":PSA_SUCCESS
+
+PSA Multipart Nonce Generation: ChaCha20 - Poly1305, NONCE = (Req 12 / Expect 12)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_generate_nonce:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:12:12:"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":PSA_SUCCESS
+
+PSA Multipart Nonce Generation: ChaCha20 - Poly1305, NONCE = (Req 11 / Expect 0)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_generate_nonce:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:11:0:"":"":PSA_ERROR_BUFFER_TOO_SMALL
+
+PSA Multipart Nonce Generation: ChaCha20 - Poly1305, NONCE = (Req 0 / Expect 0)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_generate_nonce:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:0:0:"":"":PSA_ERROR_BUFFER_TOO_SMALL
+
+PSA Multipart Nonce Generation: ChaCha20 - Poly1305, NONCE = (Req 16 / Expect 12)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_generate_nonce:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:16:12:"":"":PSA_SUCCESS
+
+PSA Multipart Set Nonce, AES - GCM, NONCE = 0 (NULL)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_GCM:0:"":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce, AES - GCM, NONCE = 0 (Non-NULL)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_GCM:-1:"":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce, AES - GCM, NONCE = 16
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_GCM:16:"290322092d57479e20f6281e331d95a9":"e7fb0631eebf9bdba87045b33650c4ce":PSA_SUCCESS
+
+PSA Multipart Set Nonce, AES - GCM, NONCE = 20
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_GCM:20:"290322092d57479e20f6281e331d95a9":"e7fb0631eebf9bdba87045b33650c4ce":PSA_SUCCESS
+
+PSA Multipart Set Nonce, AES - GCM_12, NONCE = 0 (NULL)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,12):0:"":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce, AES - GCM_12, NONCE = 0 (Non-NULL)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,12):-1:"":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce, AES - GCM_12, NONCE = 16
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,12):16:"290322092d57479e20f6281e331d95a9":"e7fb0631eebf9bdba87045b33650c4ce":PSA_SUCCESS
+
+PSA Multipart Set Nonce, AES - GCM_12, NONCE = 20
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,12):20:"290322092d57479e20f6281e331d95a9":"e7fb0631eebf9bdba87045b33650c4ce":PSA_SUCCESS
+
+PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 11
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_set_nonce:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:11:"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 12
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_set_nonce:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:12:"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":PSA_SUCCESS
+
+PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 13
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_set_nonce:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:13:"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 0 (NULL)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_set_nonce:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:0:"":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 0 (Non-NULL)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_set_nonce:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:-1:"":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD output buffer test: AES - GCM, IN = 16, BUF = 15
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_update_buffer_test:PSA_KEY_TYPE_AES:"fbc0b4c56a714c83217b2d1bcadd2ed2e9efb0dcac6cc19f":PSA_ALG_GCM:15:"5f4b43e811da9c470d6a9b01":"":"d2ae38c4375954835d75b8e4c2f9bbb4":PSA_ERROR_BUFFER_TOO_SMALL
+
+PSA AEAD output buffer test: AES - GCM, IN = 16, BUF = 0
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_update_buffer_test:PSA_KEY_TYPE_AES:"fbc0b4c56a714c83217b2d1bcadd2ed2e9efb0dcac6cc19f":PSA_ALG_GCM:0:"5f4b43e811da9c470d6a9b01":"":"d2ae38c4375954835d75b8e4c2f9bbb4":PSA_ERROR_BUFFER_TOO_SMALL
+
+PSA AEAD output buffer test: ChaCha20 - Poly1305 IN = 130, BUF = 129
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_update_buffer_test:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:129:"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd0600691":PSA_ERROR_BUFFER_TOO_SMALL
+
+PSA AEAD output buffer test: ChaCha20 - Poly1305 IN = 130, BUF = 0
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_update_buffer_test:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:0:"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd0600691":PSA_ERROR_BUFFER_TOO_SMALL
+
+PSA AEAD finish buffer test: AES - GCM, BUF = 8, TAG = 16
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_finish_buffer_test:PSA_KEY_TYPE_AES:"fbc0b4c56a714c83217b2d1bcadd2ed2e9efb0dcac6cc19f":PSA_ALG_GCM:8:16:"5f4b43e811da9c470d6a9b01":"":"d2ae38c4375954835d75b8e4c2f9bbb4":PSA_ERROR_BUFFER_TOO_SMALL
+
+PSA AEAD finish buffer test: AES - GCM, BUF = 15, TAG = 20
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_finish_buffer_test:PSA_KEY_TYPE_AES:"fbc0b4c56a714c83217b2d1bcadd2ed2e9efb0dcac6cc19f":PSA_ALG_GCM:15:20:"5f4b43e811da9c470d6a9b01":"":"d2ae38c4375954835d75b8e4c2f9bbb4":PSA_SUCCESS
+
+PSA AEAD finish buffer test: AES - GCM, BUF = 15, TAG = 15
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_finish_buffer_test:PSA_KEY_TYPE_AES:"fbc0b4c56a714c83217b2d1bcadd2ed2e9efb0dcac6cc19f":PSA_ALG_GCM:15:15:"5f4b43e811da9c470d6a9b01":"":"d2ae38c4375954835d75b8e4c2f9bbb4":PSA_ERROR_BUFFER_TOO_SMALL
+
+PSA AEAD finish buffer test: AES - GCM, BUF = 15, TAG = 0
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_finish_buffer_test:PSA_KEY_TYPE_AES:"fbc0b4c56a714c83217b2d1bcadd2ed2e9efb0dcac6cc19f":PSA_ALG_GCM:15:0:"5f4b43e811da9c470d6a9b01":"":"d2ae38c4375954835d75b8e4c2f9bbb4":PSA_ERROR_BUFFER_TOO_SMALL
+
+PSA AEAD finish buffer test: ChaCha20 - Poly1305, BUF = 0, TAG = 20
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_finish_buffer_test:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:0:20:"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd0600691":PSA_SUCCESS
+
+PSA AEAD finish buffer test: ChaCha20 - Poly1305, BUF = 0, TAG = 15
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_finish_buffer_test:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:0:15:"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd0600691":PSA_ERROR_BUFFER_TOO_SMALL
+
+PSA AEAD finish buffer test: ChaCha20 - Poly1305, BUF = 0, TAG = 0
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_finish_buffer_test:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:0:0:"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd0600691":PSA_ERROR_BUFFER_TOO_SMALL
+
+PSA AEAD setup: invalid algorithm (CTR)
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
+aead_multipart_setup:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CTR:PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: invalid algorithm (ChaCha20)
+depends_on:PSA_WANT_ALG_STREAM_CIPHER:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_setup:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_STREAM_CIPHER:PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: invalid algorithm (ChaCha20 - Poly1305 with short tag)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_setup:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305,12):PSA_ERROR_NOT_SUPPORTED
+
+PSA Multipart State Checks, AES - GCM
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_state_test:PSA_KEY_TYPE_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":PSA_ALG_GCM:"000102030405060708090A0B0C0D0E0F":"000102030405060708090A0B":"0C0D0E0F101112131415161718191A1B1C1D1E"
+
 PSA signature size: RSA keypair, 1024 bits, PKCS#1 v1.5 raw
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
 signature_size:PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:128
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 01e5d59..591c296 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -278,6 +278,316 @@
     DERIVE_KEY = 2
 } generate_method;
 
+typedef enum
+{
+    DO_NOT_SET_LENGTHS = 0,
+    SET_LENGTHS_BEFORE_NONCE = 1,
+    SET_LENGTHS_AFTER_NONCE = 2
+} set_lengths_method_t;
+
+typedef enum
+{
+    USE_NULL_TAG = 0,
+    USE_GIVEN_TAG = 1,
+} tag_usage_method_t;
+
+/*!
+ * \brief                           Internal Function for AEAD multipart tests.
+ * \param key_type_arg              Type of key passed in
+ * \param key_data                  The encryption / decryption key data
+ * \param alg_arg                   The type of algorithm used
+ * \param nonce                     Nonce data
+ * \param additional_data           Additional data
+ * \param ad_part_len_arg           If not -1, the length of chunks to
+ *                                  feed additional data in to be encrypted /
+ *                                  decrypted. If -1, no chunking.
+ * \param input_data                Data to encrypt / decrypt
+ * \param data_part_len_arg         If not -1, the length of chunks to feed
+ *                                  the data in to be encrypted / decrypted. If
+ *                                  -1, no chunking
+ * \param set_lengths_method        A member of the set_lengths_method_t enum is
+ *                                  expected here, this controls whether or not
+ *                                  to set lengths, and in what order with
+ *                                  respect to set nonce.
+ * \param expected_output           Expected output
+ * \param is_encrypt                If non-zero this is an encryption operation.
+ * \param do_zero_parts             If non-zero, interleave zero length chunks
+ *                                  with normal length chunks.
+ * \return int                      Zero on failure, non-zero on success.
+ */
+static int aead_multipart_internal_func( int key_type_arg, data_t *key_data,
+                                         int alg_arg,
+                                         data_t *nonce,
+                                         data_t *additional_data,
+                                         int ad_part_len_arg,
+                                         data_t *input_data,
+                                         int data_part_len_arg,
+                                         set_lengths_method_t set_lengths_method,
+                                         data_t *expected_output,
+                                         int is_encrypt,
+                                         int do_zero_parts )
+{
+    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
+    unsigned char *output_data = NULL;
+    unsigned char *part_data = NULL;
+    unsigned char *final_data = NULL;
+    size_t data_true_size = 0;
+    size_t part_data_size = 0;
+    size_t output_size = 0;
+    size_t final_output_size = 0;
+    size_t output_length = 0;
+    size_t key_bits = 0;
+    size_t tag_length = 0;
+    size_t part_offset = 0;
+    size_t part_length = 0;
+    size_t output_part_length = 0;
+    size_t tag_size = 0;
+    size_t ad_part_len = 0;
+    size_t data_part_len = 0;
+    uint8_t tag_buffer[PSA_AEAD_TAG_MAX_SIZE];
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_status_t status = PSA_ERROR_GENERIC_ERROR;
+
+    int test_ok = 0;
+    size_t part_count = 0;
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    if( is_encrypt )
+        psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT  );
+    else
+        psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT  );
+
+    psa_set_key_algorithm( &attributes, alg );
+    psa_set_key_type( &attributes, key_type );
+
+    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
+                                &key ) );
+
+    PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
+    key_bits = psa_get_key_bits( &attributes );
+
+    tag_length = PSA_AEAD_TAG_LENGTH( key_type, key_bits, alg );
+
+    if( is_encrypt )
+    {
+        /* Tag gets written at end of buffer. */
+        output_size = PSA_AEAD_UPDATE_OUTPUT_SIZE( key_type, alg,
+                                                   ( input_data->len +
+                                                    tag_length ) );
+        data_true_size = input_data->len;
+    }
+    else
+    {
+        output_size = PSA_AEAD_UPDATE_OUTPUT_SIZE( key_type, alg,
+                                                   ( input_data->len -
+                                                    tag_length ) );
+
+        /* Do not want to attempt to decrypt tag. */
+        data_true_size = input_data->len - tag_length;
+    }
+
+    ASSERT_ALLOC( output_data, output_size );
+
+    if( is_encrypt )
+    {
+        final_output_size = PSA_AEAD_FINISH_OUTPUT_SIZE( key_type, alg );
+        TEST_ASSERT( final_output_size <= PSA_AEAD_FINISH_OUTPUT_MAX_SIZE );
+    }
+    else
+    {
+        final_output_size = PSA_AEAD_VERIFY_OUTPUT_SIZE( key_type, alg );
+        TEST_ASSERT( final_output_size <= PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE );
+    }
+
+    ASSERT_ALLOC( final_data, final_output_size );
+
+    if( is_encrypt )
+        status = psa_aead_encrypt_setup( &operation, key, alg );
+    else
+        status = psa_aead_decrypt_setup( &operation, key, alg );
+
+    /* If the operation is not supported, just skip and not fail in case the
+     * encryption involves a common limitation of cryptography hardwares and
+     * an alternative implementation. */
+    if( status == PSA_ERROR_NOT_SUPPORTED )
+    {
+        MBEDTLS_TEST_PSA_SKIP_IF_ALT_AES_192( key_type, key_data->len * 8 );
+        MBEDTLS_TEST_PSA_SKIP_IF_ALT_GCM_NOT_12BYTES_NONCE( alg, nonce->len );
+    }
+
+    PSA_ASSERT( status );
+
+    if( set_lengths_method ==  DO_NOT_SET_LENGTHS )
+        PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+    else if( set_lengths_method == SET_LENGTHS_BEFORE_NONCE )
+    {
+        PSA_ASSERT( psa_aead_set_lengths( &operation, additional_data->len,
+                                          data_true_size ) );
+        PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+    }
+    else if( set_lengths_method ==  SET_LENGTHS_AFTER_NONCE )
+    {
+        PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+        PSA_ASSERT( psa_aead_set_lengths( &operation, additional_data->len,
+                                          data_true_size ) );
+    }
+
+    if( ad_part_len_arg != -1 )
+    {
+        /* Pass additional data in parts */
+        ad_part_len = (size_t) ad_part_len_arg;
+
+        for( part_offset = 0, part_count = 0;
+             part_offset < additional_data->len;
+             part_offset += part_length, part_count++ )
+        {
+            if( do_zero_parts && ( part_count & 0x01 ) )
+            {
+                part_length = 0;
+            }
+            else if( additional_data->len - part_offset < ad_part_len )
+            {
+                part_length = additional_data->len - part_offset;
+            }
+            else
+            {
+                part_length = ad_part_len;
+            }
+
+            PSA_ASSERT( psa_aead_update_ad( &operation,
+                                            additional_data->x + part_offset,
+                                            part_length ) );
+
+        }
+    }
+    else
+    {
+        /* Pass additional data in one go. */
+        PSA_ASSERT( psa_aead_update_ad( &operation, additional_data->x,
+                                        additional_data->len ) );
+    }
+
+    if( data_part_len_arg != -1 )
+    {
+        /* Pass data in parts */
+        data_part_len = ( size_t ) data_part_len_arg;
+        part_data_size = PSA_AEAD_UPDATE_OUTPUT_SIZE( key_type, alg,
+                                                      ( size_t ) data_part_len );
+
+        ASSERT_ALLOC( part_data, part_data_size );
+
+        for( part_offset = 0, part_count = 0;
+             part_offset < data_true_size;
+             part_offset += part_length, part_count++ )
+        {
+            if( do_zero_parts && ( part_count & 0x01 ) )
+            {
+                part_length = 0;
+            }
+            else if( ( data_true_size - part_offset ) < data_part_len )
+            {
+                part_length = ( data_true_size - part_offset );
+            }
+            else
+            {
+                part_length = data_part_len;
+            }
+
+            PSA_ASSERT( psa_aead_update( &operation,
+                                         ( input_data->x + part_offset ),
+                                         part_length, part_data,
+                                         part_data_size,
+                                         &output_part_length ) );
+
+            if( output_data && output_part_length )
+            {
+                memcpy( ( output_data + part_offset ), part_data,
+                        output_part_length );
+            }
+
+            output_length += output_part_length;
+        }
+    }
+    else
+    {
+        /* Pass all data in one go. */
+        PSA_ASSERT( psa_aead_update( &operation, input_data->x,
+                                     data_true_size, output_data,
+                                     output_size, &output_length ) );
+    }
+
+    if( is_encrypt )
+        PSA_ASSERT( psa_aead_finish( &operation, final_data,
+                                     final_output_size,
+                                     &output_part_length,
+                                     tag_buffer, tag_length,
+                                     &tag_size ) );
+    else
+    {
+        PSA_ASSERT( psa_aead_verify( &operation, final_data,
+                                     final_output_size,
+                                     &output_part_length,
+                                     ( input_data->x + data_true_size ),
+                                     tag_length ) );
+    }
+
+    if( output_data && output_part_length )
+        memcpy( ( output_data + output_length ), final_data,
+                output_part_length );
+
+    output_length += output_part_length;
+
+
+    /* For all currently defined algorithms, PSA_AEAD_xxx_OUTPUT_SIZE
+     * should be exact.*/
+    if( is_encrypt )
+    {
+        TEST_EQUAL( tag_length, tag_size );
+
+        if( output_data && tag_length )
+            memcpy( ( output_data + output_length ), tag_buffer,
+                    tag_length );
+
+        output_length += tag_length;
+
+        TEST_EQUAL( output_length,
+                      PSA_AEAD_ENCRYPT_OUTPUT_SIZE( key_type, alg,
+                                                    input_data->len ) );
+        TEST_ASSERT( output_length <=
+                      PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE( input_data->len ) );
+    }
+    else
+    {
+       TEST_EQUAL( output_length,
+                      PSA_AEAD_DECRYPT_OUTPUT_SIZE( key_type, alg,
+                                                    input_data->len ) );
+       TEST_ASSERT( output_length <=
+                      PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE( input_data->len ) );
+    }
+
+
+    ASSERT_COMPARE( expected_output->x, expected_output->len,
+                    output_data, output_length );
+
+
+    test_ok = 1;
+
+exit:
+    psa_destroy_key( key );
+    psa_aead_abort( &operation );
+    mbedtls_free( output_data );
+    mbedtls_free( part_data );
+    mbedtls_free( final_data );
+    PSA_DONE( );
+
+    return( test_ok );
+}
+
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
@@ -3474,6 +3784,1209 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void aead_multipart_encrypt( int key_type_arg, data_t *key_data,
+                             int alg_arg,
+                             data_t *nonce,
+                             data_t *additional_data,
+                             data_t *input_data,
+                             int do_set_lengths,
+                             data_t *expected_output )
+{
+    size_t ad_part_len = 0;
+    size_t data_part_len = 0;
+    set_lengths_method_t set_lengths_method = DO_NOT_SET_LENGTHS;
+
+    for( ad_part_len = 1; ad_part_len <= additional_data->len; ad_part_len++ )
+    {
+        mbedtls_test_set_step( ad_part_len );
+
+        if( do_set_lengths )
+        {
+            if( ad_part_len & 0x01 )
+                set_lengths_method = SET_LENGTHS_AFTER_NONCE;
+            else
+                set_lengths_method = SET_LENGTHS_BEFORE_NONCE;
+        }
+
+        /* Split ad into length(ad_part_len) parts. */
+        if( !aead_multipart_internal_func( key_type_arg, key_data,
+                                           alg_arg, nonce,
+                                           additional_data,
+                                           ad_part_len,
+                                           input_data, -1,
+                                           set_lengths_method,
+                                           expected_output,
+                                           1, 0 ) )
+            break;
+
+        /* length(0) part, length(ad_part_len) part, length(0) part... */
+        mbedtls_test_set_step( 1000 + ad_part_len );
+
+        if( !aead_multipart_internal_func( key_type_arg, key_data,
+                                           alg_arg, nonce,
+                                           additional_data,
+                                           ad_part_len,
+                                           input_data, -1,
+                                           set_lengths_method,
+                                           expected_output,
+                                           1, 1 ) )
+            break;
+    }
+
+    for( data_part_len = 1; data_part_len <= input_data->len; data_part_len++ )
+    {
+        /* Split data into length(data_part_len) parts. */
+        mbedtls_test_set_step( 2000 + data_part_len );
+
+        if( do_set_lengths )
+        {
+            if( data_part_len & 0x01 )
+                set_lengths_method = SET_LENGTHS_AFTER_NONCE;
+            else
+                set_lengths_method = SET_LENGTHS_BEFORE_NONCE;
+        }
+
+        if( !aead_multipart_internal_func( key_type_arg, key_data,
+                                           alg_arg, nonce,
+                                           additional_data, -1,
+                                           input_data, data_part_len,
+                                           set_lengths_method,
+                                           expected_output,
+                                           1, 0 ) )
+            break;
+
+        /* length(0) part, length(data_part_len) part, length(0) part... */
+        mbedtls_test_set_step( 3000 + data_part_len );
+
+        if( !aead_multipart_internal_func( key_type_arg, key_data,
+                                           alg_arg, nonce,
+                                           additional_data, -1,
+                                           input_data, data_part_len,
+                                           set_lengths_method,
+                                           expected_output,
+                                           1, 1 ) )
+            break;
+    }
+
+    /* Goto is required to silence warnings about unused labels, as we
+     * don't actually do any test assertions in this function. */
+    goto exit;
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void aead_multipart_decrypt( int key_type_arg, data_t *key_data,
+                             int alg_arg,
+                             data_t *nonce,
+                             data_t *additional_data,
+                             data_t *input_data,
+                             int do_set_lengths,
+                             data_t *expected_output )
+{
+    size_t ad_part_len = 0;
+    size_t data_part_len = 0;
+    set_lengths_method_t set_lengths_method = DO_NOT_SET_LENGTHS;
+
+    for( ad_part_len = 1; ad_part_len <= additional_data->len; ad_part_len++ )
+    {
+        /* Split ad into length(ad_part_len) parts. */
+        mbedtls_test_set_step( ad_part_len );
+
+        if( do_set_lengths )
+        {
+            if( ad_part_len & 0x01 )
+                set_lengths_method = SET_LENGTHS_AFTER_NONCE;
+            else
+                set_lengths_method = SET_LENGTHS_BEFORE_NONCE;
+        }
+
+        if( !aead_multipart_internal_func( key_type_arg, key_data,
+                                           alg_arg, nonce,
+                                           additional_data,
+                                           ad_part_len,
+                                           input_data, -1,
+                                           set_lengths_method,
+                                           expected_output,
+                                           0, 0 ) )
+            break;
+
+        /* length(0) part, length(ad_part_len) part, length(0) part... */
+        mbedtls_test_set_step( 1000 + ad_part_len );
+
+        if( !aead_multipart_internal_func( key_type_arg, key_data,
+                                           alg_arg, nonce,
+                                           additional_data,
+                                           ad_part_len,
+                                           input_data, -1,
+                                           set_lengths_method,
+                                           expected_output,
+                                           0, 1 ) )
+            break;
+    }
+
+    for( data_part_len = 1; data_part_len <= input_data->len; data_part_len++ )
+    {
+        /* Split data into length(data_part_len) parts. */
+        mbedtls_test_set_step( 2000 + data_part_len );
+
+        if( do_set_lengths )
+        {
+            if( data_part_len & 0x01 )
+                set_lengths_method = SET_LENGTHS_AFTER_NONCE;
+            else
+                set_lengths_method = SET_LENGTHS_BEFORE_NONCE;
+        }
+
+        if( !aead_multipart_internal_func( key_type_arg, key_data,
+                                           alg_arg, nonce,
+                                           additional_data, -1,
+                                           input_data, data_part_len,
+                                           set_lengths_method,
+                                           expected_output,
+                                           0, 0 ) )
+            break;
+
+        /* length(0) part, length(data_part_len) part, length(0) part... */
+        mbedtls_test_set_step( 3000 + data_part_len );
+
+        if( !aead_multipart_internal_func( key_type_arg, key_data,
+                                           alg_arg, nonce,
+                                           additional_data, -1,
+                                           input_data, data_part_len,
+                                           set_lengths_method,
+                                           expected_output,
+                                           0, 1 ) )
+            break;
+    }
+
+    /* Goto is required to silence warnings about unused labels, as we
+     * don't actually do any test assertions in this function. */
+    goto exit;
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void aead_multipart_generate_nonce( int key_type_arg, data_t *key_data,
+                                    int alg_arg,
+                                    int nonce_length,
+                                    int expected_nonce_length_arg,
+                                    data_t *additional_data,
+                                    data_t *input_data,
+                                    int expected_status_arg )
+{
+
+    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
+    uint8_t nonce_buffer[PSA_AEAD_NONCE_MAX_SIZE];
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_status_t status = PSA_ERROR_GENERIC_ERROR;
+    psa_status_t expected_status = expected_status_arg;
+    size_t actual_nonce_length = 0;
+    size_t expected_nonce_length = expected_nonce_length_arg;
+    unsigned char *output = NULL;
+    unsigned char *ciphertext = NULL;
+    size_t output_size = 0;
+    size_t ciphertext_size = 0;
+    size_t ciphertext_length = 0;
+    size_t tag_length = 0;
+    uint8_t tag_buffer[PSA_AEAD_TAG_MAX_SIZE];
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    psa_set_key_usage_flags( & attributes, PSA_KEY_USAGE_ENCRYPT  );
+    psa_set_key_algorithm( & attributes, alg );
+    psa_set_key_type( & attributes, key_type );
+
+    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
+                                &key ) );
+
+    PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
+
+    output_size = PSA_AEAD_UPDATE_OUTPUT_SIZE( key_type, alg, input_data->len );
+
+    ASSERT_ALLOC( output, output_size );
+
+    ciphertext_size = PSA_AEAD_FINISH_OUTPUT_SIZE( key_type, alg );
+
+    TEST_ASSERT( ciphertext_size <= PSA_AEAD_FINISH_OUTPUT_MAX_SIZE );
+
+    ASSERT_ALLOC( ciphertext, ciphertext_size );
+
+    status = psa_aead_encrypt_setup( &operation, key, alg );
+
+    /* If the operation is not supported, just skip and not fail in case the
+     * encryption involves a common limitation of cryptography hardwares and
+     * an alternative implementation. */
+    if( status == PSA_ERROR_NOT_SUPPORTED )
+    {
+        MBEDTLS_TEST_PSA_SKIP_IF_ALT_AES_192( key_type, key_data->len * 8 );
+        MBEDTLS_TEST_PSA_SKIP_IF_ALT_GCM_NOT_12BYTES_NONCE( alg, nonce_length );
+    }
+
+    PSA_ASSERT( status );
+
+    status = psa_aead_generate_nonce( &operation, nonce_buffer,
+                                      nonce_length,
+                                      &actual_nonce_length );
+
+    TEST_EQUAL( status, expected_status );
+
+    TEST_EQUAL( actual_nonce_length, expected_nonce_length );
+
+    if( expected_status == PSA_SUCCESS )
+        TEST_EQUAL( actual_nonce_length, PSA_AEAD_NONCE_LENGTH( key_type,
+                                                                alg ) );
+
+    TEST_ASSERT( actual_nonce_length < PSA_AEAD_NONCE_MAX_SIZE );
+
+    if( expected_status == PSA_SUCCESS )
+    {
+
+        /* Ensure we can still complete operation. */
+
+        PSA_ASSERT( psa_aead_update_ad( &operation, additional_data->x,
+                                        additional_data->len ) );
+
+        PSA_ASSERT( psa_aead_update( &operation, input_data->x, input_data->len,
+                                     output, output_size,
+                                     &ciphertext_length ) );
+
+        PSA_ASSERT( psa_aead_finish( &operation, ciphertext, ciphertext_size,
+                                     &ciphertext_length, tag_buffer,
+                                     PSA_AEAD_TAG_MAX_SIZE, &tag_length ) );
+    }
+
+exit:
+    psa_destroy_key( key );
+    mbedtls_free( output );
+    mbedtls_free( ciphertext );
+    psa_aead_abort( &operation );
+    PSA_DONE( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void aead_multipart_set_nonce( int key_type_arg, data_t *key_data,
+                               int alg_arg,
+                               int nonce_length_arg,
+                               data_t *additional_data,
+                               data_t *input_data,
+                               int expected_status_arg )
+{
+
+    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
+    uint8_t *nonce_buffer = NULL;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_status_t status = PSA_ERROR_GENERIC_ERROR;
+    psa_status_t expected_status = expected_status_arg;
+    unsigned char *output = NULL;
+    unsigned char *ciphertext = NULL;
+    size_t nonce_length;
+    size_t output_size = 0;
+    size_t ciphertext_size = 0;
+    size_t ciphertext_length = 0;
+    size_t tag_length = 0;
+    uint8_t tag_buffer[PSA_AEAD_TAG_MAX_SIZE];
+    size_t index = 0;
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT  );
+    psa_set_key_algorithm( &attributes, alg );
+    psa_set_key_type( &attributes, key_type );
+
+    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
+                                &key ) );
+
+    PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
+
+    output_size = PSA_AEAD_UPDATE_OUTPUT_SIZE( key_type, alg, input_data->len );
+
+    ASSERT_ALLOC( output, output_size );
+
+    ciphertext_size = PSA_AEAD_FINISH_OUTPUT_SIZE( key_type, alg );
+
+    TEST_ASSERT( ciphertext_size <= PSA_AEAD_FINISH_OUTPUT_MAX_SIZE );
+
+    ASSERT_ALLOC( ciphertext, ciphertext_size );
+
+    status = psa_aead_encrypt_setup( &operation, key, alg );
+
+    /* If the operation is not supported, just skip and not fail in case the
+     * encryption involves a common limitation of cryptography hardwares and
+     * an alternative implementation. */
+    if( status == PSA_ERROR_NOT_SUPPORTED )
+    {
+        MBEDTLS_TEST_PSA_SKIP_IF_ALT_AES_192( key_type, key_data->len * 8 );
+        MBEDTLS_TEST_PSA_SKIP_IF_ALT_GCM_NOT_12BYTES_NONCE( alg, nonce_length_arg );
+    }
+
+    PSA_ASSERT( status );
+
+    /* -1 == zero length and valid buffer, 0 = zero length and NULL buffer. */
+    if( nonce_length_arg == -1 )
+    {
+         /* Arbitrary size buffer, to test zero length valid buffer. */
+         ASSERT_ALLOC( nonce_buffer, 4 );
+         nonce_length = 0;
+    }
+    else
+    {
+        /* If length is zero, then this will return NULL. */
+        nonce_length = ( size_t ) nonce_length_arg;
+        ASSERT_ALLOC( nonce_buffer, nonce_length );
+
+        if( nonce_buffer )
+        {
+            for( index = 0; index < nonce_length - 1; ++index )
+            {
+                nonce_buffer[index] = 'a' + index;
+            }
+        }
+    }
+
+    status = psa_aead_set_nonce( &operation, nonce_buffer, nonce_length );
+
+    TEST_EQUAL( status, expected_status );
+
+    if( expected_status == PSA_SUCCESS )
+    {
+        /* Ensure we can still complete operation. */
+
+        PSA_ASSERT( psa_aead_update_ad( &operation, additional_data->x,
+                                        additional_data->len ) );
+
+        PSA_ASSERT( psa_aead_update( &operation, input_data->x, input_data->len,
+                                     output, output_size,
+                                     &ciphertext_length ) );
+
+        PSA_ASSERT( psa_aead_finish( &operation, ciphertext, ciphertext_size,
+                                     &ciphertext_length, tag_buffer,
+                                     PSA_AEAD_TAG_MAX_SIZE, &tag_length ) );
+    }
+
+exit:
+    psa_destroy_key( key );
+    mbedtls_free( output );
+    mbedtls_free( ciphertext );
+    mbedtls_free( nonce_buffer );
+    psa_aead_abort( &operation );
+    PSA_DONE( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void aead_multipart_update_buffer_test( int key_type_arg, data_t *key_data,
+                                       int alg_arg,
+                                       int output_size_arg,
+                                       data_t *nonce,
+                                       data_t *additional_data,
+                                       data_t *input_data,
+                                       int expected_status_arg )
+{
+
+    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_status_t status = PSA_ERROR_GENERIC_ERROR;
+    psa_status_t expected_status = expected_status_arg;
+    unsigned char *output = NULL;
+    unsigned char *ciphertext = NULL;
+    size_t output_size = output_size_arg;
+    size_t ciphertext_size = 0;
+    size_t ciphertext_length = 0;
+    size_t tag_length = 0;
+    uint8_t tag_buffer[PSA_AEAD_TAG_MAX_SIZE];
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT  );
+    psa_set_key_algorithm( &attributes, alg );
+    psa_set_key_type( &attributes, key_type );
+
+    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
+                                &key ) );
+
+    PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
+
+    ASSERT_ALLOC( output, output_size );
+
+    ciphertext_size = PSA_AEAD_FINISH_OUTPUT_SIZE( key_type, alg );
+
+    ASSERT_ALLOC( ciphertext, ciphertext_size );
+
+    status = psa_aead_encrypt_setup( &operation, key, alg );
+
+    /* If the operation is not supported, just skip and not fail in case the
+     * encryption involves a common limitation of cryptography hardwares and
+     * an alternative implementation. */
+    if( status == PSA_ERROR_NOT_SUPPORTED )
+    {
+        MBEDTLS_TEST_PSA_SKIP_IF_ALT_AES_192( key_type, key_data->len * 8 );
+        MBEDTLS_TEST_PSA_SKIP_IF_ALT_GCM_NOT_12BYTES_NONCE( alg, nonce->len );
+    }
+
+    PSA_ASSERT( status );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    PSA_ASSERT( psa_aead_update_ad( &operation, additional_data->x,
+                                    additional_data->len ) );
+
+    status = psa_aead_update( &operation, input_data->x, input_data->len,
+                              output, output_size, &ciphertext_length );
+
+    TEST_EQUAL( status, expected_status );
+
+    if( expected_status == PSA_SUCCESS )
+    {
+        /* Ensure we can still complete operation. */
+        PSA_ASSERT( psa_aead_finish( &operation, ciphertext, ciphertext_size,
+                                     &ciphertext_length, tag_buffer,
+                                     PSA_AEAD_TAG_MAX_SIZE, &tag_length ) );
+    }
+
+exit:
+    psa_destroy_key( key );
+    mbedtls_free( output );
+    mbedtls_free( ciphertext );
+    psa_aead_abort( &operation );
+    PSA_DONE( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void aead_multipart_finish_buffer_test( int key_type_arg, data_t *key_data,
+                                        int alg_arg,
+                                        int finish_ciphertext_size_arg,
+                                        int tag_size_arg,
+                                        data_t *nonce,
+                                        data_t *additional_data,
+                                        data_t *input_data,
+                                        int expected_status_arg )
+{
+
+    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_status_t status = PSA_ERROR_GENERIC_ERROR;
+    psa_status_t expected_status = expected_status_arg;
+    unsigned char *ciphertext = NULL;
+    unsigned char *finish_ciphertext = NULL;
+    unsigned char *tag_buffer = NULL;
+    size_t ciphertext_size = 0;
+    size_t ciphertext_length = 0;
+    size_t finish_ciphertext_size = ( size_t ) finish_ciphertext_size_arg;
+    size_t tag_size = ( size_t ) tag_size_arg;
+    size_t tag_length = 0;
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT  );
+    psa_set_key_algorithm( &attributes, alg );
+    psa_set_key_type( &attributes, key_type );
+
+    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
+                                &key ) );
+
+    PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
+
+    ciphertext_size = PSA_AEAD_UPDATE_OUTPUT_SIZE( key_type, alg, input_data->len );
+
+    ASSERT_ALLOC( ciphertext, ciphertext_size );
+
+    ASSERT_ALLOC( finish_ciphertext, finish_ciphertext_size );
+
+    ASSERT_ALLOC( tag_buffer, tag_size );
+
+    status = psa_aead_encrypt_setup( &operation, key, alg );
+
+    /* If the operation is not supported, just skip and not fail in case the
+     * encryption involves a common limitation of cryptography hardwares and
+     * an alternative implementation. */
+    if( status == PSA_ERROR_NOT_SUPPORTED )
+    {
+        MBEDTLS_TEST_PSA_SKIP_IF_ALT_AES_192( key_type, key_data->len * 8 );
+        MBEDTLS_TEST_PSA_SKIP_IF_ALT_GCM_NOT_12BYTES_NONCE( alg, nonce->len );
+    }
+
+    PSA_ASSERT( status );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    PSA_ASSERT( psa_aead_update_ad( &operation, additional_data->x,
+                                    additional_data->len ) );
+
+    PSA_ASSERT( psa_aead_update( &operation, input_data->x, input_data->len,
+                              ciphertext, ciphertext_size, &ciphertext_length ) );
+
+    /* Ensure we can still complete operation. */
+    status = psa_aead_finish( &operation, finish_ciphertext,
+                              finish_ciphertext_size,
+                              &ciphertext_length, tag_buffer,
+                              tag_size, &tag_length );
+
+    TEST_EQUAL( status, expected_status );
+
+exit:
+    psa_destroy_key( key );
+    mbedtls_free( ciphertext );
+    mbedtls_free( finish_ciphertext );
+    mbedtls_free( tag_buffer );
+    psa_aead_abort( &operation );
+    PSA_DONE( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void aead_multipart_verify( int key_type_arg, data_t *key_data,
+                            int alg_arg,
+                            data_t *nonce,
+                            data_t *additional_data,
+                            data_t *input_data,
+                            data_t *tag,
+                            int tag_usage_arg,
+                            int expected_status_arg )
+{
+    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_status_t status = PSA_ERROR_GENERIC_ERROR;
+    psa_status_t expected_status = expected_status_arg;
+    unsigned char *plaintext = NULL;
+    unsigned char *finish_plaintext = NULL;
+    size_t plaintext_size = 0;
+    size_t plaintext_length = 0;
+    size_t verify_plaintext_size = 0;
+    tag_usage_method_t tag_usage = tag_usage_arg;
+    unsigned char *tag_buffer = NULL;
+    size_t tag_size = 0;
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT  );
+    psa_set_key_algorithm( &attributes, alg );
+    psa_set_key_type( &attributes, key_type );
+
+    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
+                                &key ) );
+
+    PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
+
+    plaintext_size = PSA_AEAD_UPDATE_OUTPUT_SIZE( key_type, alg,
+                                                  input_data->len );
+
+    ASSERT_ALLOC( plaintext, plaintext_size );
+
+    verify_plaintext_size = PSA_AEAD_VERIFY_OUTPUT_SIZE( key_type, alg );
+
+    ASSERT_ALLOC( finish_plaintext, verify_plaintext_size );
+
+    status = psa_aead_decrypt_setup( &operation, key, alg );
+
+    /* If the operation is not supported, just skip and not fail in case the
+     * encryption involves a common limitation of cryptography hardwares and
+     * an alternative implementation. */
+    if( status == PSA_ERROR_NOT_SUPPORTED )
+    {
+        MBEDTLS_TEST_PSA_SKIP_IF_ALT_AES_192( key_type, key_data->len * 8 );
+        MBEDTLS_TEST_PSA_SKIP_IF_ALT_GCM_NOT_12BYTES_NONCE( alg, nonce->len );
+    }
+
+    PSA_ASSERT( status );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    PSA_ASSERT( psa_aead_update_ad( &operation, additional_data->x,
+                                    additional_data->len ) );
+
+    PSA_ASSERT( psa_aead_update( &operation, input_data->x,
+                                 input_data->len,
+                                 plaintext, plaintext_size,
+                                 &plaintext_length ) );
+
+    if( tag_usage == USE_GIVEN_TAG )
+    {
+        tag_buffer = tag->x;
+        tag_size = tag->len;
+    }
+
+    status = psa_aead_verify( &operation, finish_plaintext,
+                              verify_plaintext_size,
+                              &plaintext_length,
+                              tag_buffer, tag_size );
+
+    TEST_EQUAL( status, expected_status );
+
+exit:
+    psa_destroy_key( key );
+    mbedtls_free( plaintext );
+    mbedtls_free( finish_plaintext );
+    psa_aead_abort( &operation );
+    PSA_DONE( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void aead_multipart_setup( int key_type_arg, data_t *key_data,
+                           int alg_arg, int expected_status_arg )
+{
+    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_status_t status = PSA_ERROR_GENERIC_ERROR;
+    psa_status_t expected_status = expected_status_arg;
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    psa_set_key_usage_flags( &attributes,
+                             PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
+    psa_set_key_algorithm( &attributes, alg );
+    psa_set_key_type( &attributes, key_type );
+
+    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
+                                &key ) );
+
+    status = psa_aead_encrypt_setup( &operation, key, alg );
+
+    TEST_EQUAL( status, expected_status );
+
+    psa_aead_abort( &operation );
+
+    status = psa_aead_decrypt_setup( &operation, key, alg );
+
+    TEST_EQUAL(status, expected_status );
+
+exit:
+    psa_destroy_key( key );
+    psa_aead_abort( &operation );
+    PSA_DONE( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void aead_multipart_state_test( int key_type_arg, data_t *key_data,
+                                int alg_arg,
+                                data_t *nonce,
+                                data_t *additional_data,
+                                data_t *input_data )
+{
+    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
+    unsigned char *output_data = NULL;
+    unsigned char *final_data = NULL;
+    size_t output_size = 0;
+    size_t finish_output_size = 0;
+    size_t output_length = 0;
+    size_t key_bits = 0;
+    size_t tag_length = 0;
+    size_t tag_size = 0;
+    size_t nonce_length = 0;
+    uint8_t nonce_buffer[PSA_AEAD_NONCE_MAX_SIZE];
+    uint8_t tag_buffer[PSA_AEAD_TAG_MAX_SIZE];
+    size_t output_part_length = 0;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    psa_set_key_usage_flags( & attributes,
+                             PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
+    psa_set_key_algorithm( & attributes, alg );
+    psa_set_key_type( & attributes, key_type );
+
+    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
+                                &key ) );
+
+    PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
+    key_bits = psa_get_key_bits( &attributes );
+
+    tag_length = PSA_AEAD_TAG_LENGTH( key_type, key_bits, alg );
+
+    TEST_ASSERT( tag_length <= PSA_AEAD_TAG_MAX_SIZE );
+
+    output_size = PSA_AEAD_UPDATE_OUTPUT_SIZE( key_type, alg, input_data->len );
+
+    ASSERT_ALLOC( output_data, output_size );
+
+    finish_output_size = PSA_AEAD_FINISH_OUTPUT_SIZE( key_type, alg );
+
+    TEST_ASSERT( finish_output_size <= PSA_AEAD_FINISH_OUTPUT_MAX_SIZE );
+
+    ASSERT_ALLOC( final_data, finish_output_size );
+
+    /* Test all operations error without calling setup first. */
+
+    TEST_EQUAL( psa_aead_set_nonce( &operation, nonce->x, nonce->len ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    TEST_EQUAL( psa_aead_generate_nonce( &operation, nonce_buffer,
+                                         PSA_AEAD_NONCE_MAX_SIZE,
+                                         &nonce_length ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* ------------------------------------------------------- */
+
+    TEST_EQUAL( psa_aead_set_lengths( &operation, additional_data->len,
+                                      input_data->len ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* ------------------------------------------------------- */
+
+    TEST_EQUAL( psa_aead_update_ad( &operation, additional_data->x,
+                                    additional_data->len ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* ------------------------------------------------------- */
+
+    TEST_EQUAL( psa_aead_update( &operation, input_data->x,
+                                 input_data->len, output_data,
+                                 output_size, &output_length ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* ------------------------------------------------------- */
+
+    TEST_EQUAL( psa_aead_finish( &operation, final_data,
+                                 finish_output_size,
+                                 &output_part_length,
+                                 tag_buffer, tag_length,
+                                 &tag_size ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* ------------------------------------------------------- */
+
+    TEST_EQUAL( psa_aead_verify( &operation, final_data,
+                                 finish_output_size,
+                                 &output_part_length,
+                                 tag_buffer,
+                                 tag_length ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* Test for double setups. */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    TEST_EQUAL( psa_aead_encrypt_setup( &operation, key, alg ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* ------------------------------------------------------- */
+
+    PSA_ASSERT( psa_aead_decrypt_setup( &operation, key, alg ) );
+
+    TEST_EQUAL( psa_aead_decrypt_setup( &operation, key, alg ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* ------------------------------------------------------- */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    TEST_EQUAL( psa_aead_decrypt_setup( &operation, key, alg ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* ------------------------------------------------------- */
+
+    PSA_ASSERT( psa_aead_decrypt_setup( &operation, key, alg ) );
+
+    TEST_EQUAL( psa_aead_encrypt_setup( &operation, key, alg ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* Test for not setting a nonce. */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    TEST_EQUAL( psa_aead_update_ad( &operation, additional_data->x,
+                                    additional_data->len ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* ------------------------------------------------------- */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    TEST_EQUAL( psa_aead_update( &operation, input_data->x,
+                                 input_data->len, output_data,
+                                 output_size, &output_length ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* ------------------------------------------------------- */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    TEST_EQUAL( psa_aead_finish( &operation, final_data,
+                                 finish_output_size,
+                                 &output_part_length,
+                                 tag_buffer, tag_length,
+                                 &tag_size ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* ------------------------------------------------------- */
+
+    PSA_ASSERT( psa_aead_decrypt_setup( &operation, key, alg ) );
+
+    TEST_EQUAL( psa_aead_verify( &operation, final_data,
+                                 finish_output_size,
+                                 &output_part_length,
+                                 tag_buffer,
+                                 tag_length ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* Test for double setting nonce. */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    TEST_EQUAL( psa_aead_set_nonce( &operation, nonce->x, nonce->len ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* Test for double generating nonce. */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_generate_nonce( &operation, nonce_buffer,
+                                         PSA_AEAD_NONCE_MAX_SIZE,
+                                         &nonce_length ) );
+
+    TEST_EQUAL( psa_aead_generate_nonce( &operation, nonce_buffer,
+                                         PSA_AEAD_NONCE_MAX_SIZE,
+                                         &nonce_length ),
+                PSA_ERROR_BAD_STATE );
+
+
+    psa_aead_abort( &operation );
+
+    /* Test for generate nonce then set and vice versa */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_generate_nonce( &operation, nonce_buffer,
+                                         PSA_AEAD_NONCE_MAX_SIZE,
+                                         &nonce_length ) );
+
+    TEST_EQUAL( psa_aead_set_nonce( &operation, nonce->x, nonce->len ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* ------------------------------------------------------- */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    TEST_EQUAL( psa_aead_generate_nonce( &operation, nonce_buffer,
+                                         PSA_AEAD_NONCE_MAX_SIZE,
+                                         &nonce_length ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* Test for generating nonce in decrypt setup. */
+
+    PSA_ASSERT( psa_aead_decrypt_setup( &operation, key, alg ) );
+
+    TEST_EQUAL( psa_aead_generate_nonce( &operation, nonce_buffer,
+                                         PSA_AEAD_NONCE_MAX_SIZE,
+                                         &nonce_length ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* Test for setting lengths twice. */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    PSA_ASSERT( psa_aead_set_lengths( &operation, additional_data->len,
+                                      input_data->len ) );
+
+    TEST_EQUAL( psa_aead_set_lengths( &operation, additional_data->len,
+                                      input_data->len ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* Test for setting lengths after already starting data. */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    PSA_ASSERT( psa_aead_update_ad( &operation, additional_data->x,
+                                    additional_data->len ) );
+
+    TEST_EQUAL( psa_aead_set_lengths( &operation, additional_data->len,
+                                      input_data->len ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* ------------------------------------------------------- */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    PSA_ASSERT( psa_aead_update( &operation, input_data->x,
+                                 input_data->len, output_data,
+                                 output_size, &output_length ) );
+
+    TEST_EQUAL( psa_aead_set_lengths( &operation, additional_data->len,
+                                      input_data->len ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* Test for not sending any additional data or data after setting non zero
+     * lengths for them. (encrypt) */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    PSA_ASSERT( psa_aead_set_lengths( &operation, additional_data->len,
+                                      input_data->len ) );
+
+    TEST_EQUAL( psa_aead_finish( &operation, final_data,
+                                 finish_output_size,
+                                 &output_part_length,
+                                 tag_buffer, tag_length,
+                                 &tag_size ),
+                PSA_ERROR_INVALID_ARGUMENT );
+
+    psa_aead_abort( &operation );
+
+    /* Test for not sending any additional data or data after setting non-zero
+     * lengths for them. (decrypt) */
+
+    PSA_ASSERT( psa_aead_decrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    PSA_ASSERT( psa_aead_set_lengths( &operation, additional_data->len,
+                                      input_data->len ) );
+
+    TEST_EQUAL( psa_aead_verify( &operation, final_data,
+                                 finish_output_size,
+                                 &output_part_length,
+                                 tag_buffer,
+                                 tag_length ),
+                PSA_ERROR_INVALID_ARGUMENT );
+
+    psa_aead_abort( &operation );
+
+    /* Test for not sending any additional data after setting a non-zero length
+     * for it. */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    PSA_ASSERT( psa_aead_set_lengths( &operation, additional_data->len,
+                                      input_data->len ) );
+
+    TEST_EQUAL( psa_aead_update( &operation, input_data->x,
+                                 input_data->len, output_data,
+                                 output_size, &output_length ),
+                PSA_ERROR_INVALID_ARGUMENT );
+
+    psa_aead_abort( &operation );
+
+    /* Test for not sending any data after setting a non-zero length for it.*/
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    PSA_ASSERT( psa_aead_set_lengths( &operation, additional_data->len,
+                                      input_data->len ) );
+
+    PSA_ASSERT( psa_aead_update_ad( &operation, additional_data->x,
+                                    additional_data->len ) );
+
+    TEST_EQUAL( psa_aead_finish( &operation, final_data,
+                                 finish_output_size,
+                                 &output_part_length,
+                                 tag_buffer, tag_length,
+                                 &tag_size ),
+                PSA_ERROR_INVALID_ARGUMENT );
+
+    psa_aead_abort( &operation );
+
+    /* Test for sending too much additional data after setting lengths. */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    PSA_ASSERT( psa_aead_set_lengths( &operation, 0, 0 ) );
+
+
+    TEST_EQUAL( psa_aead_update_ad( &operation, additional_data->x,
+                                    additional_data->len ),
+                PSA_ERROR_INVALID_ARGUMENT );
+
+    psa_aead_abort( &operation );
+
+    /* ------------------------------------------------------- */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    PSA_ASSERT( psa_aead_set_lengths( &operation, additional_data->len,
+                                      input_data->len ) );
+
+    PSA_ASSERT( psa_aead_update_ad( &operation, additional_data->x,
+                                    additional_data->len ) );
+
+    TEST_EQUAL( psa_aead_update_ad( &operation, additional_data->x,
+                                    1 ),
+                PSA_ERROR_INVALID_ARGUMENT );
+
+    psa_aead_abort( &operation );
+
+    /* Test for sending too much data after setting lengths. */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    PSA_ASSERT( psa_aead_set_lengths( &operation, 0, 0 ) );
+
+    TEST_EQUAL( psa_aead_update( &operation, input_data->x,
+                                 input_data->len, output_data,
+                                 output_size, &output_length ),
+                PSA_ERROR_INVALID_ARGUMENT );
+
+    psa_aead_abort( &operation );
+
+    /* ------------------------------------------------------- */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    PSA_ASSERT( psa_aead_set_lengths( &operation, additional_data->len,
+                                      input_data->len ) );
+
+    PSA_ASSERT( psa_aead_update_ad( &operation, additional_data->x,
+                                    additional_data->len ) );
+
+    PSA_ASSERT( psa_aead_update( &operation, input_data->x,
+                                 input_data->len, output_data,
+                                 output_size, &output_length ) );
+
+    TEST_EQUAL( psa_aead_update( &operation, input_data->x,
+                                 1, output_data,
+                                 output_size, &output_length ),
+                PSA_ERROR_INVALID_ARGUMENT );
+
+    psa_aead_abort( &operation );
+
+    /* Test sending additional data after data. */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    PSA_ASSERT( psa_aead_update( &operation, input_data->x,
+                                 input_data->len, output_data,
+                                 output_size, &output_length ) );
+
+    TEST_EQUAL( psa_aead_update_ad( &operation, additional_data->x,
+                                    additional_data->len ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* Test calling finish on decryption. */
+
+    PSA_ASSERT( psa_aead_decrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    TEST_EQUAL( psa_aead_finish( &operation, final_data,
+                                 finish_output_size,
+                                 &output_part_length,
+                                 tag_buffer, tag_length,
+                                 &tag_size ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+    /* Test calling verify on encryption. */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    TEST_EQUAL( psa_aead_verify( &operation, final_data,
+                                 finish_output_size,
+                                 &output_part_length,
+                                 tag_buffer,
+                                 tag_length ),
+                PSA_ERROR_BAD_STATE );
+
+    psa_aead_abort( &operation );
+
+
+exit:
+    psa_destroy_key( key );
+    psa_aead_abort( &operation );
+    mbedtls_free( output_data );
+    mbedtls_free( final_data );
+    PSA_DONE( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void signature_size( int type_arg,
                      int bits,
                      int alg_arg,
diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function
index 6d78ad5..bc6ff34 100644
--- a/tests/suites/test_suite_psa_crypto_driver_wrappers.function
+++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.function
@@ -1063,7 +1063,7 @@
                                input_data->x, input_data->len,
                                output_data, output_size,
                                &output_length );
-    TEST_EQUAL( mbedtls_test_driver_aead_hooks.hits, 1 );
+    TEST_EQUAL( mbedtls_test_driver_aead_hooks.hits_encrypt, 1 );
     TEST_EQUAL( mbedtls_test_driver_aead_hooks.driver_status, forced_status );
 
     TEST_EQUAL( status, ( forced_status == PSA_ERROR_NOT_SUPPORTED ) ?
@@ -1127,7 +1127,7 @@
                                input_data->x, input_data->len,
                                output_data, output_size,
                                &output_length );
-    TEST_EQUAL( mbedtls_test_driver_aead_hooks.hits, 1 );
+    TEST_EQUAL( mbedtls_test_driver_aead_hooks.hits_decrypt, 1 );
     TEST_EQUAL( mbedtls_test_driver_aead_hooks.driver_status, forced_status );
 
     TEST_EQUAL( status, ( forced_status == PSA_ERROR_NOT_SUPPORTED ) ?