Merge pull request #4984 from gilles-peskine-arm/check-names-files

check_names.py: more robust handling of excluded files
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/check-return.txt b/ChangeLog.d/check-return.txt
new file mode 100644
index 0000000..045b180
--- /dev/null
+++ b/ChangeLog.d/check-return.txt
@@ -0,0 +1,17 @@
+Bugfix
+   * Failures of alternative implementations of AES or DES single-block
+     functions enabled with MBEDTLS_AES_ENCRYPT_ALT, MBEDTLS_AES_DECRYPT_ALT,
+     MBEDTLS_DES_CRYPT_ECB_ALT or MBEDTLS_DES3_CRYPT_ECB_ALT were ignored.
+     This does not concern the implementation provided with Mbed TLS,
+     where this function cannot fail, or full-module replacements with
+     MBEDTLS_AES_ALT or MBEDTLS_DES_ALT. Reported by Armelle Duboc in #1092.
+
+Features
+   * Warn if errors from certain functions are ignored. This is currently
+     supported on GCC-like compilers and on MSVC and can be configured through
+     the macro MBEDTLS_CHECK_RETURN. The warnings are always enabled
+     (where supported) for critical functions where ignoring the return
+     value is almost always a bug. Enable the new configuration option
+     MBEDTLS_CHECK_RETURN_WARNING to get warnings for other functions. This
+     is currently implemented in the AES and DES modules, and will be extended
+     to other modules in the future.
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/aes.h b/include/mbedtls/aes.h
index 879c3f2..becbfae 100644
--- a/include/mbedtls/aes.h
+++ b/include/mbedtls/aes.h
@@ -42,6 +42,7 @@
 #include "mbedtls/private_access.h"
 
 #include "mbedtls/build_info.h"
+#include "mbedtls/platform_util.h"
 
 #include <stddef.h>
 #include <stdint.h>
@@ -163,6 +164,7 @@
  * \return         \c 0 on success.
  * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
                     unsigned int keybits );
 
@@ -181,6 +183,7 @@
  * \return         \c 0 on success.
  * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
                     unsigned int keybits );
 
@@ -201,6 +204,7 @@
  * \return         \c 0 on success.
  * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
                                 const unsigned char *key,
                                 unsigned int keybits );
@@ -221,6 +225,7 @@
  * \return         \c 0 on success.
  * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
                                 const unsigned char *key,
                                 unsigned int keybits );
@@ -249,6 +254,7 @@
 
  * \return         \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
                     int mode,
                     const unsigned char input[16],
@@ -296,6 +302,7 @@
  * \return         #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
  *                 on failure.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
                     int mode,
                     size_t length,
@@ -340,6 +347,7 @@
  *                     smaller than an AES block in size (16 Bytes) or if \p
  *                     length is larger than 2^20 blocks (16 MiB).
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
                            int mode,
                            size_t length,
@@ -388,6 +396,7 @@
  *
  * \return         \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
                        int mode,
                        size_t length,
@@ -432,6 +441,7 @@
  *
  * \return         \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
                     int mode,
                     size_t length,
@@ -486,6 +496,7 @@
  *
  * \return         \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
                        size_t length,
                        size_t *iv_off,
@@ -572,6 +583,7 @@
  *
  * \return                 \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
                        size_t length,
                        size_t *nc_off,
@@ -592,6 +604,7 @@
  *
  * \return          \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
                                   const unsigned char input[16],
                                   unsigned char output[16] );
@@ -607,6 +620,7 @@
  *
  * \return          \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
                                   const unsigned char input[16],
                                   unsigned char output[16] );
@@ -618,6 +632,7 @@
  * \return         \c 0 on success.
  * \return         \c 1 on failure.
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 int mbedtls_aes_self_test( int verbose );
 
 #endif /* MBEDTLS_SELF_TEST */
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/des.h b/include/mbedtls/des.h
index 63a8e00..be74cb1 100644
--- a/include/mbedtls/des.h
+++ b/include/mbedtls/des.h
@@ -29,6 +29,7 @@
 #include "mbedtls/private_access.h"
 
 #include "mbedtls/build_info.h"
+#include "mbedtls/platform_util.h"
 
 #include <stddef.h>
 #include <stdint.h>
@@ -139,6 +140,7 @@
  *                 security risk. We recommend considering stronger ciphers
  *                 instead.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
 
 /**
@@ -152,6 +154,7 @@
  *                 security risk. We recommend considering stronger ciphers
  *                 instead.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
 
 /**
@@ -166,6 +169,7 @@
  *                 security risk. We recommend considering stronger ciphers
  *                 instead.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
 
 /**
@@ -180,6 +184,7 @@
  *                 security risk. We recommend considering stronger ciphers
  *                 instead.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
 
 /**
@@ -190,6 +195,7 @@
  *
  * \return         0
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
                       const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
 
@@ -201,6 +207,7 @@
  *
  * \return         0
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
                       const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
 
@@ -212,6 +219,7 @@
  *
  * \return         0
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
                       const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
 
@@ -223,6 +231,7 @@
  *
  * \return         0
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
                       const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
 
@@ -239,6 +248,7 @@
  *                 security risk. We recommend considering stronger ciphers
  *                 instead.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
                     const unsigned char input[8],
                     unsigned char output[8] );
@@ -266,6 +276,7 @@
  *                 security risk. We recommend considering stronger ciphers
  *                 instead.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
                     int mode,
                     size_t length,
@@ -283,6 +294,7 @@
  *
  * \return         0 if successful
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
                      const unsigned char input[8],
                      unsigned char output[8] );
@@ -308,6 +320,7 @@
  *
  * \return         0 if successful, or MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
                      int mode,
                      size_t length,
@@ -338,6 +351,7 @@
  *
  * \return         0 if successful, or 1 if the test failed
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 int mbedtls_des_self_test( int verbose );
 
 #endif /* MBEDTLS_SELF_TEST */
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 adc317d..4757aa6 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -521,6 +521,29 @@
 //#define MBEDTLS_CAMELLIA_SMALL_MEMORY
 
 /**
+ * \def MBEDTLS_CHECK_RETURN_WARNING
+ *
+ * If this macro is defined, emit a compile-time warning if application code
+ * calls a function without checking its return value, but the return value
+ * should generally be checked in portable applications.
+ *
+ * This is only supported on platforms where #MBEDTLS_CHECK_RETURN is
+ * implemented. Otherwise this option has no effect.
+ *
+ * Uncomment to get warnings on using fallible functions without checking
+ * their return value.
+ *
+ * \note  This feature is a work in progress.
+ *        Warnings will be added to more functions in the future.
+ *
+ * \note  A few functions are considered critical, and ignoring the return
+ *        value of these functions will trigger a warning even if this
+ *        macro is not defined. To completely disable return value check
+ *        warnings, define #MBEDTLS_CHECK_RETURN with an empty expansion.
+ */
+//#define MBEDTLS_CHECK_RETURN_WARNING
+
+/**
  * \def MBEDTLS_CIPHER_MODE_CBC
  *
  * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers.
@@ -3067,6 +3090,29 @@
 //#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO   mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
 //#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO  mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
 
+/** \def MBEDTLS_CHECK_RETURN
+ *
+ * This macro is used at the beginning of the declaration of a function
+ * to indicate that its return value should be checked. It should
+ * instruct the compiler to emit a warning or an error if the function
+ * is called without checking its return value.
+ *
+ * There is a default implementation for popular compilers in platform_util.h.
+ * You can override the default implementation by defining your own here.
+ *
+ * If the implementation here is empty, this will effectively disable the
+ * checking of functions' return values.
+ */
+//#define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__))
+
+/** \def MBEDTLS_IGNORE_RETURN
+ *
+ * This macro requires one argument, which should be a C function call.
+ * If that function call would cause a #MBEDTLS_CHECK_RETURN warning, this
+ * warning is suppressed.
+ */
+//#define MBEDTLS_IGNORE_RETURN( result ) ((void) !(result))
+
 /* PSA options */
 /**
  * Use HMAC_DRBG with the specified hash algorithm for HMAC_DRBG for the
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/platform_util.h b/include/mbedtls/platform_util.h
index 1a0a135..36e3718 100644
--- a/include/mbedtls/platform_util.h
+++ b/include/mbedtls/platform_util.h
@@ -60,6 +60,95 @@
 #endif /* MBEDTLS_DEPRECATED_WARNING */
 #endif /* MBEDTLS_DEPRECATED_REMOVED */
 
+/* Implementation of the check-return facility.
+ * See the user documentation in mbedtls_config.h.
+ *
+ * Do not use this macro directly to annotate function: instead,
+ * use one of MBEDTLS_CHECK_RETURN_CRITICAL or MBEDTLS_CHECK_RETURN_TYPICAL
+ * depending on how important it is to check the return value.
+ */
+#if !defined(MBEDTLS_CHECK_RETURN)
+#if defined(__GNUC__)
+#define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__))
+#elif defined(_MSC_VER) && _MSC_VER >= 1700
+#include <sal.h>
+#define MBEDTLS_CHECK_RETURN _Check_return_
+#else
+#define MBEDTLS_CHECK_RETURN
+#endif
+#endif
+
+/** Critical-failure function
+ *
+ * This macro appearing at the beginning of the declaration of a function
+ * indicates that its return value should be checked in all applications.
+ * Omitting the check is very likely to indicate a bug in the application
+ * and will result in a compile-time warning if #MBEDTLS_CHECK_RETURN
+ * is implemented for the compiler in use.
+ *
+ * \note  The use of this macro is a work in progress.
+ *        This macro may be added to more functions in the future.
+ *        Such an extension is not considered an API break, provided that
+ *        there are near-unavoidable circumstances under which the function
+ *        can fail. For example, signature/MAC/AEAD verification functions,
+ *        and functions that require a random generator, are considered
+ *        return-check-critical.
+ */
+#define MBEDTLS_CHECK_RETURN_CRITICAL MBEDTLS_CHECK_RETURN
+
+/** Ordinary-failure function
+ *
+ * This macro appearing at the beginning of the declaration of a function
+ * indicates that its return value should be generally be checked in portable
+ * applications. Omitting the check will result in a compile-time warning if
+ * #MBEDTLS_CHECK_RETURN is implemented for the compiler in use and
+ * #MBEDTLS_CHECK_RETURN_WARNING is enabled in the compile-time configuration.
+ *
+ * You can use #MBEDTLS_IGNORE_RETURN to explicitly ignore the return value
+ * of a function that is annotated with #MBEDTLS_CHECK_RETURN.
+ *
+ * \note  The use of this macro is a work in progress.
+ *        This macro will be added to more functions in the future.
+ *        Eventually this should appear before most functions returning
+ *        an error code (as \c int in the \c mbedtls_xxx API or
+ *        as ::psa_status_t in the \c psa_xxx API).
+ */
+#if defined(MBEDTLS_CHECK_RETURN_WARNING)
+#define MBEDTLS_CHECK_RETURN_TYPICAL MBEDTLS_CHECK_RETURN
+#else
+#define MBEDTLS_CHECK_RETURN_TYPICAL
+#endif
+
+/** Benign-failure function
+ *
+ * This macro appearing at the beginning of the declaration of a function
+ * indicates that it is rarely useful to check its return value.
+ *
+ * This macro has an empty expansion. It exists for documentation purposes:
+ * a #MBEDTLS_CHECK_RETURN_OPTIONAL annotation indicates that the function
+ * has been analyzed for return-check usefuless, whereas the lack of
+ * an annotation indicates that the function has not been analyzed and its
+ * return-check usefulness is unknown.
+ */
+#define MBEDTLS_CHECK_RETURN_OPTIONAL
+
+/** \def MBEDTLS_IGNORE_RETURN
+ *
+ * Call this macro with one argument, a function call, to suppress a warning
+ * from #MBEDTLS_CHECK_RETURN due to that function call.
+ */
+#if !defined(MBEDTLS_IGNORE_RETURN)
+/* GCC doesn't silence the warning with just (void)(result).
+ * (void)!(result) is known to work up at least up to GCC 10, as well
+ * as with Clang and MSVC.
+ *
+ * https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Non_002dbugs.html
+ * https://stackoverflow.com/questions/40576003/ignoring-warning-wunused-result
+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425#c34
+ */
+#define MBEDTLS_IGNORE_RETURN(result) ( (void) !( result ) )
+#endif
+
 /**
  * \brief       Securely zeroize a buffer
  *
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 725b156..c1b1836 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -593,6 +593,9 @@
 
 #define MBEDTLS_PREMASTER_SIZE     sizeof( union mbedtls_ssl_premaster_secret )
 
+/* Length in number of bytes of the TLS sequence number */
+#define MBEDTLS_SSL_SEQUENCE_NUMBER_LEN 8
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -623,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;
@@ -1526,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.  */
@@ -1552,7 +1569,7 @@
     size_t MBEDTLS_PRIVATE(out_buf_len);         /*!< length of output buffer          */
 #endif
 
-    unsigned char MBEDTLS_PRIVATE(cur_out_ctr)[8]; /*!<  Outgoing record sequence  number. */
+    unsigned char MBEDTLS_PRIVATE(cur_out_ctr)[MBEDTLS_SSL_SEQUENCE_NUMBER_LEN]; /*!<  Outgoing record sequence  number. */
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
     uint16_t MBEDTLS_PRIVATE(mtu);               /*!< path mtu, used to fragment outgoing messages */
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/aes.c b/library/aes.c
index 8e3358c..4afc3c4 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -1011,6 +1011,7 @@
                     unsigned char *output )
 {
     int i;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char temp[16];
 
     AES_VALIDATE_RET( ctx != NULL );
@@ -1040,7 +1041,9 @@
         while( length > 0 )
         {
             memcpy( temp, input, 16 );
-            mbedtls_aes_crypt_ecb( ctx, mode, input, output );
+            ret = mbedtls_aes_crypt_ecb( ctx, mode, input, output );
+            if( ret != 0 )
+                goto exit;
 
             for( i = 0; i < 16; i++ )
                 output[i] = (unsigned char)( output[i] ^ iv[i] );
@@ -1059,7 +1062,9 @@
             for( i = 0; i < 16; i++ )
                 output[i] = (unsigned char)( input[i] ^ iv[i] );
 
-            mbedtls_aes_crypt_ecb( ctx, mode, output, output );
+            ret = mbedtls_aes_crypt_ecb( ctx, mode, output, output );
+            if( ret != 0 )
+                goto exit;
             memcpy( iv, output, 16 );
 
             input  += 16;
@@ -1067,8 +1072,10 @@
             length -= 16;
         }
     }
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
 
@@ -1222,6 +1229,7 @@
                        unsigned char *output )
 {
     int c;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t n;
 
     AES_VALIDATE_RET( ctx != NULL );
@@ -1242,7 +1250,11 @@
         while( length-- )
         {
             if( n == 0 )
-                mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+            {
+                ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+                if( ret != 0 )
+                    goto exit;
+            }
 
             c = *input++;
             *output++ = (unsigned char)( c ^ iv[n] );
@@ -1256,7 +1268,11 @@
         while( length-- )
         {
             if( n == 0 )
-                mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+            {
+                ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+                if( ret != 0 )
+                    goto exit;
+            }
 
             iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
 
@@ -1265,8 +1281,10 @@
     }
 
     *iv_off = n;
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 
 /*
@@ -1279,6 +1297,7 @@
                             const unsigned char *input,
                             unsigned char *output )
 {
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char c;
     unsigned char ov[17];
 
@@ -1291,7 +1310,9 @@
     while( length-- )
     {
         memcpy( ov, iv, 16 );
-        mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+        ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+        if( ret != 0 )
+            goto exit;
 
         if( mode == MBEDTLS_AES_DECRYPT )
             ov[16] = *input;
@@ -1303,8 +1324,10 @@
 
         memcpy( iv, ov + 1, 16 );
     }
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 #endif /* MBEDTLS_CIPHER_MODE_CFB */
 
@@ -1366,6 +1389,7 @@
                        unsigned char *output )
 {
     int c, i;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t n;
 
     AES_VALIDATE_RET( ctx != NULL );
@@ -1383,7 +1407,9 @@
     while( length-- )
     {
         if( n == 0 ) {
-            mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
+            ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
+            if( ret != 0 )
+                goto exit;
 
             for( i = 16; i > 0; i-- )
                 if( ++nonce_counter[i - 1] != 0 )
@@ -1396,8 +1422,10 @@
     }
 
     *nc_off = n;
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 #endif /* MBEDTLS_CIPHER_MODE_CTR */
 
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/des.c b/library/des.c
index 7f90faa..91d22b5 100644
--- a/library/des.c
+++ b/library/des.c
@@ -28,6 +28,7 @@
 #if defined(MBEDTLS_DES_C)
 
 #include "mbedtls/des.h"
+#include "mbedtls/error.h"
 #include "mbedtls/platform_util.h"
 
 #include <string.h>
@@ -642,6 +643,7 @@
                     unsigned char *output )
 {
     int i;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char temp[8];
 
     if( length % 8 )
@@ -654,7 +656,9 @@
             for( i = 0; i < 8; i++ )
                 output[i] = (unsigned char)( input[i] ^ iv[i] );
 
-            mbedtls_des_crypt_ecb( ctx, output, output );
+            ret = mbedtls_des_crypt_ecb( ctx, output, output );
+            if( ret != 0 )
+                goto exit;
             memcpy( iv, output, 8 );
 
             input  += 8;
@@ -667,7 +671,9 @@
         while( length > 0 )
         {
             memcpy( temp, input, 8 );
-            mbedtls_des_crypt_ecb( ctx, input, output );
+            ret = mbedtls_des_crypt_ecb( ctx, input, output );
+            if( ret != 0 )
+                goto exit;
 
             for( i = 0; i < 8; i++ )
                 output[i] = (unsigned char)( output[i] ^ iv[i] );
@@ -679,8 +685,10 @@
             length -= 8;
         }
     }
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
 
@@ -741,6 +749,7 @@
                      unsigned char *output )
 {
     int i;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char temp[8];
 
     if( length % 8 )
@@ -753,7 +762,9 @@
             for( i = 0; i < 8; i++ )
                 output[i] = (unsigned char)( input[i] ^ iv[i] );
 
-            mbedtls_des3_crypt_ecb( ctx, output, output );
+            ret = mbedtls_des3_crypt_ecb( ctx, output, output );
+            if( ret != 0 )
+                goto exit;
             memcpy( iv, output, 8 );
 
             input  += 8;
@@ -766,7 +777,9 @@
         while( length > 0 )
         {
             memcpy( temp, input, 8 );
-            mbedtls_des3_crypt_ecb( ctx, input, output );
+            ret = mbedtls_des3_crypt_ecb( ctx, input, output );
+            if( ret != 0 )
+                goto exit;
 
             for( i = 0; i < 8; i++ )
                 output[i] = (unsigned char)( output[i] ^ iv[i] );
@@ -778,8 +791,10 @@
             length -= 8;
         }
     }
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
 
@@ -872,39 +887,43 @@
         switch( i )
         {
         case 0:
-            mbedtls_des_setkey_dec( &ctx, des3_test_keys );
+            ret = mbedtls_des_setkey_dec( &ctx, des3_test_keys );
             break;
 
         case 1:
-            mbedtls_des_setkey_enc( &ctx, des3_test_keys );
+            ret = mbedtls_des_setkey_enc( &ctx, des3_test_keys );
             break;
 
         case 2:
-            mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
             break;
 
         case 3:
-            mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
             break;
 
         case 4:
-            mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
             break;
 
         case 5:
-            mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
             break;
 
         default:
             return( 1 );
         }
+        if( ret != 0 )
+            goto exit;
 
         for( j = 0; j < 100; j++ )
         {
             if( u == 0 )
-                mbedtls_des_crypt_ecb( &ctx, buf, buf );
+                ret = mbedtls_des_crypt_ecb( &ctx, buf, buf );
             else
-                mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
+                ret = mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
+            if( ret != 0 )
+                goto exit;
         }
 
         if( ( v == MBEDTLS_DES_DECRYPT &&
@@ -947,41 +966,45 @@
         switch( i )
         {
         case 0:
-            mbedtls_des_setkey_dec( &ctx, des3_test_keys );
+            ret = mbedtls_des_setkey_dec( &ctx, des3_test_keys );
             break;
 
         case 1:
-            mbedtls_des_setkey_enc( &ctx, des3_test_keys );
+            ret = mbedtls_des_setkey_enc( &ctx, des3_test_keys );
             break;
 
         case 2:
-            mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
             break;
 
         case 3:
-            mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
             break;
 
         case 4:
-            mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
             break;
 
         case 5:
-            mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
             break;
 
         default:
             return( 1 );
         }
+        if( ret != 0 )
+            goto exit;
 
         if( v == MBEDTLS_DES_DECRYPT )
         {
             for( j = 0; j < 100; j++ )
             {
                 if( u == 0 )
-                    mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
+                    ret = mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
                 else
-                    mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
+                    ret = mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
+                if( ret != 0 )
+                    goto exit;
             }
         }
         else
@@ -991,9 +1014,11 @@
                 unsigned char tmp[8];
 
                 if( u == 0 )
-                    mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
+                    ret = mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
                 else
-                    mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
+                    ret = mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
+                if( ret != 0 )
+                    goto exit;
 
                 memcpy( tmp, prv, 8 );
                 memcpy( prv, buf, 8 );
@@ -1027,6 +1052,8 @@
     mbedtls_des_free( &ctx );
     mbedtls_des3_free( &ctx3 );
 
+    if( ret != 0 )
+        ret = 1;
     return( ret );
 }
 
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 c338d79..9041c51 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -307,6 +307,10 @@
       + ( MBEDTLS_SSL_CID_OUT_LEN_MAX ) )
 #endif
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+#define MBEDTLS_TLS1_3_MD_MAX_SIZE         MBEDTLS_MD_MAX_SIZE
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
 /**
  * \brief          Return the maximum fragment length (payload, in bytes) for
@@ -409,6 +413,32 @@
         }                                                                \
     } while( 0 )
 
+/**
+ * \brief        This macro checks if the remaining length in an input buffer is
+ *               greater or equal than a needed length. If it is not the case, it
+ *               returns #MBEDTLS_ERR_SSL_DECODE_ERROR error and pends a
+ *               #MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR alert message.
+ *
+ *               This is a function-like macro. It is guaranteed to evaluate each
+ *               argument exactly once.
+ *
+ * \param cur    Pointer to the current position in the buffer.
+ * \param end    Pointer to one past the end of the buffer.
+ * \param need   Needed length in bytes.
+ *
+ */
+#define MBEDTLS_SSL_CHK_BUF_READ_PTR( cur, end, need )                          \
+    do {                                                                        \
+        if( mbedtls_ssl_chk_buf_ptr( ( cur ), ( end ), ( need ) ) != 0 )        \
+        {                                                                       \
+            MBEDTLS_SSL_DEBUG_MSG( 1,                                           \
+                                   ( "missing input data in %s", __func__ ) );  \
+            MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,   \
+                                          MBEDTLS_ERR_SSL_DECODE_ERROR );       \
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );                             \
+        }                                                                       \
+    } while( 0 )
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -486,6 +516,9 @@
     /*
      * Handshake specific crypto variables
      */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+    int tls1_3_kex_modes; /*!< key exchange modes for TLS 1.3 */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
     defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
@@ -573,8 +606,8 @@
                                               flight being received          */
     mbedtls_ssl_transform *alt_transform_out;   /*!<  Alternative transform for
                                               resending messages             */
-    unsigned char alt_out_ctr[8];       /*!<  Alternative record epoch/counter
-                                              for resending messages         */
+    unsigned char alt_out_ctr[MBEDTLS_SSL_SEQUENCE_NUMBER_LEN]; /*!<  Alternative record epoch/counter
+                                                                      for resending messages         */
 
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
     /* The state of CID configuration in this handshake. */
@@ -675,6 +708,13 @@
     int extensions_present;             /*!< extension presence; Each bitfield
                                              represents an extension and defined
                                              as \c MBEDTLS_SSL_EXT_XXX */
+
+    union
+    {
+        unsigned char early    [MBEDTLS_TLS1_3_MD_MAX_SIZE];
+        unsigned char handshake[MBEDTLS_TLS1_3_MD_MAX_SIZE];
+        unsigned char app      [MBEDTLS_TLS1_3_MD_MAX_SIZE];
+    } tls1_3_master_secrets;
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
@@ -866,14 +906,14 @@
 
 typedef struct
 {
-    uint8_t ctr[8];         /* In TLS:  The implicit record sequence number.
-                             * In DTLS: The 2-byte epoch followed by
-                             *          the 6-byte sequence number.
-                             * This is stored as a raw big endian byte array
-                             * as opposed to a uint64_t because we rarely
-                             * need to perform arithmetic on this, but do
-                             * need it as a Byte array for the purpose of
-                             * MAC computations.                             */
+    uint8_t ctr[MBEDTLS_SSL_SEQUENCE_NUMBER_LEN];  /* In TLS:  The implicit record sequence number.
+                                                    * In DTLS: The 2-byte epoch followed by
+                                                    *          the 6-byte sequence number.
+                                                    * This is stored as a raw big endian byte array
+                                                    * as opposed to a uint64_t because we rarely
+                                                    * need to perform arithmetic on this, but do
+                                                    * need it as a Byte array for the purpose of
+                                                    * MAC computations.                             */
     uint8_t type;           /* The record content type.                      */
     uint8_t ver[2];         /* SSL/TLS version as present on the wire.
                              * Convert to internal presentation of versions
@@ -956,6 +996,14 @@
  */
 void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl );
 
+/* set inbound transform of ssl context */
+void mbedtls_ssl_set_inbound_transform( mbedtls_ssl_context *ssl,
+                                        mbedtls_ssl_transform *transform );
+
+/* set outbound transform of ssl context */
+void mbedtls_ssl_set_outbound_transform( mbedtls_ssl_context *ssl,
+                                         mbedtls_ssl_transform *transform );
+
 int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl );
 int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl );
 void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl );
@@ -1342,6 +1390,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
@@ -1399,6 +1463,53 @@
                    MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_ALL ) );
 }
 
+/**
+ * Given a list of key exchange modes, check if at least one of them is
+ * supported.
+ *
+ * \param[in] ssl  SSL context
+ * \param kex_modes_mask  Mask of the key exchange modes to check
+ *
+ * \return 0 if at least one of the key exchange modes is supported,
+ *         !=0 otherwise.
+ */
+static inline unsigned mbedtls_ssl_tls1_3_check_kex_modes( mbedtls_ssl_context *ssl,
+                                                           int kex_modes_mask )
+{
+    return( ( ssl->handshake->tls1_3_kex_modes & kex_modes_mask ) == 0 );
+}
+
+static inline int mbedtls_ssl_tls1_3_psk_enabled( mbedtls_ssl_context *ssl )
+{
+    return( ! mbedtls_ssl_tls1_3_check_kex_modes( ssl,
+                   MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK ) );
+}
+
+static inline int mbedtls_ssl_tls1_3_psk_ephemeral_enabled(
+                                                    mbedtls_ssl_context *ssl )
+{
+    return( ! mbedtls_ssl_tls1_3_check_kex_modes( ssl,
+                   MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_EPHEMERAL ) );
+}
+
+static inline int mbedtls_ssl_tls1_3_ephemeral_enabled( mbedtls_ssl_context *ssl )
+{
+    return( ! mbedtls_ssl_tls1_3_check_kex_modes( ssl,
+                   MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL ) );
+}
+
+static inline int mbedtls_ssl_tls1_3_some_ephemeral_enabled( mbedtls_ssl_context *ssl )
+{
+    return( ! mbedtls_ssl_tls1_3_check_kex_modes( ssl,
+                   MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL_ALL ) );
+}
+
+static inline int mbedtls_ssl_tls1_3_some_psk_enabled( mbedtls_ssl_context *ssl )
+{
+    return( ! mbedtls_ssl_tls1_3_check_kex_modes( ssl,
+                   MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_ALL ) );
+}
+
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
 
 /**
@@ -1474,6 +1585,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,
@@ -1486,13 +1605,19 @@
 int mbedtls_ssl_tls13_finish_handshake_msg( mbedtls_ssl_context *ssl,
                                             size_t buf_len,
                                             size_t msg_len );
-/*
- * Update checksum with handshake header
- */
+
 void mbedtls_ssl_tls13_add_hs_hdr_to_checksum( mbedtls_ssl_context *ssl,
                                                unsigned hs_type,
                                                size_t total_hs_len );
 
+/*
+ * Update checksum of handshake messages.
+ */
+void mbedtls_ssl_tls1_3_add_hs_msg_to_checksum( mbedtls_ssl_context *ssl,
+                                                unsigned hs_type,
+                                                unsigned char const *msg,
+                                                size_t msg_len );
+
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
 /*
  * Write TLS 1.3 Signature Algorithm extension
@@ -1506,4 +1631,11 @@
 
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
 
+/* Get handshake transcript */
+int mbedtls_ssl_get_handshake_transcript( mbedtls_ssl_context *ssl,
+                                          const mbedtls_md_type_t md,
+                                          unsigned char *dst,
+                                          size_t dst_len,
+                                          size_t *olen );
+
 #endif /* ssl_misc.h */
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index 2fe801a..3795c65 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -2101,7 +2101,7 @@
 static int ssl_swap_epochs( mbedtls_ssl_context *ssl )
 {
     mbedtls_ssl_transform *tmp_transform;
-    unsigned char tmp_out_ctr[8];
+    unsigned char tmp_out_ctr[MBEDTLS_SSL_SEQUENCE_NUMBER_LEN];
 
     if( ssl->transform_out == ssl->handshake->alt_transform_out )
     {
@@ -2117,9 +2117,11 @@
     ssl->handshake->alt_transform_out = tmp_transform;
 
     /* Swap epoch + sequence_number */
-    memcpy( tmp_out_ctr,                 ssl->cur_out_ctr,            8 );
-    memcpy( ssl->cur_out_ctr,            ssl->handshake->alt_out_ctr, 8 );
-    memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr,                 8 );
+    memcpy( tmp_out_ctr, ssl->cur_out_ctr, sizeof( tmp_out_ctr ) );
+    memcpy( ssl->cur_out_ctr, ssl->handshake->alt_out_ctr,
+            sizeof( ssl->cur_out_ctr ) );
+    memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr,
+            sizeof( ssl->handshake->alt_out_ctr ) );
 
     /* Adjust to the newly activated transform */
     mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out );
@@ -2562,7 +2564,7 @@
         mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
                            ssl->conf->transport, ssl->out_hdr + 1 );
 
-        memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 );
+        memcpy( ssl->out_ctr, ssl->cur_out_ctr, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN );
         MBEDTLS_PUT_UINT16_BE( len, ssl->out_len, 0);
 
         if( ssl->transform_out != NULL )
@@ -2574,7 +2576,7 @@
             rec.data_len    = ssl->out_msglen;
             rec.data_offset = ssl->out_msg - rec.buf;
 
-            memcpy( &rec.ctr[0], ssl->out_ctr, 8 );
+            memcpy( &rec.ctr[0], ssl->out_ctr, sizeof( rec.ctr ) );
             mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
                                        ssl->conf->transport, rec.ver );
             rec.type = ssl->out_msgtype;
@@ -3649,9 +3651,12 @@
 #endif
         {
             unsigned i;
-            for( i = 8; i > mbedtls_ssl_ep_len( ssl ); i-- )
+            for( i = MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
+                 i > mbedtls_ssl_ep_len( ssl ); i-- )
+            {
                 if( ++ssl->in_ctr[i - 1] != 0 )
                     break;
+            }
 
             /* The loop goes to its end iff the counter is wrapping */
             if( i == mbedtls_ssl_ep_len( ssl ) )
@@ -4791,7 +4796,7 @@
     }
     else
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
-    memset( ssl->in_ctr, 0, 8 );
+    memset( ssl->in_ctr, 0, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN );
 
     mbedtls_ssl_update_in_pointers( ssl );
 
@@ -4827,12 +4832,12 @@
     {
         ssl->out_ctr = ssl->out_hdr +  3;
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
-        ssl->out_cid = ssl->out_ctr +  8;
+        ssl->out_cid = ssl->out_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
         ssl->out_len = ssl->out_cid;
         if( transform != NULL )
             ssl->out_len += transform->out_cid_len;
 #else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
-        ssl->out_len = ssl->out_ctr + 8;
+        ssl->out_len = ssl->out_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
         ssl->out_iv  = ssl->out_len + 2;
     }
@@ -4881,17 +4886,17 @@
          * ssl_parse_record_header(). */
         ssl->in_ctr = ssl->in_hdr +  3;
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
-        ssl->in_cid = ssl->in_ctr +  8;
+        ssl->in_cid = ssl->in_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
         ssl->in_len = ssl->in_cid; /* Default: no CID */
 #else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
-        ssl->in_len = ssl->in_ctr + 8;
+        ssl->in_len = ssl->in_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
         ssl->in_iv  = ssl->in_len + 2;
     }
     else
 #endif
     {
-        ssl->in_ctr = ssl->in_hdr - 8;
+        ssl->in_ctr = ssl->in_hdr - MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
         ssl->in_len = ssl->in_hdr + 3;
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
         ssl->in_cid = ssl->in_len;
@@ -5065,9 +5070,11 @@
     }
 
     in_ctr_cmp = memcmp( ssl->in_ctr + ep_len,
-                        ssl->conf->renego_period + ep_len, 8 - ep_len );
-    out_ctr_cmp = memcmp( ssl->cur_out_ctr + ep_len,
-                          ssl->conf->renego_period + ep_len, 8 - ep_len );
+                         &ssl->conf->renego_period[ep_len],
+                         MBEDTLS_SSL_SEQUENCE_NUMBER_LEN - ep_len );
+    out_ctr_cmp = memcmp( &ssl->cur_out_ctr[ep_len],
+                          &ssl->conf->renego_period[ep_len],
+                          sizeof( ssl->cur_out_ctr ) - ep_len );
 
     if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 )
     {
@@ -5551,6 +5558,20 @@
     mbedtls_platform_zeroize( transform, sizeof( mbedtls_ssl_transform ) );
 }
 
+void mbedtls_ssl_set_inbound_transform( mbedtls_ssl_context *ssl,
+                                        mbedtls_ssl_transform *transform )
+{
+    ssl->transform_in = transform;
+    memset( ssl->in_ctr, 0, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN );
+}
+
+void mbedtls_ssl_set_outbound_transform( mbedtls_ssl_context *ssl,
+                                         mbedtls_ssl_transform *transform )
+{
+    ssl->transform_out = transform;
+    memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) );
+}
+
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
 
 void mbedtls_ssl_buffering_free( mbedtls_ssl_context *ssl )
@@ -5639,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_srv.c b/library/ssl_srv.c
index b8c4314..e27fdff 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -1220,7 +1220,8 @@
             return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
 
-        memcpy( ssl->cur_out_ctr + 2, ssl->in_ctr + 2, 6 );
+        memcpy( &ssl->cur_out_ctr[2], ssl->in_ctr + 2,
+                sizeof( ssl->cur_out_ctr ) - 2 );
 
 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
         if( mbedtls_ssl_dtls_replay_check( ssl ) != 0 )
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 3604192..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 )
@@ -2820,10 +2820,12 @@
 
         /* Remember current epoch settings for resending */
         ssl->handshake->alt_transform_out = ssl->transform_out;
-        memcpy( ssl->handshake->alt_out_ctr, ssl->cur_out_ctr, 8 );
+        memcpy( ssl->handshake->alt_out_ctr, ssl->cur_out_ctr,
+                sizeof( ssl->handshake->alt_out_ctr ) );
 
         /* Set sequence_number to zero */
-        memset( ssl->cur_out_ctr + 2, 0, 6 );
+        memset( &ssl->cur_out_ctr[2], 0, sizeof( ssl->cur_out_ctr ) - 2 );
+
 
         /* Increment epoch */
         for( i = 2; i > 0; i-- )
@@ -2839,7 +2841,7 @@
     }
     else
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
-    memset( ssl->cur_out_ctr, 0, 8 );
+    memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) );
 
     ssl->transform_out = ssl->transform_negotiate;
     ssl->session_out = ssl->session_negotiate;
@@ -5170,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 )
     {
@@ -5199,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 );
 }
 
@@ -5775,11 +5794,11 @@
     }
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
-    used += 8;
+    used += MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
     if( used <= buf_len )
     {
-        memcpy( p, ssl->cur_out_ctr, 8 );
-        p += 8;
+        memcpy( p, ssl->cur_out_ctr, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN );
+        p += MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
     }
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
@@ -6035,11 +6054,10 @@
     ssl->disable_datagram_packing = *p++;
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
-    if( (size_t)( end - p ) < 8 )
+    if( (size_t)( end - p ) < sizeof( ssl->cur_out_ctr ) )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-    memcpy( ssl->cur_out_ctr, p, 8 );
-    p += 8;
+    memcpy( ssl->cur_out_ctr, p, sizeof( ssl->cur_out_ctr ) );
+    p += sizeof( ssl->cur_out_ctr );
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
     if( (size_t)( end - p ) < 2 )
@@ -6978,4 +6996,106 @@
 
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+int mbedtls_ssl_get_handshake_transcript( mbedtls_ssl_context *ssl,
+                                          const mbedtls_md_type_t md,
+                                          unsigned char *dst,
+                                          size_t dst_len,
+                                          size_t *olen )
+{
+    ((void) ssl);
+    ((void) md);
+    ((void) dst);
+    ((void) dst_len);
+    *olen = 0;
+    return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE);
+}
+#else /* MBEDTLS_USE_PSA_CRYPTO */
+
+#if defined(MBEDTLS_SHA384_C)
+static int ssl_get_handshake_transcript_sha384( mbedtls_ssl_context *ssl,
+                                                unsigned char *dst,
+                                                size_t dst_len,
+                                                size_t *olen )
+{
+    int ret;
+    mbedtls_sha512_context sha512;
+
+    if( dst_len < 48 )
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+
+    mbedtls_sha512_init( &sha512 );
+    mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
+
+    if( ( ret = mbedtls_sha512_finish( &sha512, dst ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha512_finish", ret );
+        goto exit;
+    }
+
+    *olen = 48;
+
+exit:
+
+    mbedtls_sha512_free( &sha512 );
+    return( ret );
+}
+#endif /* MBEDTLS_SHA384_C */
+
+#if defined(MBEDTLS_SHA256_C)
+static int ssl_get_handshake_transcript_sha256( mbedtls_ssl_context *ssl,
+                                                unsigned char *dst,
+                                                size_t dst_len,
+                                                size_t *olen )
+{
+    int ret;
+    mbedtls_sha256_context sha256;
+
+    if( dst_len < 32 )
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+
+    mbedtls_sha256_init( &sha256 );
+    mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
+
+    if( ( ret = mbedtls_sha256_finish( &sha256, dst ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha256_finish", ret );
+        goto exit;
+    }
+
+    *olen = 32;
+
+exit:
+
+    mbedtls_sha256_free( &sha256 );
+    return( ret );
+}
+#endif /* MBEDTLS_SHA256_C */
+
+int mbedtls_ssl_get_handshake_transcript( mbedtls_ssl_context *ssl,
+                                          const mbedtls_md_type_t md,
+                                          unsigned char *dst,
+                                          size_t dst_len,
+                                          size_t *olen )
+{
+    switch( md )
+    {
+
+#if defined(MBEDTLS_SHA384_C)
+    case MBEDTLS_MD_SHA384:
+        return( ssl_get_handshake_transcript_sha384( ssl, dst, dst_len, olen ) );
+#endif /* MBEDTLS_SHA384_C */
+
+#if defined(MBEDTLS_SHA256_C)
+    case MBEDTLS_MD_SHA256:
+        return( ssl_get_handshake_transcript_sha256( ssl, dst, dst_len, olen ) );
+#endif /* MBEDTLS_SHA256_C */
+
+    default:
+        break;
+    }
+    return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+}
+#endif /* !MBEDTLS_USE_PSA_CRYPTO */
+
 #endif /* MBEDTLS_SSL_TLS_C */
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 5c20f29..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,
@@ -66,6 +104,15 @@
     return( ret );
 }
 
+void mbedtls_ssl_tls1_3_add_hs_msg_to_checksum( mbedtls_ssl_context *ssl,
+                                                unsigned hs_type,
+                                                unsigned char const *msg,
+                                                size_t msg_len )
+{
+    mbedtls_ssl_tls13_add_hs_hdr_to_checksum( ssl, hs_type, msg_len );
+    ssl->handshake->update_checksum( ssl, msg, msg_len );
+}
+
 void mbedtls_ssl_tls13_add_hs_hdr_to_checksum( mbedtls_ssl_context *ssl,
                                                unsigned hs_type,
                                                size_t total_hs_len )
diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c
index 7aec21d..b07c1c3 100644
--- a/library/ssl_tls13_keys.c
+++ b/library/ssl_tls13_keys.c
@@ -21,14 +21,16 @@
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
 
-#include "mbedtls/hkdf.h"
-#include "ssl_misc.h"
-#include "ssl_tls13_keys.h"
-#include "mbedtls/debug.h"
-
 #include <stdint.h>
 #include <string.h>
 
+#include "mbedtls/hkdf.h"
+#include "mbedtls/debug.h"
+#include "mbedtls/error.h"
+
+#include "ssl_misc.h"
+#include "ssl_tls13_keys.h"
+
 #define MBEDTLS_SSL_TLS1_3_LABEL( name, string )       \
     .name = string,
 
@@ -820,4 +822,28 @@
     return( 0 );
 }
 
+int mbedtls_ssl_tls1_3_key_schedule_stage_early( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    mbedtls_md_type_t md_type;
+
+    if( ssl->handshake->ciphersuite_info == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher suite info not found" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    md_type = ssl->handshake->ciphersuite_info->mac;
+
+    ret = mbedtls_ssl_tls1_3_evolve_secret( md_type, NULL, NULL, 0,
+                                ssl->handshake->tls1_3_master_secrets.early );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls1_3_evolve_secret", ret );
+        return( ret );
+    }
+
+    return( 0 );
+}
+
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
diff --git a/library/ssl_tls13_keys.h b/library/ssl_tls13_keys.h
index ca892b1..866aae9 100644
--- a/library/ssl_tls13_keys.h
+++ b/library/ssl_tls13_keys.h
@@ -531,4 +531,26 @@
                                           mbedtls_ssl_key_set const *traffic_keys,
                                           mbedtls_ssl_context *ssl );
 
+/*
+ * TLS 1.3 key schedule evolutions
+ *
+ *   Early -> Handshake -> Application
+ *
+ * Small wrappers around mbedtls_ssl_tls1_3_evolve_secret().
+ */
+
+/**
+ * \brief Begin TLS 1.3 key schedule by calculating early secret.
+ *
+ *        The TLS 1.3 key schedule can be viewed as a simple state machine
+ *        with states Initial -> Early -> Handshake -> Application, and
+ *        this function represents the Initial -> Early transition.
+ *
+ * \param ssl  The SSL context to operate on.
+ *
+ * \returns    \c 0 on success.
+ * \returns    A negative error code on failure.
+ */
+int mbedtls_ssl_tls1_3_key_schedule_stage_early( mbedtls_ssl_context *ssl );
+
 #endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */
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/dh_client.c b/programs/pkey/dh_client.c
index eccb42a..d633e4d 100644
--- a/programs/pkey/dh_client.c
+++ b/programs/pkey/dh_client.c
@@ -270,7 +270,9 @@
     mbedtls_printf( "...\n  . Receiving and decrypting the ciphertext" );
     fflush( stdout );
 
-    mbedtls_aes_setkey_dec( &aes, buf, 256 );
+    ret = mbedtls_aes_setkey_dec( &aes, buf, 256 );
+    if( ret != 0 )
+        goto exit;
 
     memset( buf, 0, sizeof( buf ) );
 
@@ -280,7 +282,9 @@
         goto exit;
     }
 
-    mbedtls_aes_crypt_ecb( &aes, MBEDTLS_AES_DECRYPT, buf, buf );
+    ret = mbedtls_aes_crypt_ecb( &aes, MBEDTLS_AES_DECRYPT, buf, buf );
+    if( ret != 0 )
+        goto exit;
     buf[16] = '\0';
     mbedtls_printf( "\n  . Plaintext is \"%s\"\n\n", (char *) buf );
 
diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c
index 0ddb85c..75713ff 100644
--- a/programs/pkey/dh_server.c
+++ b/programs/pkey/dh_server.c
@@ -290,9 +290,13 @@
     mbedtls_printf( "...\n  . Encrypting and sending the ciphertext" );
     fflush( stdout );
 
-    mbedtls_aes_setkey_enc( &aes, buf, 256 );
+    ret = mbedtls_aes_setkey_enc( &aes, buf, 256 );
+    if( ret != 0 )
+        goto exit;
     memcpy( buf, PLAINTEXT, 16 );
-    mbedtls_aes_crypt_ecb( &aes, MBEDTLS_AES_ENCRYPT, buf, buf );
+    ret = mbedtls_aes_crypt_ecb( &aes, MBEDTLS_AES_ENCRYPT, buf, buf );
+    if( ret != 0 )
+        goto exit;
 
     if( ( ret = mbedtls_net_send( &client_fd, buf, 16 ) ) != 16 )
     {
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/test/benchmark.c b/programs/test/benchmark.c
index 5985caf..d3faad9 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -674,7 +674,8 @@
     {
         mbedtls_des3_context des3;
         mbedtls_des3_init( &des3 );
-        mbedtls_des3_set3key_enc( &des3, tmp );
+        if( mbedtls_des3_set3key_enc( &des3, tmp ) != 0 )
+            mbedtls_exit( 1 );
         TIME_AND_TSC( "3DES",
                 mbedtls_des3_crypt_cbc( &des3, MBEDTLS_DES_ENCRYPT, BUFSIZE, tmp, buf, buf ) );
         mbedtls_des3_free( &des3 );
@@ -684,7 +685,8 @@
     {
         mbedtls_des_context des;
         mbedtls_des_init( &des );
-        mbedtls_des_setkey_enc( &des, tmp );
+        if( mbedtls_des_setkey_enc( &des, tmp ) != 0 )
+            mbedtls_exit( 1 );
         TIME_AND_TSC( "DES",
                 mbedtls_des_crypt_cbc( &des, MBEDTLS_DES_ENCRYPT, BUFSIZE, tmp, buf, buf ) );
         mbedtls_des_free( &des );
@@ -722,7 +724,7 @@
 
             memset( buf, 0, sizeof( buf ) );
             memset( tmp, 0, sizeof( tmp ) );
-            mbedtls_aes_setkey_enc( &aes, tmp, keysize );
+            CHECK_AND_CONTINUE( mbedtls_aes_setkey_enc( &aes, tmp, keysize ) );
 
             TIME_AND_TSC( title,
                 mbedtls_aes_crypt_cbc( &aes, MBEDTLS_AES_ENCRYPT, BUFSIZE, tmp, buf, buf ) );
@@ -743,7 +745,7 @@
 
             memset( buf, 0, sizeof( buf ) );
             memset( tmp, 0, sizeof( tmp ) );
-            mbedtls_aes_xts_setkey_enc( &ctx, tmp, keysize * 2 );
+            CHECK_AND_CONTINUE( mbedtls_aes_xts_setkey_enc( &ctx, tmp, keysize * 2 ) );
 
             TIME_AND_TSC( title,
                     mbedtls_aes_crypt_xts( &ctx, MBEDTLS_AES_ENCRYPT, BUFSIZE,
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 f30795c..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
@@ -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/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..b5ddc37 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -753,7 +753,7 @@
 # check if the given command uses dtls and sets global variable DTLS
 detect_dtls() {
     case "$1" in
-        *dtls=1*|-dtls|-u) DTLS=1;;
+        *dtls=1*|*-dtls*|*-u*) DTLS=1;;
         *) DTLS=0;;
     esac
 }
@@ -1309,22 +1309,24 @@
 
 # fix commands to use this port, force IPv4 while at it
 # +SRV_PORT will be replaced by either $SRV_PORT or $PXY_PORT later
+# Note: Using 'localhost' rather than 127.0.0.1 here is unwise, as on many
+# machines that will resolve to ::1, and we don't want ipv6 here.
 P_SRV="$P_SRV server_addr=127.0.0.1 server_port=$SRV_PORT"
 P_CLI="$P_CLI server_addr=127.0.0.1 server_port=+SRV_PORT"
 P_PXY="$P_PXY server_addr=127.0.0.1 server_port=$SRV_PORT listen_addr=127.0.0.1 listen_port=$PXY_PORT ${SEED:+"seed=$SEED"}"
 O_SRV="$O_SRV -accept $SRV_PORT"
-O_CLI="$O_CLI -connect localhost:+SRV_PORT"
+O_CLI="$O_CLI -connect 127.0.0.1:+SRV_PORT"
 G_SRV="$G_SRV -p $SRV_PORT"
 G_CLI="$G_CLI -p +SRV_PORT"
 
 if [ -n "${OPENSSL_LEGACY:-}" ]; then
     O_LEGACY_SRV="$O_LEGACY_SRV -accept $SRV_PORT -dhparam data_files/dhparams.pem"
-    O_LEGACY_CLI="$O_LEGACY_CLI -connect localhost:+SRV_PORT"
+    O_LEGACY_CLI="$O_LEGACY_CLI -connect 127.0.0.1:+SRV_PORT"
 fi
 
 if [ -n "${OPENSSL_NEXT:-}" ]; then
     O_NEXT_SRV="$O_NEXT_SRV -accept $SRV_PORT"
-    O_NEXT_CLI="$O_NEXT_CLI -connect localhost:+SRV_PORT"
+    O_NEXT_CLI="$O_NEXT_CLI -connect 127.0.0.1:+SRV_PORT"
 fi
 
 if [ -n "${GNUTLS_NEXT_SERV:-}" ]; then
@@ -2694,10 +2696,13 @@
             -c "parse new session ticket" \
             -c "a session has been resumed"
 
+# For reasons that aren't fully understood, this test randomly fails with high
+# probability with OpenSSL 1.0.2g on the CI, see #5012.
+requires_openssl_next
 run_test    "Session resume using tickets, DTLS: openssl client" \
             "$P_SRV dtls=1 debug_level=3 tickets=1" \
-            "( $O_CLI -dtls -sess_out $SESSION; \
-               $O_CLI -dtls -sess_in $SESSION; \
+            "( $O_NEXT_CLI -dtls -sess_out $SESSION; \
+               $O_NEXT_CLI -dtls -sess_in $SESSION; \
                rm -f $SESSION )" \
             0 \
             -s "found session ticket extension" \
@@ -2894,10 +2899,13 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+# For reasons that aren't fully understood, this test randomly fails with high
+# probability with OpenSSL 1.0.2g on the CI, see #5012.
+requires_openssl_next
 run_test    "Session resume using cache, DTLS: openssl client" \
             "$P_SRV dtls=1 debug_level=3 tickets=0" \
-            "( $O_CLI -dtls -sess_out $SESSION; \
-               $O_CLI -dtls -sess_in $SESSION; \
+            "( $O_NEXT_CLI -dtls -sess_out $SESSION; \
+               $O_NEXT_CLI -dtls -sess_in $SESSION; \
                rm -f $SESSION )" \
             0 \
             -s "found session ticket extension" \
@@ -8660,29 +8668,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_aes.function b/tests/suites/test_suite_aes.function
index 1892c25..52af8e0 100644
--- a/tests/suites/test_suite_aes.function
+++ b/tests/suites/test_suite_aes.function
@@ -67,7 +67,7 @@
 
     mbedtls_aes_init( &ctx );
 
-    mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
+    TEST_ASSERT( mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 ) == 0 );
     TEST_ASSERT( mbedtls_aes_crypt_cbc( &ctx, MBEDTLS_AES_ENCRYPT, src_str->len, iv_str->x, src_str->x, output ) == cbc_result );
     if( cbc_result == 0 )
     {
@@ -92,7 +92,7 @@
     memset(output, 0x00, 100);
     mbedtls_aes_init( &ctx );
 
-    mbedtls_aes_setkey_dec( &ctx, key_str->x, key_str->len * 8 );
+    TEST_ASSERT( mbedtls_aes_setkey_dec( &ctx, key_str->x, key_str->len * 8 ) == 0 );
     TEST_ASSERT( mbedtls_aes_crypt_cbc( &ctx, MBEDTLS_AES_DECRYPT, src_str->len, iv_str->x, src_str->x, output ) == cbc_result );
     if( cbc_result == 0)
     {
@@ -241,7 +241,7 @@
     mbedtls_aes_init( &ctx );
 
 
-    mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
+    TEST_ASSERT( mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 ) == 0 );
     TEST_ASSERT( mbedtls_aes_crypt_cfb128( &ctx, MBEDTLS_AES_ENCRYPT, 16, &iv_offset, iv_str->x, src_str->x, output ) == 0 );
 
     TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
@@ -263,7 +263,7 @@
     mbedtls_aes_init( &ctx );
 
 
-    mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
+    TEST_ASSERT( mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 ) == 0 );
     TEST_ASSERT( mbedtls_aes_crypt_cfb128( &ctx, MBEDTLS_AES_DECRYPT, 16, &iv_offset, iv_str->x, src_str->x, output ) == 0 );
 
     TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
@@ -284,7 +284,7 @@
     mbedtls_aes_init( &ctx );
 
 
-    mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
+    TEST_ASSERT( mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 ) == 0 );
     TEST_ASSERT( mbedtls_aes_crypt_cfb8( &ctx, MBEDTLS_AES_ENCRYPT, src_str->len, iv_str->x, src_str->x, output ) == 0 );
 
     TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
@@ -306,7 +306,7 @@
     mbedtls_aes_init( &ctx );
 
 
-    mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
+    TEST_ASSERT( mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 ) == 0 );
     TEST_ASSERT( mbedtls_aes_crypt_cfb8( &ctx, MBEDTLS_AES_DECRYPT, src_str->len, iv_str->x, src_str->x, output ) == 0 );
 
     TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
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_des.function b/tests/suites/test_suite_des.function
index 5b24935..7256fb5 100644
--- a/tests/suites/test_suite_des.function
+++ b/tests/suites/test_suite_des.function
@@ -24,7 +24,7 @@
     mbedtls_des_init( &ctx );
 
 
-    mbedtls_des_setkey_enc( &ctx, key_str->x );
+    TEST_ASSERT( mbedtls_des_setkey_enc( &ctx, key_str->x ) == 0 );
     TEST_ASSERT( mbedtls_des_crypt_ecb( &ctx, src_str->x, output ) == 0 );
 
     TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
@@ -44,7 +44,7 @@
     mbedtls_des_init( &ctx );
 
 
-    mbedtls_des_setkey_dec( &ctx, key_str->x );
+    TEST_ASSERT( mbedtls_des_setkey_dec( &ctx, key_str->x ) == 0 );
     TEST_ASSERT( mbedtls_des_crypt_ecb( &ctx, src_str->x, output ) == 0 );
 
     TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
@@ -65,7 +65,7 @@
     mbedtls_des_init( &ctx );
 
 
-    mbedtls_des_setkey_enc( &ctx, key_str->x );
+    TEST_ASSERT( mbedtls_des_setkey_enc( &ctx, key_str->x ) == 0 );
     TEST_ASSERT( mbedtls_des_crypt_cbc( &ctx, MBEDTLS_DES_ENCRYPT, src_str->len, iv_str->x, src_str->x, output ) == cbc_result );
     if( cbc_result == 0 )
     {
@@ -91,7 +91,7 @@
     mbedtls_des_init( &ctx );
 
 
-    mbedtls_des_setkey_dec( &ctx, key_str->x );
+    TEST_ASSERT( mbedtls_des_setkey_dec( &ctx, key_str->x ) == 0 );
     TEST_ASSERT( mbedtls_des_crypt_cbc( &ctx, MBEDTLS_DES_DECRYPT, src_str->len, iv_str->x, src_str->x, output ) == cbc_result );
     if( cbc_result == 0 )
     {
@@ -117,9 +117,9 @@
 
 
     if( key_count == 2 )
-        mbedtls_des3_set2key_enc( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set2key_enc( &ctx, key_str->x ) == 0 );
     else if( key_count == 3 )
-        mbedtls_des3_set3key_enc( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set3key_enc( &ctx, key_str->x ) == 0 );
     else
         TEST_ASSERT( 0 );
 
@@ -144,9 +144,9 @@
 
 
     if( key_count == 2 )
-        mbedtls_des3_set2key_dec( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set2key_dec( &ctx, key_str->x ) == 0 );
     else if( key_count == 3 )
-        mbedtls_des3_set3key_dec( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set3key_dec( &ctx, key_str->x ) == 0 );
     else
         TEST_ASSERT( 0 );
 
@@ -172,9 +172,9 @@
 
 
     if( key_count == 2 )
-        mbedtls_des3_set2key_enc( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set2key_enc( &ctx, key_str->x ) == 0 );
     else if( key_count == 3 )
-        mbedtls_des3_set3key_enc( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set3key_enc( &ctx, key_str->x ) == 0 );
     else
         TEST_ASSERT( 0 );
 
@@ -205,9 +205,9 @@
 
 
     if( key_count == 2 )
-        mbedtls_des3_set2key_dec( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set2key_dec( &ctx, key_str->x ) == 0 );
     else if( key_count == 3 )
-        mbedtls_des3_set3key_dec( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set3key_dec( &ctx, key_str->x ) == 0 );
     else
         TEST_ASSERT( 0 );
 
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 ) ?