Merge pull request #5382 from lhuang04/tls13_f_export_keys

Swap the client and server random for TLS 1.3 f_export_keys
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 63076f4..c1beccd 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -4,5 +4,5 @@
       url: mailto:mbed-tls-security@lists.trustedfirmware.org
       about: Report a security vulnerability.
     - name: Mbed TLS mailing list
-      url: https://lists.trustedfirmware.org/mailman/listinfo/mbed-tls
+      url: https://lists.trustedfirmware.org/mailman3/lists/mbed-tls.lists.trustedfirmware.org
       about: Mbed TLS community support and general discussion.
diff --git a/.gitignore b/.gitignore
index 26986d6..8824ece 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,6 +23,11 @@
 # generated by scripts/memory.sh
 massif-*
 
+# Eclipse project files
+.cproject
+.project
+/.settings
+
 # MSVC build artifacts:
 *.exe
 *.pdb
diff --git a/BRANCHES.md b/BRANCHES.md
index 60218b0..a6ddfd5 100644
--- a/BRANCHES.md
+++ b/BRANCHES.md
@@ -1,6 +1,6 @@
 # Maintained branches
 
-At any point in time, we have a number of maintained branches consisting of:
+At any point in time, we have a number of maintained branches, currently consisting of:
 
 - The [`master`](https://github.com/ARMmbed/mbedtls/tree/master) branch:
   this always contains the latest release, including all publicly available
@@ -9,11 +9,18 @@
   this is where the current major version of Mbed TLS (version 3.x) is being
   prepared. It has API changes that make it incompatible with Mbed TLS 2.x,
   as well as all the new features and bug fixes and security fixes.
-- The [`development_2.x`](https://github.com/ARMmbed/mbedtls/tree/development_2.x) branch:
-  this branch retains the API of Mbed TLS 2.x, and has a subset of the
-  features added after Mbed TLS 2.26.0 and bug fixes and security fixes.
-- One or more long-time support (LTS) branches:
-  these only get bug fixes and security fixes.
+- One or more long-time support (LTS) branches: these only get bug fixes and
+  security fixes. Currently, the only supported LTS branch is:
+  [`mbedtls-2.28`](https://github.com/ARMmbed/mbedtls/tree/mbedtls-2.28).
+- For a short time we also have the previous LTS, which has recently ended its
+  support period,
+  [`mbedtls-2.16`](https://github.com/ARMmbed/mbedtls/tree/mbedtls-2.16).
+  This branch will move into the `archive` namespace around the time of
+  the next release.
+
+We retain a number of historical branches, whose names are prefixed by `archive/`,
+such as [`archive/mbedtls-2.7`](https://github.com/ARMmbed/mbedtls/tree/archive/mbedtls-2.7).
+These branches will not receive any changes or updates.
 
 We use [Semantic Versioning](https://semver.org/). In particular, we maintain
 API compatibility in the `master` branch across minor version changes (e.g.
@@ -70,9 +77,8 @@
 
 - [master](https://github.com/ARMmbed/mbedtls/tree/master)
 - [`development`](https://github.com/ARMmbed/mbedtls/)
-- [`development_2.x`](https://github.com/ARMmbed/mbedtls/tree/development_2.x)
-- [`mbedtls-2.16`](https://github.com/ARMmbed/mbedtls/tree/mbedtls-2.16)
- maintained until at least the end of 2021, see
-  <https://tls.mbed.org/tech-updates/blog/announcing-lts-branch-mbedtls-2.16>
+- [`mbedtls-2.28`](https://github.com/ARMmbed/mbedtls/tree/mbedtls-2.28)
+ maintained until at least the end of 2024, see
+  <https://github.com/ARMmbed/mbedtls/releases/tag/v2.28.0>.
 
 Users are urged to always use the latest version of a maintained branch.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index dcaa360..cd41578 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -14,7 +14,7 @@
 
 Making a Contribution
 ---------------------
-1. [Check for open issues](https://github.com/ARMmbed/mbedtls/issues) or [start a discussion](https://lists.trustedfirmware.org/mailman/listinfo/mbed-tls) around a feature idea or a bug.
+1. [Check for open issues](https://github.com/ARMmbed/mbedtls/issues) or [start a discussion](https://lists.trustedfirmware.org/mailman3/lists/mbed-tls.lists.trustedfirmware.org) around a feature idea or a bug.
 1. Fork the [Mbed TLS repository on GitHub](https://github.com/ARMmbed/mbedtls) to start making your changes. As a general rule, you should use the ["development" branch](https://github.com/ARMmbed/mbedtls/tree/development) as a basis.
 1. Write a test which shows that the bug was fixed or that the feature works as expected.
 1. Send a pull request (PR) and work with us until it gets merged and published. Contributions may need some modifications, so a few rounds of review and fixing may be necessary. We will include your name in the ChangeLog :)
diff --git a/ChangeLog.d/Driver_wrapper_codegen_1.0.txt b/ChangeLog.d/Driver_wrapper_codegen_1.0.txt
new file mode 100644
index 0000000..a4d9c54
--- /dev/null
+++ b/ChangeLog.d/Driver_wrapper_codegen_1.0.txt
@@ -0,0 +1,5 @@
+Changes
+   * The file library/psa_crypto_driver_wrappers.c is now generated
+     from a template. In the future, the generation will support
+     driver descriptions. For the time being, to customize this file,
+     see docs/proposed/psa-driver-wrappers-codegen-migration-guide.md
diff --git a/ChangeLog.d/chacha20_invalid_iv_len_fix.txt b/ChangeLog.d/chacha20_invalid_iv_len_fix.txt
new file mode 100644
index 0000000..af35e2a
--- /dev/null
+++ b/ChangeLog.d/chacha20_invalid_iv_len_fix.txt
@@ -0,0 +1,4 @@
+Default behavior changes
+   * mbedtls_cipher_set_iv will now fail with ChaCha20 and ChaCha20+Poly1305
+     for IV lengths other than 12. The library was silently overwriting this
+     length with 12, but did not inform the caller about it. Fixes #4301.
diff --git a/ChangeLog.d/mbedtls_ssl_comfig_defaults-memleak.txt b/ChangeLog.d/mbedtls_ssl_comfig_defaults-memleak.txt
new file mode 100644
index 0000000..d55c016
--- /dev/null
+++ b/ChangeLog.d/mbedtls_ssl_comfig_defaults-memleak.txt
@@ -0,0 +1,2 @@
+Bugfix
+   * Fix memory leak if mbedtls_ssl_config_defaults() call is repeated
diff --git a/ChangeLog.d/mbedtls_ssl_get_ciphersuite_id.txt b/ChangeLog.d/mbedtls_ssl_get_ciphersuite_id.txt
new file mode 100644
index 0000000..c4235b7
--- /dev/null
+++ b/ChangeLog.d/mbedtls_ssl_get_ciphersuite_id.txt
@@ -0,0 +1,3 @@
+Features
+   * Add accessor to obtain ciphersuite id from ssl context.
+   * Add accessors to get members from ciphersuite info.
diff --git a/ChangeLog.d/pkparse-pkcs8-unencrypted-no-alloc.txt b/ChangeLog.d/pkparse-pkcs8-unencrypted-no-alloc.txt
new file mode 100644
index 0000000..9d7a32e
--- /dev/null
+++ b/ChangeLog.d/pkparse-pkcs8-unencrypted-no-alloc.txt
@@ -0,0 +1,3 @@
+Changes
+   * In mbedtls_pk_parse_key(), if no password is provided, don't allocate a
+     temporary variable on the heap. Suggested by Sergey Kanatov in #5304.
diff --git a/ChangeLog.d/psa_aead_singleshot_error.txt b/ChangeLog.d/psa_aead_singleshot_error.txt
new file mode 100644
index 0000000..7243874
--- /dev/null
+++ b/ChangeLog.d/psa_aead_singleshot_error.txt
@@ -0,0 +1,4 @@
+Changes
+   * Return PSA_ERROR_INVALID_ARGUMENT if the algorithm passed to singleshot
+     AEAD functions is not an AEAD algorithm. This aligns them with the
+     multipart functions, and the PSA Crypto API 1.1 spec.
diff --git a/SUPPORT.md b/SUPPORT.md
index 1bc0695..dab7ac5 100644
--- a/SUPPORT.md
+++ b/SUPPORT.md
@@ -7,9 +7,9 @@
 - the `docs` directory in the source tree;
 - the [Mbed TLS knowledge Base](https://tls.mbed.org/kb);
 - the [Mbed TLS mailing-list
-  archives](https://lists.trustedfirmware.org/pipermail/mbed-tls/).
+  archives](https://lists.trustedfirmware.org/archives/list/mbed-tls@lists.trustedfirmware.org/).
 
 ## Asking Questions
 
 If you can't find your answer in the above sources, please use the [Mbed TLS
-mailing list](https://lists.trustedfirmware.org/mailman/listinfo/mbed-tls).
+mailing list](https://lists.trustedfirmware.org/mailman3/lists/mbed-tls.lists.trustedfirmware.org).
diff --git a/docs/proposed/psa-driver-wrappers-codegen-migration-guide.md b/docs/proposed/psa-driver-wrappers-codegen-migration-guide.md
new file mode 100644
index 0000000..4f82bed
--- /dev/null
+++ b/docs/proposed/psa-driver-wrappers-codegen-migration-guide.md
@@ -0,0 +1,32 @@
+Migrating to an auto genrated psa_crypto_driver_wrappers.c file
+===============================================================
+
+**This is a specification of work in progress. The implementation is not yet merged into Mbed TLS.**
+
+This document describes how to migrate to the auto generated psa_crypto_driver_wrappers.c file.
+It is meant to give the library user migration guidelines while the Mbed TLS project tides over multiple minor revs of version 1.0, after which this will be merged into psa-driver-interface.md.
+
+## Introduction
+
+The design of the Driver Wrappers code generation is based on the design proposal https://github.com/ARMmbed/mbedtls/pull/5067
+During the process of implementation there might be minor variations wrt versioning and broader implementation specific ideas, but the design remains the same.
+
+## Prerequisites
+
+Python3 and Jinja2 rev 2.10.1
+
+## Feature Version
+
+1.0
+
+### What's critical for a migrating user
+
+The Driver Wrapper auto generation project is designed to use a python templating library ( Jinja2 ) to render templates based on drivers that are defined using a Driver descrioption JSON file(s).
+
+While that is the larger goal, for version 1.0 here's what's changed
+
+#### What's changed
+
+(1) psa_crypto_driver_wrappers.c will from this point on be auto generated.
+(2) The auto generation is based on the template file at scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja.
+(3) So while all driver wrapper templating support is yet to come in, the library user will need to patch into the template file as needed, this could be read as replacing the template file with the current psa_crypto_driver_wrappers.c file maintained by the library user.
diff --git a/include/mbedtls/asn1.h b/include/mbedtls/asn1.h
index 4746c1c..30b0ed2 100644
--- a/include/mbedtls/asn1.h
+++ b/include/mbedtls/asn1.h
@@ -58,7 +58,7 @@
 /** Buffer too small when writing ASN.1 data structure. */
 #define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL                    -0x006C
 
-/* \} name */
+/** \} name ASN1 Error codes */
 
 /**
  * \name DER constants
@@ -118,8 +118,7 @@
 #define MBEDTLS_ASN1_TAG_PC_MASK             0x20
 #define MBEDTLS_ASN1_TAG_VALUE_MASK          0x1F
 
-/* \} name */
-/* \} addtogroup asn1_module */
+/** \} name DER constants */
 
 /** Returns the size of the binary string, without the trailing \\0 */
 #define MBEDTLS_OID_SIZE(x) (sizeof(x) - 1)
@@ -626,6 +625,9 @@
  */
 void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head );
 
+/** \} name Functions to parse ASN.1 data structures */
+/** \} addtogroup asn1_module */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index ce97f6a..d7cc7bc 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -149,6 +149,10 @@
 #error "MBEDTLS_PK_PARSE_C defined, but not all prerequesites"
 #endif
 
+#if defined(MBEDTLS_PKCS5_C) && !defined(MBEDTLS_MD_C)
+#error "MBEDTLS_PKCS5_C defined, but not all prerequesites"
+#endif
+
 #if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) &&      \
                                     !defined(MBEDTLS_SHA256_C))
 #error "MBEDTLS_ENTROPY_C defined, but not all prerequisites"
@@ -561,11 +565,6 @@
 #error "MBEDTLS_PSA_ITS_FILE_C defined, but not all prerequisites"
 #endif
 
-#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) && \
-    defined(MBEDTLS_USE_PSA_CRYPTO)
-#error "MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined, but it cannot coexist with MBEDTLS_USE_PSA_CRYPTO."
-#endif
-
 #if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) ||         \
     !defined(MBEDTLS_OID_C) )
 #error "MBEDTLS_RSA_C defined, but not all prerequisites"
diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h
index 959a5d5..2b66b53 100644
--- a/include/mbedtls/ctr_drbg.h
+++ b/include/mbedtls/ctr_drbg.h
@@ -135,7 +135,7 @@
 /**< The maximum size of seed or reseed buffer in bytes. */
 #endif
 
-/* \} name SECTION: Module settings */
+/** \} name SECTION: Module settings */
 
 #define MBEDTLS_CTR_DRBG_PR_OFF             0
 /**< Prediction resistance is disabled. */
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index 5b26084..9895573 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -299,7 +299,7 @@
 #define MBEDTLS_ECP_FIXED_POINT_OPTIM  1   /**< Enable fixed-point speed-up. */
 #endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */
 
-/* \} name SECTION: Module settings */
+/** \} name SECTION: Module settings */
 
 #else  /* MBEDTLS_ECP_ALT */
 #include "ecp_alt.h"
diff --git a/include/mbedtls/entropy.h b/include/mbedtls/entropy.h
index fede05f..14e8b31 100644
--- a/include/mbedtls/entropy.h
+++ b/include/mbedtls/entropy.h
@@ -69,7 +69,7 @@
 #define MBEDTLS_ENTROPY_MAX_GATHER      128     /**< Maximum amount requested from entropy sources */
 #endif
 
-/* \} name SECTION: Module settings */
+/** \} name SECTION: Module settings */
 
 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
 #define MBEDTLS_ENTROPY_BLOCK_SIZE      64      /**< Block size of entropy accumulator (SHA-512) */
diff --git a/include/mbedtls/hkdf.h b/include/mbedtls/hkdf.h
index e6bfe05..2e225cb 100644
--- a/include/mbedtls/hkdf.h
+++ b/include/mbedtls/hkdf.h
@@ -35,7 +35,7 @@
  */
 /** Bad input parameters to function. */
 #define MBEDTLS_ERR_HKDF_BAD_INPUT_DATA  -0x5F80
-/* \} name */
+/** \} name */
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h
index 0f1653f..37702b5 100644
--- a/include/mbedtls/hmac_drbg.h
+++ b/include/mbedtls/hmac_drbg.h
@@ -71,7 +71,7 @@
 #define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT    384     /**< Maximum size of (re)seed buffer */
 #endif
 
-/* \} name SECTION: Module settings */
+/** \} name SECTION: Module settings */
 
 #define MBEDTLS_HMAC_DRBG_PR_OFF   0   /**< No prediction resistance       */
 #define MBEDTLS_HMAC_DRBG_PR_ON    1   /**< Prediction resistance enabled  */
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index 0558ee0..a935c80 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -256,7 +256,7 @@
  */
 //#define MBEDTLS_DEPRECATED_REMOVED
 
-/* \} name SECTION: System support */
+/** \} name SECTION: System support */
 
 /**
  * \name SECTION: mbed TLS feature support
@@ -1081,7 +1081,7 @@
  * which is currently hard-coded to be int32_t.
  *
  * Note that this option is meant for internal use only and may be removed
- * without notice. It is incompatible with MBEDTLS_USE_PSA_CRYPTO.
+ * without notice.
  */
 //#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
 
@@ -1829,7 +1829,7 @@
  * Comment this macro to disallow using RSASSA-PSS in certificates.
  */
 #define MBEDTLS_X509_RSASSA_PSS_SUPPORT
-/* \} name SECTION: mbed TLS feature support */
+/** \} name SECTION: mbed TLS feature support */
 
 /**
  * \name SECTION: mbed TLS modules
@@ -3021,7 +3021,7 @@
  */
 #define MBEDTLS_X509_CSR_WRITE_C
 
-/* \} name SECTION: mbed TLS modules */
+/** \} name SECTION: mbed TLS modules */
 
 /**
  * \name SECTION: Module configuration options
@@ -3319,4 +3319,4 @@
  */
 //#define MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED
 
-/* \} name SECTION: Customisation configuration options */
+/** \} name SECTION: Customisation configuration options */
diff --git a/include/mbedtls/memory_buffer_alloc.h b/include/mbedtls/memory_buffer_alloc.h
index d4737f5..857fa5e 100644
--- a/include/mbedtls/memory_buffer_alloc.h
+++ b/include/mbedtls/memory_buffer_alloc.h
@@ -38,7 +38,7 @@
 #define MBEDTLS_MEMORY_ALIGN_MULTIPLE       4 /**< Align on multiples of this value */
 #endif
 
-/* \} name SECTION: Module settings */
+/** \} name SECTION: Module settings */
 
 #define MBEDTLS_MEMORY_VERIFY_NONE         0
 #define MBEDTLS_MEMORY_VERIFY_ALLOC        (1 << 0)
diff --git a/include/mbedtls/pem.h b/include/mbedtls/pem.h
index baceb07..a2b73f8 100644
--- a/include/mbedtls/pem.h
+++ b/include/mbedtls/pem.h
@@ -51,7 +51,7 @@
 #define MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE               -0x1400
 /** Bad input parameters to function. */
 #define MBEDTLS_ERR_PEM_BAD_INPUT_DATA                    -0x1480
-/* \} name */
+/** \} name PEM Error codes */
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h
index 5f9f29f..9ad7a1d 100644
--- a/include/mbedtls/pk.h
+++ b/include/mbedtls/pk.h
@@ -351,7 +351,7 @@
  * \return          #MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure.
  */
 int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx,
-                             const psa_key_id_t key );
+                             const mbedtls_svc_key_id_t key );
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 
 #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
@@ -898,7 +898,7 @@
  * \return          An Mbed TLS error code otherwise.
  */
 int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk,
-                               psa_key_id_t *key,
+                               mbedtls_svc_key_id_t *key,
                                psa_algorithm_t hash_alg );
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 
diff --git a/include/mbedtls/platform.h b/include/mbedtls/platform.h
index 277a85c..11a9ca1 100644
--- a/include/mbedtls/platform.h
+++ b/include/mbedtls/platform.h
@@ -119,7 +119,7 @@
 #endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
 
 
-/* \} name SECTION: Module settings */
+/** \} name SECTION: Module settings */
 
 /*
  * The function pointers for calloc and free.
diff --git a/include/mbedtls/platform_time.h b/include/mbedtls/platform_time.h
index 8d4b95d..8bef553 100644
--- a/include/mbedtls/platform_time.h
+++ b/include/mbedtls/platform_time.h
@@ -28,14 +28,6 @@
 extern "C" {
 #endif
 
-/**
- * \name SECTION: Module settings
- *
- * The configuration options you can set for this module are in this section.
- * Either change them in mbedtls_config.h or define them on the compiler command line.
- * \{
- */
-
 /*
  * The time_t datatype
  */
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 072ebbe..350ee2c 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -380,7 +380,7 @@
 #define MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY 16
 #endif
 
-/* \} name SECTION: Module settings */
+/** \} name SECTION: Module settings */
 
 /*
  * Length of the verify data for secure renegotiation
@@ -505,6 +505,7 @@
 #define MBEDTLS_SSL_HS_CERTIFICATE_VERIFY      15
 #define MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE     16
 #define MBEDTLS_SSL_HS_FINISHED                20
+#define MBEDTLS_SSL_HS_MESSAGE_HASH           254
 
 /*
  * TLS extensions
@@ -643,6 +644,7 @@
     MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY,
 #if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
     MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED,
+    MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO,
 #endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
 }
@@ -1359,11 +1361,11 @@
 #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
-    const int *MBEDTLS_PRIVATE(sig_hashes);          /*!< allowed signature hashes           */
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
-    const uint16_t *MBEDTLS_PRIVATE(tls13_sig_algs); /*!< allowed signature algorithms for TLS 1.3 */
-#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+    const int *MBEDTLS_PRIVATE(sig_hashes);         /*!< allowed signature hashes           */
+#endif
+    const uint16_t *MBEDTLS_PRIVATE(sig_algs);      /*!< allowed signature algorithms       */
 #endif
 
 #if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_DEPRECATED_REMOVED)
@@ -1380,7 +1382,7 @@
 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-    psa_key_id_t MBEDTLS_PRIVATE(psk_opaque); /*!< PSA key slot holding opaque PSK. This field
+    mbedtls_svc_key_id_t MBEDTLS_PRIVATE(psk_opaque); /*!< PSA key slot holding opaque PSK. This field
                               *   should only be set via
                               *   mbedtls_ssl_conf_psk_opaque().
                               *   If either no PSK or a raw PSK have been
@@ -3042,7 +3044,7 @@
  * \return         Another negative error code on other kinds of failure.
  */
 int mbedtls_ssl_conf_psk_opaque( mbedtls_ssl_config *conf,
-                                 psa_key_id_t psk,
+                                 mbedtls_svc_key_id_t psk,
                                  const unsigned char *psk_identity,
                                  size_t psk_identity_len );
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
@@ -3088,7 +3090,7 @@
  * \return         An \c MBEDTLS_ERR_SSL_XXX error code on failure.
  */
 int mbedtls_ssl_set_hs_psk_opaque( mbedtls_ssl_context *ssl,
-                                   psa_key_id_t psk );
+                                   mbedtls_svc_key_id_t psk );
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 
 /**
@@ -3267,6 +3269,7 @@
                               const uint16_t *groups );
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+#if !defined(MBEDTLS_DEPRECATED_REMOVED) && defined(MBEDTLS_SSL_PROTO_TLS1_2)
 /**
  * \brief          Set the allowed hashes for signatures during the handshake.
  *
@@ -3296,10 +3299,10 @@
  * \param hashes   Ordered list of allowed signature hashes,
  *                 terminated by \c MBEDTLS_MD_NONE.
  */
-void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf,
-                                  const int *hashes );
+void MBEDTLS_DEPRECATED mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf,
+                                                     const int *hashes );
+#endif /* !MBEDTLS_DEPRECATED_REMOVED && MBEDTLS_SSL_PROTO_TLS1_2 */
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
 /**
  * \brief          Configure allowed signature algorithms for use in TLS 1.3
  *
@@ -3311,7 +3314,6 @@
  */
 void mbedtls_ssl_conf_sig_algs( mbedtls_ssl_config *conf,
                                 const uint16_t* sig_algs );
-#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
@@ -3889,6 +3891,15 @@
 uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl );
 
 /**
+ * \brief          Return the id of the current ciphersuite
+ *
+ * \param ssl      SSL context
+ *
+ * \return         a ciphersuite id
+ */
+int mbedtls_ssl_get_ciphersuite_id_from_ssl( const mbedtls_ssl_context *ssl );
+
+/**
  * \brief          Return the name of the current ciphersuite
  *
  * \param ssl      SSL context
diff --git a/include/mbedtls/ssl_cache.h b/include/mbedtls/ssl_cache.h
index 6a81ac9..cb016fe 100644
--- a/include/mbedtls/ssl_cache.h
+++ b/include/mbedtls/ssl_cache.h
@@ -47,7 +47,7 @@
 #define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES      50   /*!< Maximum entries in cache */
 #endif
 
-/* \} name SECTION: Module settings */
+/** \} name SECTION: Module settings */
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/ssl_ciphersuites.h b/include/mbedtls/ssl_ciphersuites.h
index 18e7c98..b46442a 100644
--- a/include/mbedtls/ssl_ciphersuites.h
+++ b/include/mbedtls/ssl_ciphersuites.h
@@ -394,6 +394,13 @@
 int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info );
 int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info );
 
+static inline const char *mbedtls_ssl_ciphersuite_get_name( const mbedtls_ssl_ciphersuite_t *info )
+{
+    return info->MBEDTLS_PRIVATE(name);
+}
+
+size_t mbedtls_ssl_ciphersuite_get_cipher_key_bitlen( const mbedtls_ssl_ciphersuite_t *info );
+
 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED)
 static inline int mbedtls_ssl_ciphersuite_has_pfs( const mbedtls_ssl_ciphersuite_t *info )
 {
diff --git a/include/mbedtls/ssl_cookie.h b/include/mbedtls/ssl_cookie.h
index 86698b0..34452aa 100644
--- a/include/mbedtls/ssl_cookie.h
+++ b/include/mbedtls/ssl_cookie.h
@@ -42,7 +42,7 @@
 #define MBEDTLS_SSL_COOKIE_TIMEOUT     60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
 #endif
 
-/* \} name SECTION: Module settings */
+/** \} name SECTION: Module settings */
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h
index 9a4be95..3c76fec 100644
--- a/include/mbedtls/x509.h
+++ b/include/mbedtls/x509.h
@@ -93,7 +93,7 @@
 #define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL                 -0x2980
 /** A fatal error occurred, eg the chain is too long or the vrfy callback failed. */
 #define MBEDTLS_ERR_X509_FATAL_ERROR                      -0x3000
-/* \} name */
+/** \} name X509 Error codes */
 
 /**
  * \name X509 Verify codes
@@ -121,8 +121,8 @@
 #define MBEDTLS_X509_BADCRL_BAD_PK           0x040000  /**< The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA). */
 #define MBEDTLS_X509_BADCRL_BAD_KEY          0x080000  /**< The CRL is signed with an unacceptable key (eg bad curve, RSA too short). */
 
-/* \} name */
-/* \} addtogroup x509_module */
+/** \} name X509 Verify codes */
+/** \} addtogroup x509_module */
 
 /*
  * X.509 v3 Subject Alternative Name types.
@@ -252,7 +252,6 @@
 mbedtls_x509_time;
 
 /** \} name Structures for parsing X.509 certificates, CRLs and CSRs */
-/** \} addtogroup x509_module */
 
 /**
  * \brief          Store the certificate DN in printable form into buf;
@@ -308,6 +307,8 @@
  */
 int mbedtls_x509_time_is_future( const mbedtls_x509_time *from );
 
+/** \} addtogroup x509_module */
+
 /*
  * Internal module functions. You probably do not want to use these unless you
  * know you do.
diff --git a/include/mbedtls/x509_crl.h b/include/mbedtls/x509_crl.h
index 52bd43c..0339db8 100644
--- a/include/mbedtls/x509_crl.h
+++ b/include/mbedtls/x509_crl.h
@@ -176,8 +176,8 @@
  */
 void mbedtls_x509_crl_free( mbedtls_x509_crl *crl );
 
-/* \} name */
-/* \} addtogroup x509_module */
+/** \} name Structures and functions for parsing CRLs */
+/** \} addtogroup x509_module */
 
 #ifdef __cplusplus
 }
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index 3c11a99..51883dc 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -955,8 +955,7 @@
 #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
-/* \} name */
-/* \} addtogroup x509_module */
+/** \} name Structures and functions for parsing and writing X.509 certificates */
 
 #if defined(MBEDTLS_X509_CRT_WRITE_C)
 /**
@@ -1186,6 +1185,8 @@
 #endif /* MBEDTLS_PEM_WRITE_C */
 #endif /* MBEDTLS_X509_CRT_WRITE_C */
 
+/** \} addtogroup x509_module */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/x509_csr.h b/include/mbedtls/x509_csr.h
index f80a1a1..20a516e 100644
--- a/include/mbedtls/x509_csr.h
+++ b/include/mbedtls/x509_csr.h
@@ -154,8 +154,7 @@
 void mbedtls_x509_csr_free( mbedtls_x509_csr *csr );
 #endif /* MBEDTLS_X509_CSR_PARSE_C */
 
-/* \} name */
-/* \} addtogroup x509_module */
+/** \} name Structures and functions for X.509 Certificate Signing Requests (CSR) */
 
 #if defined(MBEDTLS_X509_CSR_WRITE_C)
 /**
@@ -297,6 +296,8 @@
 #endif /* MBEDTLS_PEM_WRITE_C */
 #endif /* MBEDTLS_X509_CSR_WRITE_C */
 
+/** \} addtogroup x509_module */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/library/.gitignore b/library/.gitignore
index cf2ddac..18cd305 100644
--- a/library/.gitignore
+++ b/library/.gitignore
@@ -7,3 +7,4 @@
 /error.c
 /version_features.c
 /ssl_debug_helpers_generated.c
+/psa_crypto_driver_wrappers.c
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 1884db9..ddede03 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -157,10 +157,25 @@
             ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/generate_ssl_debug_helpers.py
             ${error_headers}
     )
+
+    add_custom_command(
+        OUTPUT
+            ${CMAKE_CURRENT_BINARY_DIR}/psa_crypto_driver_wrappers.c
+        COMMAND
+            ${MBEDTLS_PYTHON_EXECUTABLE}
+                ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/generate_driver_wrappers.py
+                ${CMAKE_CURRENT_BINARY_DIR}
+        DEPENDS
+            ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/generate_driver_wrappers.py
+            ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja
+    )
+
+
 else()
     link_to_source(error.c)
     link_to_source(version_features.c)
     link_to_source(ssl_debug_helpers_generated.c)
+    link_to_source(psa_crypto_driver_wrappers.c)
 endif()
 
 if(CMAKE_COMPILER_IS_GNUCC)
diff --git a/library/Makefile b/library/Makefile
index 0b5a43a..e9c0a11 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -290,7 +290,8 @@
 .PHONY: generated_files
 GENERATED_FILES = \
 	error.c version_features.c \
-	ssl_debug_helpers_generated.c
+	ssl_debug_helpers_generated.c \
+        psa_crypto_driver_wrappers.c
 generated_files: $(GENERATED_FILES)
 
 error.c: ../scripts/generate_errors.pl
@@ -318,6 +319,12 @@
 	echo "  Gen   $@"
 	$(PERL) ../scripts/generate_features.pl
 
+psa_crypto_driver_wrappers.c: ../scripts/generate_driver_wrappers.py
+psa_crypto_driver_wrappers.c: ../scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja
+psa_crypto_driver_wrappers.c:
+	echo "  Gen   $@"
+	$(PYTHON) ../scripts/generate_driver_wrappers.py
+
 clean:
 ifndef WINDOWS
 	rm -f *.o libmbed*
diff --git a/library/bignum.c b/library/bignum.c
index e47e259..a7e3fa3 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -1931,7 +1931,7 @@
         mpi_mul_hlp( m, B->p, d, u0 );
         mpi_mul_hlp( n, N->p, d, u1 );
 
-        *d++ = u0; d[n + 1] = 0;
+        d++; d[n + 1] = 0;
     }
 
     /* At this point, d is either the desired result or the desired result
diff --git a/library/cipher.c b/library/cipher.c
index 03e84c6..4c7ca3f 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -386,6 +386,12 @@
 #if defined(MBEDTLS_CHACHA20_C)
     if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 )
     {
+        /* Even though the actual_iv_size is overwritten with a correct value
+         * of 12 from the cipher info, return an error to indicate that
+         * the input iv_len is wrong. */
+        if( iv_len != 12 )
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
         if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx,
                                            iv,
                                            0U ) ) /* Initial counter value */
@@ -393,6 +399,11 @@
             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
         }
     }
+#if defined(MBEDTLS_CHACHAPOLY_C)
+    if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 &&
+         iv_len != 12 )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+#endif
 #endif
 
 #if defined(MBEDTLS_GCM_C)
diff --git a/library/cipher_wrap.h b/library/cipher_wrap.h
index 90563d8..e27d6af 100644
--- a/library/cipher_wrap.h
+++ b/library/cipher_wrap.h
@@ -130,7 +130,7 @@
 typedef struct
 {
     psa_algorithm_t alg;
-    psa_key_id_t slot;
+    mbedtls_svc_key_id_t slot;
     mbedtls_cipher_psa_key_ownership slot_state;
 } mbedtls_cipher_context_psa;
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
diff --git a/library/pk.c b/library/pk.c
index ea4869c..e364520 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -151,11 +151,11 @@
  * Initialise a PSA-wrapping context
  */
 int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx,
-                             const psa_key_id_t key )
+                             const mbedtls_svc_key_id_t key )
 {
     const mbedtls_pk_info_t * const info = &mbedtls_pk_opaque_info;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    psa_key_id_t *pk_ctx;
+    mbedtls_svc_key_id_t *pk_ctx;
     psa_key_type_t type;
 
     if( ctx == NULL || ctx->pk_info != NULL )
@@ -175,7 +175,7 @@
 
     ctx->pk_info = info;
 
-    pk_ctx = (psa_key_id_t *) ctx->pk_ctx;
+    pk_ctx = (mbedtls_svc_key_id_t *) ctx->pk_ctx;
     *pk_ctx = key;
 
     return( 0 );
@@ -598,7 +598,7 @@
  * Currently only works for EC private keys.
  */
 int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk,
-                               psa_key_id_t *key,
+                               mbedtls_svc_key_id_t *key,
                                psa_algorithm_t hash_alg )
 {
 #if !defined(MBEDTLS_ECP_C)
diff --git a/library/pk_wrap.c b/library/pk_wrap.c
index 80c0aad..0bb87a4 100644
--- a/library/pk_wrap.c
+++ b/library/pk_wrap.c
@@ -560,7 +560,7 @@
     mbedtls_ecdsa_context *ctx = ctx_arg;
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    psa_key_id_t key_id = 0;
+    mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
     psa_status_t status;
     mbedtls_pk_context key;
     int key_len;
@@ -894,7 +894,7 @@
 
 static void *pk_opaque_alloc_wrap( void )
 {
-    void *ctx = mbedtls_calloc( 1, sizeof( psa_key_id_t ) );
+    void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_svc_key_id_t ) );
 
     /* no _init() function to call, an calloc() already zeroized */
 
@@ -903,13 +903,13 @@
 
 static void pk_opaque_free_wrap( void *ctx )
 {
-    mbedtls_platform_zeroize( ctx, sizeof( psa_key_id_t ) );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_svc_key_id_t ) );
     mbedtls_free( ctx );
 }
 
 static size_t pk_opaque_get_bitlen( const void *ctx )
 {
-    const psa_key_id_t *key = (const psa_key_id_t *) ctx;
+    const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx;
     size_t bits;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 
@@ -1033,7 +1033,7 @@
     ((void) p_rng);
     return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
 #else /* !MBEDTLS_ECDSA_C */
-    const psa_key_id_t *key = (const psa_key_id_t *) ctx;
+    const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx;
     psa_algorithm_t alg = PSA_ALG_ECDSA( mbedtls_psa_translate_md( md_alg ) );
     psa_status_t status;
 
diff --git a/library/pkparse.c b/library/pkparse.c
index b2d3bb0..22dab3a 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -1343,6 +1343,7 @@
      * error
      */
 #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
+    if( pwdlen != 0 )
     {
         unsigned char *key_copy;
 
diff --git a/library/pkwrite.c b/library/pkwrite.c
index 71cc0f0..b923c38 100644
--- a/library/pkwrite.c
+++ b/library/pkwrite.c
@@ -198,7 +198,7 @@
     if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_OPAQUE )
     {
         size_t buffer_size;
-        psa_key_id_t* key_id = (psa_key_id_t*) key->pk_ctx;
+        mbedtls_svc_key_id_t* key_id = (mbedtls_svc_key_id_t*) key->pk_ctx;
 
         if ( *p < start )
             return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
@@ -265,11 +265,11 @@
     {
         psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
         psa_key_type_t key_type;
-        psa_key_id_t key_id;
+        mbedtls_svc_key_id_t key_id;
         psa_ecc_family_t curve;
         size_t bits;
 
-        key_id = *((psa_key_id_t*) key->pk_ctx );
+        key_id = *((mbedtls_svc_key_id_t*) key->pk_ctx );
         if( PSA_SUCCESS != psa_get_key_attributes( key_id, &attributes ) )
             return( MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED );
         key_type = psa_get_key_type( &attributes );
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 829ed45..642fc13 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -3719,6 +3719,14 @@
     return( PSA_ERROR_INVALID_ARGUMENT );
 }
 
+static psa_status_t psa_aead_check_algorithm( psa_algorithm_t alg )
+{
+    if( !PSA_ALG_IS_AEAD( alg ) || PSA_ALG_IS_WILDCARD( alg ) )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
+    return( PSA_SUCCESS );
+}
+
 psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key,
                                psa_algorithm_t alg,
                                const uint8_t *nonce,
@@ -3736,8 +3744,9 @@
 
     *ciphertext_length = 0;
 
-    if( !PSA_ALG_IS_AEAD( alg ) || PSA_ALG_IS_WILDCARD( alg ) )
-        return( PSA_ERROR_NOT_SUPPORTED );
+    status = psa_aead_check_algorithm( alg );
+    if( status != PSA_SUCCESS )
+        return( status );
 
     status = psa_get_and_lock_key_slot_with_policy(
                  key, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
@@ -3786,8 +3795,9 @@
 
     *plaintext_length = 0;
 
-    if( !PSA_ALG_IS_AEAD( alg ) || PSA_ALG_IS_WILDCARD( alg ) )
-        return( PSA_ERROR_NOT_SUPPORTED );
+    status = psa_aead_check_algorithm( alg );
+    if( status != PSA_SUCCESS )
+        return( status );
 
     status = psa_get_and_lock_key_slot_with_policy(
                  key, &slot, PSA_KEY_USAGE_DECRYPT, alg );
@@ -3819,6 +3829,47 @@
     return( status );
 }
 
+static psa_status_t psa_validate_tag_length( psa_aead_operation_t *operation,
+                                             psa_algorithm_t alg ) {
+    uint8_t tag_len = 0;
+    if( psa_driver_get_tag_len( operation, &tag_len ) != PSA_SUCCESS )
+    {
+        return( PSA_ERROR_INVALID_ARGUMENT );
+    }
+
+    switch( PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, 0 ) )
+    {
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
+        case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ):
+            /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.*/
+            if( tag_len < 4 || tag_len > 16 || tag_len % 2 )
+                return( PSA_ERROR_INVALID_ARGUMENT );
+            break;
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
+
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
+        case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 0 ):
+            /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16. */
+            if( tag_len != 4 && tag_len != 8 && ( tag_len < 12 || tag_len > 16 ) )
+                return( PSA_ERROR_INVALID_ARGUMENT );
+            break;
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
+
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
+        case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CHACHA20_POLY1305, 0 ):
+            /* We only support the default tag length. */
+            if( tag_len != 16 )
+                return( PSA_ERROR_INVALID_ARGUMENT );
+            break;
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
+
+        default:
+            (void) tag_len;
+            return( PSA_ERROR_NOT_SUPPORTED );
+    }
+    return( PSA_SUCCESS );
+}
+
 /* Set the key for a multipart authenticated operation. */
 static psa_status_t psa_aead_setup( psa_aead_operation_t *operation,
                                     int is_encrypt,
@@ -3830,11 +3881,9 @@
     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;
+    status = psa_aead_check_algorithm( alg );
+    if( status != PSA_SUCCESS )
         goto exit;
-    }
 
     if( operation->id != 0 )
     {
@@ -3878,6 +3927,9 @@
     if( status != PSA_SUCCESS )
         goto exit;
 
+    if( ( status = psa_validate_tag_length( operation, alg ) ) != PSA_SUCCESS )
+        goto exit;
+
     operation->key_type = psa_get_key_type( &attributes );
 
 exit:
diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h
index e09e4ed..c391fd3 100644
--- a/library/psa_crypto_driver_wrappers.h
+++ b/library/psa_crypto_driver_wrappers.h
@@ -1,7 +1,6 @@
 /*
  *  Function signatures for functionality that can be provided by
  *  cryptographic accelerators.
- *  Warning: This file will be auto-generated in the future.
  */
 /*  Copyright The Mbed TLS Contributors
  *  SPDX-License-Identifier: Apache-2.0
@@ -227,6 +226,10 @@
     const uint8_t *ciphertext, size_t ciphertext_length,
     uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length );
 
+psa_status_t psa_driver_get_tag_len(
+    psa_aead_operation_t *operation,
+    uint8_t *tag_len );
+
 psa_status_t psa_driver_wrapper_aead_encrypt_setup(
     psa_aead_operation_t *operation,
     const psa_key_attributes_t *attributes,
diff --git a/library/ssl_ciphersuites.c b/library/ssl_ciphersuites.c
index 62588dc..cd2b125 100644
--- a/library/ssl_ciphersuites.c
+++ b/library/ssl_ciphersuites.c
@@ -2064,6 +2064,19 @@
     return( cur->id );
 }
 
+size_t mbedtls_ssl_ciphersuite_get_cipher_key_bitlen( const mbedtls_ssl_ciphersuite_t *info )
+{
+#if defined(MBEDTLS_CIPHER_C)
+    const mbedtls_cipher_info_t * const cipher_info =
+      mbedtls_cipher_info_from_type( info->cipher );
+
+    return( mbedtls_cipher_info_get_key_bitlen( cipher_info ) );
+#else
+    (void)info;
+    return( 0 );
+#endif
+}
+
 #if defined(MBEDTLS_PK_C)
 mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( const mbedtls_ssl_ciphersuite_t *info )
 {
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 32d4969..e411b70 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -199,171 +199,8 @@
 }
 #endif /* MBEDTLS_SSL_RENEGOTIATION */
 
-/*
- * Only if we handle at least one key exchange that needs signatures.
- */
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
-    defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
-static int ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
-                                               unsigned char *buf,
-                                               const unsigned char *end,
-                                               size_t *olen )
-{
-    unsigned char *p = buf;
-    size_t sig_alg_len = 0;
-    const int *md;
-
-#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C)
-    unsigned char *sig_alg_list = buf + 6;
-#endif
-
-    *olen = 0;
-
-    if( ssl->conf->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
-        return( 0 );
-
-    MBEDTLS_SSL_DEBUG_MSG( 3,
-        ( "client hello, adding signature_algorithms extension" ) );
-
-    if( ssl->conf->sig_hashes == NULL )
-        return( MBEDTLS_ERR_SSL_BAD_CONFIG );
-
-    for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
-    {
-#if defined(MBEDTLS_ECDSA_C)
-        sig_alg_len += 2;
-#endif
-#if defined(MBEDTLS_RSA_C)
-        sig_alg_len += 2;
-#endif
-        if( sig_alg_len > MBEDTLS_SSL_MAX_SIG_HASH_ALG_LIST_LEN )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 3,
-                ( "length in bytes of sig-hash-alg extension too big" ) );
-            return( MBEDTLS_ERR_SSL_BAD_CONFIG );
-        }
-    }
-
-    /* Empty signature algorithms list, this is a configuration error. */
-    if( sig_alg_len == 0 )
-        return( MBEDTLS_ERR_SSL_BAD_CONFIG );
-
-    MBEDTLS_SSL_CHK_BUF_PTR( p, end, sig_alg_len + 6 );
-
-    /*
-     * Prepare signature_algorithms extension (TLS 1.2)
-     */
-    sig_alg_len = 0;
-
-    for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
-    {
-#if defined(MBEDTLS_ECDSA_C)
-        sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md );
-        sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA;
-#endif
-#if defined(MBEDTLS_RSA_C)
-        sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md );
-        sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA;
-#endif
-    }
-
-    /*
-     * enum {
-     *     none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
-     *     sha512(6), (255)
-     * } HashAlgorithm;
-     *
-     * enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
-     *   SignatureAlgorithm;
-     *
-     * struct {
-     *     HashAlgorithm hash;
-     *     SignatureAlgorithm signature;
-     * } SignatureAndHashAlgorithm;
-     *
-     * SignatureAndHashAlgorithm
-     *   supported_signature_algorithms<2..2^16-2>;
-     */
-    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SIG_ALG, p, 0 );
-    p += 2;
-
-    MBEDTLS_PUT_UINT16_BE( sig_alg_len + 2, p, 0 );
-    p += 2;
-
-    MBEDTLS_PUT_UINT16_BE( sig_alg_len, p, 0 );
-    p += 2;
-
-    *olen = 6 + sig_alg_len;
-
-    return( 0 );
-}
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
-          MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
-
 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
-static int ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl,
-                                                    unsigned char *buf,
-                                                    const unsigned char *end,
-                                                    size_t *olen )
-{
-    unsigned char *p = buf;
-    unsigned char *elliptic_curve_list = p + 6;
-    size_t elliptic_curve_len = 0;
-    const mbedtls_ecp_curve_info *info;
-    const uint16_t *group_list = mbedtls_ssl_get_groups( ssl );
-    *olen = 0;
-
-    /* Check there is room for header */
-    MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 );
-
-    MBEDTLS_SSL_DEBUG_MSG( 3,
-        ( "client hello, adding supported_elliptic_curves extension" ) );
-
-    if( group_list == NULL )
-        return( MBEDTLS_ERR_SSL_BAD_CONFIG );
-
-    for( ; *group_list != 0; group_list++ )
-    {
-        info = mbedtls_ecp_curve_info_from_tls_id( *group_list );
-        if( info == NULL )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 1,
-                ( "invalid curve in ssl configuration" ) );
-            return( MBEDTLS_ERR_SSL_BAD_CONFIG );
-        }
-
-        /* Check there is room for another curve */
-        MBEDTLS_SSL_CHK_BUF_PTR( elliptic_curve_list, end, elliptic_curve_len + 2 );
-
-        MBEDTLS_PUT_UINT16_BE( *group_list, elliptic_curve_list, elliptic_curve_len );
-        elliptic_curve_len += 2;
-
-        if( elliptic_curve_len > MBEDTLS_SSL_MAX_CURVE_LIST_LEN )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 3,
-                ( "malformed supported_elliptic_curves extension in config" ) );
-            return( MBEDTLS_ERR_SSL_BAD_CONFIG );
-        }
-    }
-
-    /* Empty elliptic curve list, this is a configuration error. */
-    if( elliptic_curve_len == 0 )
-        return( MBEDTLS_ERR_SSL_BAD_CONFIG );
-
-    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES, p, 0 );
-    p += 2;
-
-    MBEDTLS_PUT_UINT16_BE( elliptic_curve_len + 2, p, 0 );
-    p += 2;
-
-    MBEDTLS_PUT_UINT16_BE( elliptic_curve_len, p, 0 );
-    p += 2;
-
-    *olen = 6 + elliptic_curve_len;
-
-    return( 0 );
-}
 
 static int ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
                                                   unsigned char *buf,
@@ -1193,10 +1030,10 @@
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
     defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
-    if( ( ret = ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len,
-                                                    end, &olen ) ) != 0 )
+    if( ( ret = mbedtls_ssl_write_sig_alg_ext( ssl, p + 2 + ext_len,
+                                               end, &olen ) ) != 0 )
     {
-        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_signature_algorithms_ext", ret );
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_sig_alg_ext", ret );
         return( ret );
     }
     ext_len += olen;
@@ -1206,10 +1043,10 @@
     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
     if( uses_ec )
     {
-        if( ( ret = ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len,
-                                                             end, &olen ) ) != 0 )
+        if( ( ret = mbedtls_ssl_write_supported_groups_ext( ssl, p + 2 + ext_len,
+                                                            end, &olen ) ) != 0 )
         {
-            MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_supported_elliptic_curves_ext", ret );
+            MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_supported_groups_ext", ret );
             return( ret );
         }
         ext_len += olen;
@@ -2758,7 +2595,6 @@
                                           mbedtls_md_type_t *md_alg,
                                           mbedtls_pk_type_t *pk_alg )
 {
-    ((void) ssl);
     *md_alg = MBEDTLS_MD_NONE;
     *pk_alg = MBEDTLS_PK_NONE;
 
@@ -2794,9 +2630,9 @@
     }
 
     /*
-     * Check if the hash is acceptable
+     * Check if the signature algorithm is acceptable
      */
-    if( mbedtls_ssl_check_sig_hash( ssl, *md_alg ) != 0 )
+    if( !mbedtls_ssl_sig_alg_is_offered( ssl, MBEDTLS_GET_UINT16_BE( *p, 0 ) ) )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1,
             ( "server used HashAlgorithm %d that was not offered", *(p)[0] ) );
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 40e4aaf..ad358b3 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -56,6 +56,8 @@
 #include "mbedtls/psa_util.h"
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 
+#include "common.h"
+
 #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
     !defined(inline) && !defined(__cplusplus)
 #define inline __inline
@@ -256,8 +258,11 @@
         : ( MBEDTLS_SSL_IN_CONTENT_LEN )                             \
         )
 
-/* Maximum size in bytes of list in sig-hash algorithm ext., RFC 5246 */
-#define MBEDTLS_SSL_MAX_SIG_HASH_ALG_LIST_LEN  65534
+/* Maximum size in bytes of list in signature algorithms ext., RFC 5246/8446 */
+#define MBEDTLS_SSL_MAX_SIG_ALG_LIST_LEN       65534
+
+/* Minimum size in bytes of list in signature algorithms ext., RFC 5246/8446 */
+#define MBEDTLS_SSL_MIN_SIG_ALG_LIST_LEN       2
 
 /* Maximum size in bytes of list in supported elliptic curve ext., RFC 4492 */
 #define MBEDTLS_SSL_MAX_CURVE_LIST_LEN         65535
@@ -554,6 +559,7 @@
 
 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
     unsigned char group_list_heap_allocated;
+    unsigned char sig_algs_heap_allocated;
 #endif
 
 #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
@@ -585,6 +591,11 @@
     int tls13_kex_modes; /*!< key exchange modes for TLS 1.3 */
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
 
+#if defined(MBEDTLS_SSL_CLI_C)
+    /*!<  Number of Hello Retry Request messages received from the server.  */
+    int hello_retry_request_count;
+#endif /* MBEDTLS_SSL_CLI_C */
+
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
     defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
     mbedtls_ssl_sig_hash_set_t hash_algs;             /*!<  Set of suitable sig-hash pairs */
@@ -592,6 +603,7 @@
 
 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
     const uint16_t *group_list;
+    const uint16_t *sig_algs;
 #endif
 
 #if defined(MBEDTLS_DHM_C)
@@ -609,7 +621,7 @@
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_key_type_t ecdh_psa_type;
     uint16_t ecdh_bits;
-    psa_key_id_t ecdh_psa_privkey;
+    mbedtls_svc_key_id_t ecdh_psa_privkey;
     unsigned char ecdh_psa_peerkey[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
     size_t ecdh_psa_peerkey_len;
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
@@ -630,7 +642,7 @@
 
 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-    psa_key_id_t psk_opaque;            /*!< Opaque PSK from the callback   */
+    mbedtls_svc_key_id_t psk_opaque;            /*!< Opaque PSK from the callback   */
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
     unsigned char *psk;                 /*!<  PSK from the callback         */
     size_t psk_len;                     /*!<  Length of PSK from callback   */
@@ -680,15 +692,19 @@
 
     } buffering;
 
+#if defined(MBEDTLS_SSL_PROTO_DTLS) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
+    unsigned char *verify_cookie;       /*!<  Cli: HelloVerifyRequest cookie
+                                         *    for dtls / tls 1.3
+                                         *    Srv: unused                    */
+    unsigned char verify_cookie_len;    /*!<  Cli: cookie length for
+                                         *    dtls / tls 1.3
+                                         *    Srv: flag for sending a cookie */
+#endif /* MBEDTLS_SSL_PROTO_DTLS || MBEDTLS_SSL_PROTO_TLS1_3 */
+
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
     unsigned int out_msg_seq;           /*!<  Outgoing handshake sequence number */
     unsigned int in_msg_seq;            /*!<  Incoming handshake sequence number */
 
-    unsigned char *verify_cookie;       /*!<  Cli: HelloVerifyRequest cookie
-                                              Srv: unused                    */
-    unsigned char verify_cookie_len;    /*!<  Cli: cookie length
-                                              Srv: flag for sending a cookie */
-
     uint32_t retransmit_timeout;        /*!<  Current value of timeout       */
     mbedtls_ssl_flight_item *flight;    /*!<  Current outgoing flight        */
     mbedtls_ssl_flight_item *cur_msg;   /*!<  Current message in flight      */
@@ -1247,7 +1263,7 @@
  * 2. static PSK configured by \c mbedtls_ssl_conf_psk_opaque()
  * Return an opaque PSK
  */
-static inline psa_key_id_t mbedtls_ssl_get_opaque_psk(
+static inline mbedtls_svc_key_id_t mbedtls_ssl_get_opaque_psk(
     const mbedtls_ssl_context *ssl )
 {
     if( ! mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) )
@@ -1276,11 +1292,6 @@
 int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id );
 #endif
 
-#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
-int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl,
-                                mbedtls_md_type_t md );
-#endif
-
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
 static inline mbedtls_ssl_srtp_profile mbedtls_ssl_check_srtp_profile_value
                                                     ( const uint16_t srtp_profile_value )
@@ -1440,6 +1451,8 @@
 void mbedtls_ssl_update_in_pointers( mbedtls_ssl_context *ssl );
 
 int mbedtls_ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial );
+void mbedtls_ssl_session_reset_msg_layer( mbedtls_ssl_context *ssl,
+                                          int partial );
 
 /*
  * Send pending alert
@@ -1489,6 +1502,7 @@
     }
     return( 0 );
 }
+
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
@@ -1503,8 +1517,43 @@
     }
     return( 0 );
 }
+
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
+static inline int mbedtls_ssl_conf_is_tls13_enabled( const mbedtls_ssl_config *conf )
+{
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+    if( conf->min_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
+        conf->max_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
+        conf->min_minor_ver <= MBEDTLS_SSL_MINOR_VERSION_4 &&
+        conf->max_minor_ver >= MBEDTLS_SSL_MINOR_VERSION_4 )
+    {
+        return( 1 );
+    }
+    return( 0 );
+#else
+    ((void) conf);
+    return( 0 );
+#endif
+}
+
+static inline int mbedtls_ssl_conf_is_tls12_enabled( const mbedtls_ssl_config *conf )
+{
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    if( conf->min_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
+        conf->max_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
+        conf->min_minor_ver <= MBEDTLS_SSL_MINOR_VERSION_3 &&
+        conf->max_minor_ver >= MBEDTLS_SSL_MINOR_VERSION_3 )
+    {
+        return( 1 );
+    }
+    return( 0 );
+#else
+    ((void) conf);
+    return( 0 );
+#endif
+}
+
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_TLS1_3)
 static inline int mbedtls_ssl_conf_is_hybrid_tls12_tls13( const mbedtls_ssl_config *conf )
 {
@@ -1626,23 +1675,6 @@
                    MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL ) );
 }
 
-/*
- * Helper functions for NamedGroup.
- */
-static inline int mbedtls_ssl_tls13_named_group_is_ecdhe( uint16_t named_group )
-{
-    return( named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1 ||
-            named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1 ||
-            named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP521R1 ||
-            named_group == MBEDTLS_SSL_IANA_TLS_GROUP_X25519    ||
-            named_group == MBEDTLS_SSL_IANA_TLS_GROUP_X448 );
-}
-
-static inline int mbedtls_ssl_tls13_named_group_is_dhe( uint16_t named_group )
-{
-    return( named_group >= MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE2048 &&
-            named_group <= MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE8192 );
-}
 
 static inline void mbedtls_ssl_handshake_set_state( mbedtls_ssl_context *ssl,
                                                     mbedtls_ssl_states state )
@@ -1700,19 +1732,19 @@
                                                unsigned char const *msg,
                                                size_t msg_len );
 
-#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
-/*
- * Write TLS 1.3 Signature Algorithm extension
- */
-int mbedtls_ssl_tls13_write_sig_alg_ext( mbedtls_ssl_context *ssl,
-                                         unsigned char *buf,
-                                         unsigned char *end,
-                                         size_t *out_len);
-
-#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+int mbedtls_ssl_reset_transcript_for_hrr( mbedtls_ssl_context *ssl );
 
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
 
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+/*
+ * Write Signature Algorithm extension
+ */
+int mbedtls_ssl_write_sig_alg_ext( mbedtls_ssl_context *ssl, unsigned char *buf,
+                                   const unsigned char *end, size_t *out_len );
+
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+
 /* Get handshake transcript */
 int mbedtls_ssl_get_handshake_transcript( mbedtls_ssl_context *ssl,
                                           const mbedtls_md_type_t md,
@@ -1743,4 +1775,241 @@
     #endif
 }
 
+/*
+ * Helper functions for NamedGroup.
+ */
+static inline int mbedtls_ssl_tls12_named_group_is_ecdhe( uint16_t named_group )
+{
+    /*
+     * RFC 8422 section 5.1.1
+     */
+    return( named_group == MBEDTLS_SSL_IANA_TLS_GROUP_X25519    ||
+            named_group == MBEDTLS_SSL_IANA_TLS_GROUP_BP256R1   ||
+            named_group == MBEDTLS_SSL_IANA_TLS_GROUP_BP384R1   ||
+            named_group == MBEDTLS_SSL_IANA_TLS_GROUP_BP512R1   ||
+            named_group == MBEDTLS_SSL_IANA_TLS_GROUP_X448      ||
+            /* Below deprected curves should be removed with notice to users */
+            named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP192K1 ||
+            named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP192R1 ||
+            named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP224K1 ||
+            named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP224R1 ||
+            named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP256K1 ||
+            named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1 ||
+            named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1 ||
+            named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP521R1 );
+}
+
+static inline int mbedtls_ssl_tls13_named_group_is_ecdhe( uint16_t named_group )
+{
+    return( named_group == MBEDTLS_SSL_IANA_TLS_GROUP_X25519    ||
+            named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1 ||
+            named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1 ||
+            named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP521R1 ||
+            named_group == MBEDTLS_SSL_IANA_TLS_GROUP_X448 );
+}
+
+static inline int mbedtls_ssl_tls13_named_group_is_dhe( uint16_t named_group )
+{
+    return( named_group >= MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE2048 &&
+            named_group <= MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE8192 );
+}
+
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) || \
+    defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+int mbedtls_ssl_write_supported_groups_ext( mbedtls_ssl_context *ssl,
+                                            unsigned char *buf,
+                                            const unsigned char *end,
+                                            size_t *out_len );
+
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED ||
+          MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
+          MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+/*
+ * Return supported signature algorithms.
+ *
+ * In future, invocations can be changed to ssl->conf->sig_algs when
+ * mbedtls_ssl_conf_sig_hashes() is deleted.
+ *
+ * ssl->handshake->sig_algs is either a translation of sig_hashes to IANA TLS
+ * signature algorithm identifiers when mbedtls_ssl_conf_sig_hashes() has been
+ * used, or a pointer to ssl->conf->sig_algs when mbedtls_ssl_conf_sig_algs() has
+ * been more recently invoked.
+ *
+ */
+static inline const void *mbedtls_ssl_get_sig_algs(
+                                                const mbedtls_ssl_context *ssl )
+{
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+    if( ssl->handshake != NULL && ssl->handshake->sig_algs != NULL )
+        return( ssl->handshake->sig_algs );
+#endif
+    return( ssl->conf->sig_algs );
+
+#else /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+
+    ((void) ssl);
+    return( NULL );
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+}
+
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+
+static inline int mbedtls_ssl_sig_alg_is_offered( const mbedtls_ssl_context *ssl,
+                                                  uint16_t proposed_sig_alg )
+{
+    const uint16_t *sig_alg = mbedtls_ssl_get_sig_algs( ssl );
+    if( sig_alg == NULL )
+        return( 0 );
+
+    for( ; *sig_alg != MBEDTLS_TLS1_3_SIG_NONE; sig_alg++ )
+    {
+        if( *sig_alg == proposed_sig_alg )
+            return( 1 );
+    }
+    return( 0 );
+}
+
+
+static inline int mbedtls_ssl_sig_alg_is_supported(
+                                                const mbedtls_ssl_context *ssl,
+                                                const uint16_t sig_alg )
+{
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3)
+    {
+        /* High byte is hash */
+        unsigned char hash = MBEDTLS_BYTE_1( sig_alg );
+        unsigned char sig = MBEDTLS_BYTE_0( sig_alg );
+
+        switch( hash )
+        {
+#if defined(MBEDTLS_MD5_C)
+            case MBEDTLS_SSL_HASH_MD5:
+                break;
+#endif
+
+#if defined(MBEDTLS_SHA1_C)
+            case MBEDTLS_SSL_HASH_SHA1:
+                break;
+#endif
+
+#if defined(MBEDTLS_SHA224_C)
+            case MBEDTLS_SSL_HASH_SHA224:
+                break;
+#endif
+
+#if defined(MBEDTLS_SHA256_C)
+            case MBEDTLS_SSL_HASH_SHA256:
+                break;
+#endif
+
+#if defined(MBEDTLS_SHA384_C)
+            case MBEDTLS_SSL_HASH_SHA384:
+                break;
+#endif
+
+#if defined(MBEDTLS_SHA512_C)
+            case MBEDTLS_SSL_HASH_SHA512:
+                break;
+#endif
+
+            default:
+                return( 0 );
+        }
+
+        switch( sig )
+        {
+#if defined(MBEDTLS_RSA_C)
+            case MBEDTLS_SSL_SIG_RSA:
+                break;
+#endif
+
+#if defined(MBEDTLS_ECDSA_C)
+            case MBEDTLS_SSL_SIG_ECDSA:
+                break;
+#endif
+
+        default:
+            return( 0 );
+        }
+
+        return( 1 );
+    }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+    if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_4)
+    {
+        switch( sig_alg )
+        {
+#if defined(MBEDTLS_SHA256_C) && \
+    defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \
+    defined(MBEDTLS_ECDSA_C)
+            case MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256:
+                break;
+#endif /* MBEDTLS_SHA256_C &&
+          MBEDTLS_ECP_DP_SECP256R1_ENABLED &&
+          MBEDTLS_ECDSA_C */
+
+#if defined(MBEDTLS_SHA384_C) && \
+    defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && \
+    defined(MBEDTLS_ECDSA_C)
+            case MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384:
+                break;
+#endif /* MBEDTLS_SHA384_C &&
+          MBEDTLS_ECP_DP_SECP384R1_ENABLED &&
+          MBEDTLS_ECDSA_C */
+
+#if defined(MBEDTLS_SHA512_C) && \
+    defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && \
+    defined(MBEDTLS_ECDSA_C)
+            case MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512:
+                break;
+#endif /* MBEDTLS_SHA512_C &&
+          MBEDTLS_ECP_DP_SECP521R1_ENABLED &&
+          MBEDTLS_ECDSA_C */
+
+#if defined(MBEDTLS_SHA256_C) && \
+    defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
+            case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:
+                break;
+#endif /* MBEDTLS_SHA256_C &&
+          MBEDTLS_X509_RSASSA_PSS_SUPPORT */
+
+#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_RSA_C)
+            case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256:
+                break;
+#endif /* MBEDTLS_SHA256_C && MBEDTLS_RSA_C*/
+
+            default:
+                return( 0 );
+        }
+
+        return( 1 );
+    }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+    ((void) ssl);
+    ((void) sig_alg);
+    return( 0 );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+    defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_RSA_C)
+#define MBEDTLS_SSL_SIG_ALG( hash ) (( hash << 8 ) | MBEDTLS_SSL_SIG_ECDSA), \
+                                    (( hash << 8 ) | MBEDTLS_SSL_SIG_RSA),
+#elif defined(MBEDTLS_ECDSA_C)
+#define MBEDTLS_SSL_SIG_ALG( hash ) (( hash << 8 ) | MBEDTLS_SSL_SIG_ECDSA),
+#elif defined(MBEDTLS_RSA_C)
+#define MBEDTLS_SSL_SIG_ALG( hash ) (( hash << 8 ) | MBEDTLS_SSL_SIG_RSA),
+#else
+#define MBEDTLS_SSL_SIG_ALG( hash )
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_RSA_C */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+
 #endif /* ssl_misc.h */
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index f34f2de..f189e1d 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -239,9 +239,9 @@
  * This needs to be done at a later stage.
  *
  */
-static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl,
-                                               const unsigned char *buf,
-                                               size_t len )
+static int ssl_parse_sig_alg_ext( mbedtls_ssl_context *ssl,
+                                  const unsigned char *buf,
+                                  size_t len )
 {
     size_t sig_alg_list_size;
 
@@ -296,7 +296,8 @@
             continue;
         }
 
-        if( mbedtls_ssl_check_sig_hash( ssl, md_cur ) == 0 )
+        if( mbedtls_ssl_sig_alg_is_offered(
+                ssl, MBEDTLS_GET_UINT16_BE( p, 0 ) ) )
         {
             mbedtls_ssl_sig_hash_set_add( &ssl->handshake->hash_algs, sig_cur, md_cur );
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext:"
@@ -317,9 +318,48 @@
 
 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
-static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl,
-                                                const unsigned char *buf,
-                                                size_t len )
+/*
+ * Function for parsing a supported groups (TLS 1.3) or supported elliptic
+ * curves (TLS 1.2) extension.
+ *
+ * The "extension_data" field of a supported groups extension contains a
+ * "NamedGroupList" value (TLS 1.3 RFC8446):
+ *      enum {
+ *          secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019),
+ *          x25519(0x001D), x448(0x001E),
+ *          ffdhe2048(0x0100), ffdhe3072(0x0101), ffdhe4096(0x0102),
+ *          ffdhe6144(0x0103), ffdhe8192(0x0104),
+ *          ffdhe_private_use(0x01FC..0x01FF),
+ *          ecdhe_private_use(0xFE00..0xFEFF),
+ *          (0xFFFF)
+ *      } NamedGroup;
+ *      struct {
+ *          NamedGroup named_group_list<2..2^16-1>;
+ *      } NamedGroupList;
+ *
+ * The "extension_data" field of a supported elliptic curves extension contains
+ * a "NamedCurveList" value (TLS 1.2 RFC 8422):
+ * enum {
+ *      deprecated(1..22),
+ *      secp256r1 (23), secp384r1 (24), secp521r1 (25),
+ *      x25519(29), x448(30),
+ *      reserved (0xFE00..0xFEFF),
+ *      deprecated(0xFF01..0xFF02),
+ *      (0xFFFF)
+ *  } NamedCurve;
+ * struct {
+ *      NamedCurve named_curve_list<2..2^16-1>
+ *  } NamedCurveList;
+ *
+ * The TLS 1.3 supported groups extension was defined to be a compatible
+ * generalization of the TLS 1.2 supported elliptic curves extension. They both
+ * share the same extension identifier.
+ *
+ * DHE groups are not supported yet.
+ */
+static int ssl_parse_supported_groups_ext( mbedtls_ssl_context *ssl,
+                                           const unsigned char *buf,
+                                           size_t len )
 {
     size_t list_size, our_size;
     const unsigned char *p;
@@ -1635,7 +1675,7 @@
             case MBEDTLS_TLS_EXT_SIG_ALG:
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
 
-                ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size );
+                ret = ssl_parse_sig_alg_ext( ssl, ext + 4, ext_size );
                 if( ret != 0 )
                     return( ret );
 
@@ -1646,10 +1686,10 @@
 
 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
-            case MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES:
+            case MBEDTLS_TLS_EXT_SUPPORTED_GROUPS:
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) );
 
-                ret = ssl_parse_supported_elliptic_curves( ssl, ext + 4, ext_size );
+                ret = ssl_parse_supported_groups_ext( ssl, ext + 4, ext_size );
                 if( ret != 0 )
                     return( ret );
                 break;
@@ -1763,12 +1803,16 @@
      */
     if( sig_hash_alg_ext_present == 0 )
     {
-        mbedtls_md_type_t md_default = MBEDTLS_MD_SHA1;
+        uint16_t sig_algs[] = { MBEDTLS_SSL_SIG_ALG(MBEDTLS_SSL_HASH_SHA1) };
+        mbedtls_md_type_t md_default = MBEDTLS_MD_NONE;
+        for( i = 0; i < sizeof( sig_algs ) / sizeof( sig_algs[0] ) ; i++ )
+        {
+            if( mbedtls_ssl_sig_alg_is_offered( ssl, sig_algs[ i ] ) )
+                md_default = MBEDTLS_MD_SHA1;
+        }
 
-        if( mbedtls_ssl_check_sig_hash( ssl, md_default ) != 0 )
-            md_default = MBEDTLS_MD_NONE;
-
-        mbedtls_ssl_sig_hash_set_const_hash( &ssl->handshake->hash_algs, md_default );
+        mbedtls_ssl_sig_hash_set_const_hash( &ssl->handshake->hash_algs,
+                                             md_default );
     }
 
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
@@ -2754,26 +2798,24 @@
      */
     if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
     {
-        const int *cur;
-
         /*
          * Supported signature algorithms
          */
-        for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ )
-        {
-            unsigned char hash = mbedtls_ssl_hash_from_md_alg( *cur );
+        const uint16_t *sig_alg = mbedtls_ssl_get_sig_algs( ssl );
+        if( sig_alg == NULL )
+            return( MBEDTLS_ERR_SSL_BAD_CONFIG );
 
-            if( MBEDTLS_SSL_HASH_NONE == hash || mbedtls_ssl_set_calc_verify_md( ssl, hash ) )
+        for( ; *sig_alg != MBEDTLS_TLS1_3_SIG_NONE; sig_alg++ )
+        {
+            unsigned char hash = MBEDTLS_BYTE_1( *sig_alg );
+
+            if( mbedtls_ssl_set_calc_verify_md( ssl, hash ) )
+                continue;
+            if( ! mbedtls_ssl_sig_alg_is_supported( ssl, *sig_alg ) )
                 continue;
 
-#if defined(MBEDTLS_RSA_C)
-            p[2 + sa_len++] = hash;
-            p[2 + sa_len++] = MBEDTLS_SSL_SIG_RSA;
-#endif
-#if defined(MBEDTLS_ECDSA_C)
-            p[2 + sa_len++] = hash;
-            p[2 + sa_len++] = MBEDTLS_SSL_SIG_ECDSA;
-#endif
+            MBEDTLS_PUT_UINT16_BE( *sig_alg, p, sa_len );
+            sa_len += 2;
         }
 
         MBEDTLS_PUT_UINT16_BE( sa_len, p, 0 );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index d868e49..f261a6a 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -25,13 +25,17 @@
 
 #if defined(MBEDTLS_SSL_TLS_C)
 
+#include <assert.h>
+
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
 #include <stdlib.h>
+#include <stdio.h>
 #define mbedtls_calloc    calloc
 #define mbedtls_free      free
-#endif
+#define mbedtls_printf    printf
+#endif /* !MBEDTLS_PLATFORM_C */
 
 #include "mbedtls/ssl.h"
 #include "ssl_misc.h"
@@ -333,7 +337,7 @@
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
 
 static psa_status_t setup_psa_key_derivation( psa_key_derivation_operation_t* derivation,
-                                              psa_key_id_t key,
+                                              mbedtls_svc_key_id_t key,
                                               psa_algorithm_t alg,
                                               const unsigned char* seed, size_t seed_length,
                                               const unsigned char* label, size_t label_length,
@@ -393,7 +397,7 @@
 {
     psa_status_t status;
     psa_algorithm_t alg;
-    psa_key_id_t master_key = MBEDTLS_SVC_KEY_ID_INIT;
+    mbedtls_svc_key_id_t master_key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_derivation_operation_t derivation =
         PSA_KEY_DERIVATION_OPERATION_INIT;
 
@@ -1223,7 +1227,7 @@
         /* Perform PSK-to-MS expansion in a single step. */
         psa_status_t status;
         psa_algorithm_t alg;
-        psa_key_id_t psk;
+        mbedtls_svc_key_id_t psk;
         psa_key_derivation_operation_t derivation =
             PSA_KEY_DERIVATION_OPERATION_INIT;
         mbedtls_md_type_t hash_alg = handshake->ciphersuite_info->mac;
@@ -3150,6 +3154,74 @@
 #endif /* MBEDTLS_DEPRECATED_REMOVED */
 #endif /* MBEDTLS_ECP_C */
 
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    /* Heap allocate and translate sig_hashes from internal hash identifiers to
+       signature algorithms IANA identifiers.  */
+    if ( mbedtls_ssl_conf_is_tls12_only( ssl->conf ) &&
+         ssl->conf->sig_hashes != NULL )
+    {
+        const int *md;
+        const int *sig_hashes = ssl->conf->sig_hashes;
+        size_t sig_algs_len = 0;
+        uint16_t *p;
+
+#if defined(static_assert)
+        static_assert( MBEDTLS_SSL_MAX_SIG_ALG_LIST_LEN
+                       <= ( SIZE_MAX - ( 2 * sizeof(uint16_t) ) ),
+                       "MBEDTLS_SSL_MAX_SIG_ALG_LIST_LEN too big" );
+#endif
+
+        for( md = sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
+        {
+            if( mbedtls_ssl_hash_from_md_alg( *md ) == MBEDTLS_SSL_HASH_NONE )
+                continue;
+#if defined(MBEDTLS_ECDSA_C)
+            sig_algs_len += sizeof( uint16_t );
+#endif
+
+#if defined(MBEDTLS_RSA_C)
+            sig_algs_len += sizeof( uint16_t );
+#endif
+            if( sig_algs_len > MBEDTLS_SSL_MAX_SIG_ALG_LIST_LEN )
+                return( MBEDTLS_ERR_SSL_BAD_CONFIG );
+        }
+
+        if( sig_algs_len < MBEDTLS_SSL_MIN_SIG_ALG_LIST_LEN )
+            return( MBEDTLS_ERR_SSL_BAD_CONFIG );
+
+        ssl->handshake->sig_algs = mbedtls_calloc( 1, sig_algs_len +
+                                                      sizeof( uint16_t ));
+        if( ssl->handshake->sig_algs == NULL )
+            return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+
+        p = (uint16_t *)ssl->handshake->sig_algs;
+        for( md = sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
+        {
+            unsigned char hash = mbedtls_ssl_hash_from_md_alg( *md );
+            if( hash == MBEDTLS_SSL_HASH_NONE )
+                continue;
+#if defined(MBEDTLS_ECDSA_C)
+            *p = (( hash << 8 ) | MBEDTLS_SSL_SIG_ECDSA);
+            p++;
+#endif
+#if defined(MBEDTLS_RSA_C)
+            *p = (( hash << 8 ) | MBEDTLS_SSL_SIG_RSA);
+            p++;
+#endif
+        }
+        *p = MBEDTLS_TLS1_3_SIG_NONE;
+        ssl->handshake->sig_algs_heap_allocated = 1;
+    }
+    else
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+    {
+        ssl->handshake->sig_algs = ssl->conf->sig_algs;
+        ssl->handshake->sig_algs_heap_allocated = 0;
+    }
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
     return( 0 );
 }
 
@@ -3328,8 +3400,8 @@
  * If partial is non-zero, keep data in the input buffer and client ID.
  * (Use when a DTLS client reconnects from the same port.)
  */
-static void ssl_session_reset_msg_layer( mbedtls_ssl_context *ssl,
-                                         int partial )
+void mbedtls_ssl_session_reset_msg_layer( mbedtls_ssl_context *ssl,
+                                          int partial )
 {
 #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
     size_t in_buf_len = ssl->in_buf_len;
@@ -3381,12 +3453,32 @@
     mbedtls_ssl_dtls_replay_reset( ssl );
 #endif
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
     if( ssl->transform )
     {
         mbedtls_ssl_transform_free( ssl->transform );
         mbedtls_free( ssl->transform );
         ssl->transform = NULL;
     }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+    mbedtls_ssl_transform_free( ssl->transform_application );
+    mbedtls_free( ssl->transform_application );
+    ssl->transform_application = NULL;
+
+    if( ssl->handshake != NULL )
+    {
+        mbedtls_ssl_transform_free( ssl->handshake->transform_earlydata );
+        mbedtls_free( ssl->handshake->transform_earlydata );
+        ssl->handshake->transform_earlydata = NULL;
+
+        mbedtls_ssl_transform_free( ssl->handshake->transform_handshake );
+        mbedtls_free( ssl->handshake->transform_handshake );
+        ssl->handshake->transform_handshake = NULL;
+    }
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
 }
 
 int mbedtls_ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
@@ -3395,7 +3487,7 @@
 
     ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
 
-    ssl_session_reset_msg_layer( ssl, partial );
+    mbedtls_ssl_session_reset_msg_layer( ssl, partial );
 
     /* Reset renegotiation state */
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
@@ -3890,7 +3982,7 @@
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
 int mbedtls_ssl_conf_psk_opaque( mbedtls_ssl_config *conf,
-                                 psa_key_id_t psk,
+                                 mbedtls_svc_key_id_t psk,
                                  const unsigned char *psk_identity,
                                  size_t psk_identity_len )
 {
@@ -3915,7 +4007,7 @@
 }
 
 int mbedtls_ssl_set_hs_psk_opaque( mbedtls_ssl_context *ssl,
-                                   psa_key_id_t psk )
+                                   mbedtls_svc_key_id_t psk )
 {
     if( ( mbedtls_svc_key_id_is_null( psk ) ) ||
         ( ssl->handshake == NULL ) )
@@ -3944,6 +4036,9 @@
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
+    mbedtls_mpi_free( &conf->dhm_P );
+    mbedtls_mpi_free( &conf->dhm_G );
+
     if( ( ret = mbedtls_mpi_read_binary( &conf->dhm_P, dhm_P, P_len ) ) != 0 ||
         ( ret = mbedtls_mpi_read_binary( &conf->dhm_G, dhm_G, G_len ) ) != 0 )
     {
@@ -3959,6 +4054,9 @@
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
+    mbedtls_mpi_free( &conf->dhm_P );
+    mbedtls_mpi_free( &conf->dhm_G );
+
     if( ( ret = mbedtls_dhm_get_value( dhm_ctx, MBEDTLS_DHM_PARAM_P,
                                        &conf->dhm_P ) ) != 0 ||
         ( ret = mbedtls_dhm_get_value( dhm_ctx, MBEDTLS_DHM_PARAM_G,
@@ -3985,6 +4083,7 @@
 #endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+#if !defined(MBEDTLS_DEPRECATED_REMOVED) && defined(MBEDTLS_SSL_PROTO_TLS1_2)
 /*
  * Set allowed/preferred hashes for handshake signatures
  */
@@ -3993,15 +4092,17 @@
 {
     conf->sig_hashes = hashes;
 }
+#endif /* !MBEDTLS_DEPRECATED_REMOVED && MBEDTLS_SSL_PROTO_TLS1_2 */
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
-/* Configure allowed signature algorithms for use in TLS 1.3 */
+/* Configure allowed signature algorithms for handshake */
 void mbedtls_ssl_conf_sig_algs( mbedtls_ssl_config *conf,
                                 const uint16_t* sig_algs )
 {
-    conf->tls13_sig_algs = sig_algs;
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+    conf->sig_hashes = NULL;
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+    conf->sig_algs = sig_algs;
 }
-#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
 #if defined(MBEDTLS_ECP_C)
@@ -4358,6 +4459,14 @@
     return( 0xFFFFFFFF );
 }
 
+int mbedtls_ssl_get_ciphersuite_id_from_ssl( const mbedtls_ssl_context *ssl )
+{
+    if( ssl == NULL || ssl->session == NULL )
+        return( 0 );
+
+    return( ssl->session->ciphersuite );
+}
+
 const char *mbedtls_ssl_get_ciphersuite( const mbedtls_ssl_context *ssl )
 {
     if( ssl == NULL || ssl->session == NULL )
@@ -5484,6 +5593,15 @@
 #endif /* MBEDTLS_DEPRECATED_REMOVED */
 #endif /* MBEDTLS_ECP_C */
 
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+    if ( ssl->handshake->sig_algs_heap_allocated )
+        mbedtls_free( (void*) handshake->sig_algs );
+    handshake->sig_algs = NULL;
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+
 #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
     if( ssl->conf->f_async_cancel != NULL && handshake->async_in_progress != 0 )
     {
@@ -5571,11 +5689,14 @@
     mbedtls_pk_free( &handshake->peer_pubkey );
 #endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
 
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
+#if defined(MBEDTLS_SSL_PROTO_DTLS) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
     mbedtls_free( handshake->verify_cookie );
+#endif /* MBEDTLS_SSL_PROTO_DTLS || MBEDTLS_SSL_PROTO_TLS1_3 */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
     mbedtls_ssl_flight_free( handshake->flight );
     mbedtls_ssl_buffering_free( ssl );
-#endif
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
 
 #if defined(MBEDTLS_ECDH_C) &&                  \
     defined(MBEDTLS_USE_PSA_CRYPTO)
@@ -6321,6 +6442,7 @@
 }
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
 /* The selection should be the same as mbedtls_x509_crt_profile_default in
  * x509_crt.c. Here, the order matters. Currently we favor stronger hashes,
  * for no fundamental reason.
@@ -6338,7 +6460,8 @@
 #endif
     MBEDTLS_MD_NONE
 };
-#endif
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
 /* The selection should be the same as mbedtls_x509_crt_profile_default in
  * x509_crt.c, plus Montgomery curves for ECDHE. Here, the order matters:
@@ -6381,57 +6504,112 @@
 };
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
 static int ssl_preset_suiteb_hashes[] = {
+#if defined(MBEDTLS_SHA256_C)
     MBEDTLS_MD_SHA256,
+#endif
+#if defined(MBEDTLS_SHA384_C)
     MBEDTLS_MD_SHA384,
+#endif
     MBEDTLS_MD_NONE
 };
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+/* NOTICE:
+ *   For ssl_preset_*_sig_algs and ssl_tls12_preset_*_sig_algs, the following
+ *   rules SHOULD be upheld.
+ *   - No duplicate entries.
+ *   - But if there is a good reason, do not change the order of the algorithms.
+ *   - ssl_tls12_present* is for TLS 1.2 use only.
+ *   - ssl_preset_* is for TLS 1.3 only or hybrid TLS 1.3/1.2 handshakes.
+ */
 static uint16_t ssl_preset_default_sig_algs[] = {
-    /* ECDSA algorithms */
-#if defined(MBEDTLS_ECDSA_C)
-#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+
+#if defined(MBEDTLS_ECDSA_C) &&  defined(MBEDTLS_SHA256_C) && \
+    defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
     MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256,
-#endif /* MBEDTLS_SHA256_C && MBEDTLS_ECP_DP_SECP256R1_ENABLED */
-#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_SHA256_C &&
+          MBEDTLS_ECP_DP_SECP256R1_ENABLED */
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_SHA384_C) && \
+    defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
     MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384,
-#endif /* MBEDTLS_SHA384_C && MBEDTLS_ECP_DP_SECP384R1_ENABLED */
-#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_SHA384_C &&
+          MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_SHA512_C) && \
+    defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
     MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512,
-#endif /* MBEDTLS_SHA512_C && MBEDTLS_ECP_DP_SECP521R1_ENABLED */
-#endif /* MBEDTLS_ECDSA_C */
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_SHA384_C &&
+          MBEDTLS_ECP_DP_SECP521R1_ENABLED */
 
-    /* RSA algorithms */
-#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && defined(MBEDTLS_SHA256_C)
     MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256,
-#endif
+#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT && MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_RSA_C) &&  defined(MBEDTLS_SHA256_C)
     MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256,
+#endif /* MBEDTLS_RSA_C && MBEDTLS_SHA256_C */
 
     MBEDTLS_TLS1_3_SIG_NONE
 };
 
+/* NOTICE: see above */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+static uint16_t ssl_tls12_preset_default_sig_algs[] = {
+#if defined(MBEDTLS_SHA512_C)
+    MBEDTLS_SSL_SIG_ALG( MBEDTLS_SSL_HASH_SHA512 )
+#endif
+#if defined(MBEDTLS_SHA384_C)
+    MBEDTLS_SSL_SIG_ALG( MBEDTLS_SSL_HASH_SHA384 )
+#endif
+#if defined(MBEDTLS_SHA256_C)
+    MBEDTLS_SSL_SIG_ALG( MBEDTLS_SSL_HASH_SHA256 )
+#endif
+    MBEDTLS_TLS1_3_SIG_NONE
+};
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+/* NOTICE: see above */
 static uint16_t ssl_preset_suiteb_sig_algs[] = {
-    /* ECDSA algorithms */
-#if defined(MBEDTLS_ECDSA_C)
-#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
-    MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256,
-#endif /* MBEDTLS_SHA256_C && MBEDTLS_ECP_DP_SECP256R1_ENABLED */
-#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
-    MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384,
-#endif /* MBEDTLS_SHA384_C && MBEDTLS_ECP_DP_SECP384R1_ENABLED */
-#endif /* MBEDTLS_ECDSA_C */
 
-    /* RSA algorithms */
-#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
+#if defined(MBEDTLS_ECDSA_C) &&  defined(MBEDTLS_SHA256_C) && \
+    defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+    MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256,
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_SHA256_C &&
+          MBEDTLS_ECP_DP_SECP256R1_ENABLED */
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_SHA384_C) && \
+    defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+    MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384,
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_SHA384_C &&
+          MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && defined(MBEDTLS_SHA256_C)
     MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256,
-#endif
+#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT && MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_RSA_C) &&  defined(MBEDTLS_SHA256_C)
     MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256,
+#endif /* MBEDTLS_RSA_C && MBEDTLS_SHA256_C */
 
     MBEDTLS_TLS1_3_SIG_NONE
 };
-#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+
+/* NOTICE: see above */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+static uint16_t ssl_tls12_preset_suiteb_sig_algs[] = {
+#if defined(MBEDTLS_SHA256_C)
+    MBEDTLS_SSL_SIG_ALG( MBEDTLS_SSL_HASH_SHA256 )
 #endif
+#if defined(MBEDTLS_SHA384_C)
+    MBEDTLS_SSL_SIG_ALG( MBEDTLS_SSL_HASH_SHA384 )
+#endif
+    MBEDTLS_TLS1_3_SIG_NONE
+};
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
 static uint16_t ssl_preset_suiteb_groups[] = {
 #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
@@ -6443,6 +6621,31 @@
     MBEDTLS_SSL_IANA_TLS_GROUP_NONE
 };
 
+#if defined(MBEDTLS_DEBUG_C) && defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+/* Function for checking `ssl_preset_*_sig_algs` and `ssl_tls12_preset_*_sig_algs`
+ * to make sure there are no duplicated signature algorithm entries. */
+static int ssl_check_no_sig_alg_duplication( uint16_t * sig_algs )
+{
+    size_t i, j;
+    int ret = 0;
+
+    for( i = 0; sig_algs[i] != MBEDTLS_TLS1_3_SIG_NONE; i++ )
+    {
+        for( j = 0; j < i; j++ )
+        {
+            if( sig_algs[i] != sig_algs[j] )
+                continue;
+            mbedtls_printf( " entry(%04x,%" MBEDTLS_PRINTF_SIZET
+                            ") is duplicated at %" MBEDTLS_PRINTF_SIZET "\n",
+                            sig_algs[i], j, i );
+            ret = -1;
+        }
+    }
+    return( ret );
+}
+
+#endif /* MBEDTLS_DEBUG_C && MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+
 /*
  * Load default in mbedtls_ssl_config
  */
@@ -6453,6 +6656,34 @@
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 #endif
 
+#if defined(MBEDTLS_DEBUG_C) && defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+    if( ssl_check_no_sig_alg_duplication( ssl_preset_suiteb_sig_algs ) )
+    {
+        mbedtls_printf( "ssl_preset_suiteb_sig_algs has duplicated entries\n" );
+        return( MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED );
+    }
+
+    if( ssl_check_no_sig_alg_duplication( ssl_preset_default_sig_algs ) )
+    {
+        mbedtls_printf( "ssl_preset_default_sig_algs has duplicated entries\n" );
+        return( MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED );
+    }
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    if( ssl_check_no_sig_alg_duplication( ssl_tls12_preset_suiteb_sig_algs ) )
+    {
+        mbedtls_printf( "ssl_tls12_preset_suiteb_sig_algs has duplicated entries\n" );
+        return( MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED );
+    }
+
+    if( ssl_check_no_sig_alg_duplication( ssl_tls12_preset_default_sig_algs ) )
+    {
+        mbedtls_printf( "ssl_tls12_preset_default_sig_algs has duplicated entries\n" );
+        return( MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED );
+    }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+#endif /* MBEDTLS_DEBUG_C && MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+
     /* Use the functions here so that they are covered in tests,
      * but otherwise access member directly for efficiency */
     mbedtls_ssl_conf_endpoint( conf, endpoint );
@@ -6549,10 +6780,15 @@
 #endif
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
             conf->sig_hashes = ssl_preset_suiteb_hashes;
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
-            conf->tls13_sig_algs = ssl_preset_suiteb_sig_algs;
-#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+            if( mbedtls_ssl_conf_is_tls12_only( conf ) )
+                conf->sig_algs = ssl_tls12_preset_suiteb_sig_algs;
+            else
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+                conf->sig_algs = ssl_preset_suiteb_sig_algs;
 #endif
 
 #if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_DEPRECATED_REMOVED)
@@ -6587,10 +6823,15 @@
 #endif
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
             conf->sig_hashes = ssl_preset_default_hashes;
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
-            conf->tls13_sig_algs = ssl_preset_default_sig_algs;
-#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+            if( mbedtls_ssl_conf_is_tls12_only( conf ) )
+                conf->sig_algs = ssl_tls12_preset_default_sig_algs;
+            else
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+                conf->sig_algs = ssl_preset_default_sig_algs;
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
 #if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_DEPRECATED_REMOVED)
@@ -6836,27 +7077,6 @@
 }
 #endif /* MBEDTLS_ECP_C */
 
-#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
-/*
- * Check if a hash proposed by the peer is in our list.
- * Return 0 if we're willing to use it, -1 otherwise.
- */
-int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl,
-                                mbedtls_md_type_t md )
-{
-    const int *cur;
-
-    if( ssl->conf->sig_hashes == NULL )
-        return( -1 );
-
-    for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ )
-        if( *cur == (int) md )
-            return( 0 );
-
-    return( -1 );
-}
-#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
-
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
                           const mbedtls_ssl_ciphersuite_t *ciphersuite,
@@ -7187,6 +7407,236 @@
     }
     return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
 }
+
 #endif /* !MBEDTLS_USE_PSA_CRYPTO */
 
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) || \
+    defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+/*
+ * Function for writing a supported groups (TLS 1.3) or supported elliptic
+ * curves (TLS 1.2) extension.
+ *
+ * The "extension_data" field of a supported groups extension contains a
+ * "NamedGroupList" value (TLS 1.3 RFC8446):
+ *      enum {
+ *          secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019),
+ *          x25519(0x001D), x448(0x001E),
+ *          ffdhe2048(0x0100), ffdhe3072(0x0101), ffdhe4096(0x0102),
+ *          ffdhe6144(0x0103), ffdhe8192(0x0104),
+ *          ffdhe_private_use(0x01FC..0x01FF),
+ *          ecdhe_private_use(0xFE00..0xFEFF),
+ *          (0xFFFF)
+ *      } NamedGroup;
+ *      struct {
+ *          NamedGroup named_group_list<2..2^16-1>;
+ *      } NamedGroupList;
+ *
+ * The "extension_data" field of a supported elliptic curves extension contains
+ * a "NamedCurveList" value (TLS 1.2 RFC 8422):
+ * enum {
+ *      deprecated(1..22),
+ *      secp256r1 (23), secp384r1 (24), secp521r1 (25),
+ *      x25519(29), x448(30),
+ *      reserved (0xFE00..0xFEFF),
+ *      deprecated(0xFF01..0xFF02),
+ *      (0xFFFF)
+ *  } NamedCurve;
+ * struct {
+ *      NamedCurve named_curve_list<2..2^16-1>
+ *  } NamedCurveList;
+ *
+ * The TLS 1.3 supported groups extension was defined to be a compatible
+ * generalization of the TLS 1.2 supported elliptic curves extension. They both
+ * share the same extension identifier.
+ *
+ * DHE groups are not supported yet.
+ */
+int mbedtls_ssl_write_supported_groups_ext( mbedtls_ssl_context *ssl,
+                                            unsigned char *buf,
+                                            const unsigned char *end,
+                                            size_t *out_len )
+{
+    unsigned char *p = buf ;
+    unsigned char *named_group_list; /* Start of named_group_list */
+    size_t named_group_list_len;     /* Length of named_group_list */
+    const uint16_t *group_list = mbedtls_ssl_get_groups( ssl );
+
+    *out_len = 0;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_groups extension" ) );
+
+    /* Check if we have space for header and length fields:
+     * - extension_type            (2 bytes)
+     * - extension_data_length     (2 bytes)
+     * - named_group_list_length   (2 bytes)
+     */
+    MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 );
+    p += 6;
+
+    named_group_list = p;
+
+    if( group_list == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_CONFIG );
+
+    for( ; *group_list != 0; group_list++ )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "got supported group(%04x)", *group_list ) );
+
+#if defined(MBEDTLS_ECP_C)
+        if( ( mbedtls_ssl_conf_is_tls13_enabled( ssl->conf ) &&
+              mbedtls_ssl_tls13_named_group_is_ecdhe( *group_list ) ) ||
+            ( mbedtls_ssl_conf_is_tls12_enabled( ssl->conf ) &&
+              mbedtls_ssl_tls12_named_group_is_ecdhe( *group_list ) ) )
+        {
+            const mbedtls_ecp_curve_info *curve_info;
+            curve_info = mbedtls_ecp_curve_info_from_tls_id( *group_list );
+            if( curve_info == NULL )
+                continue;
+            MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
+            MBEDTLS_PUT_UINT16_BE( *group_list, p, 0 );
+            p += 2;
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "NamedGroup: %s ( %x )",
+                                curve_info->name, *group_list ) );
+        }
+#endif /* MBEDTLS_ECP_C */
+        /* Add DHE groups here */
+
+    }
+
+    /* Length of named_group_list */
+    named_group_list_len = p - named_group_list;
+    if( named_group_list_len == 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "No group available." ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    /* Write extension_type */
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SUPPORTED_GROUPS, buf, 0 );
+    /* Write extension_data_length */
+    MBEDTLS_PUT_UINT16_BE( named_group_list_len + 2, buf, 2 );
+    /* Write length of named_group_list */
+    MBEDTLS_PUT_UINT16_BE( named_group_list_len, buf, 4 );
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "Supported groups extension",
+                           buf + 4, named_group_list_len + 2 );
+
+    *out_len = p - buf;
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+    ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SUPPORTED_GROUPS;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED ||
+          MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
+          MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+/*
+ * Function for writing a signature algorithm extension.
+ *
+ * The `extension_data` field of signature algorithm contains  a `SignatureSchemeList`
+ * value (TLS 1.3 RFC8446):
+ *      enum {
+ *         ....
+ *        ecdsa_secp256r1_sha256( 0x0403 ),
+ *        ecdsa_secp384r1_sha384( 0x0503 ),
+ *        ecdsa_secp521r1_sha512( 0x0603 ),
+ *         ....
+ *      } SignatureScheme;
+ *
+ *      struct {
+ *         SignatureScheme supported_signature_algorithms<2..2^16-2>;
+ *      } SignatureSchemeList;
+ *
+ * The `extension_data` field of signature algorithm contains a `SignatureAndHashAlgorithm`
+ * value (TLS 1.2 RFC5246):
+ *      enum {
+ *          none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
+ *          sha512(6), (255)
+ *      } HashAlgorithm;
+ *
+ *      enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
+ *        SignatureAlgorithm;
+ *
+ *      struct {
+ *          HashAlgorithm hash;
+ *          SignatureAlgorithm signature;
+ *      } SignatureAndHashAlgorithm;
+ *
+ *      SignatureAndHashAlgorithm
+ *        supported_signature_algorithms<2..2^16-2>;
+ *
+ * The TLS 1.3 signature algorithm extension was defined to be a compatible
+ * generalization of the TLS 1.2 signature algorithm extension.
+ * `SignatureAndHashAlgorithm` field of TLS 1.2 can be represented by
+ * `SignatureScheme` field of TLS 1.3
+ *
+ */
+int mbedtls_ssl_write_sig_alg_ext( mbedtls_ssl_context *ssl, unsigned char *buf,
+                                   const unsigned char *end, size_t *out_len )
+{
+    unsigned char *p = buf;
+    unsigned char *supported_sig_alg; /* Start of supported_signature_algorithms */
+    size_t supported_sig_alg_len = 0; /* Length of supported_signature_algorithms */
+
+    *out_len = 0;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding signature_algorithms extension" ) );
+
+    /* Check if we have space for header and length field:
+     * - extension_type         (2 bytes)
+     * - extension_data_length  (2 bytes)
+     * - supported_signature_algorithms_length   (2 bytes)
+     */
+    MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 );
+    p += 6;
+
+    /*
+     * Write supported_signature_algorithms
+     */
+    supported_sig_alg = p;
+    const uint16_t *sig_alg = mbedtls_ssl_get_sig_algs( ssl );
+    if( sig_alg == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_CONFIG );
+
+    for( ; *sig_alg != MBEDTLS_TLS1_3_SIG_NONE; sig_alg++ )
+    {
+        if( ! mbedtls_ssl_sig_alg_is_supported( ssl, *sig_alg ) )
+            continue;
+        MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
+        MBEDTLS_PUT_UINT16_BE( *sig_alg, p, 0 );
+        p += 2;
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "signature scheme [%x]", *sig_alg ) );
+    }
+
+    /* Length of supported_signature_algorithms */
+    supported_sig_alg_len = p - supported_sig_alg;
+    if( supported_sig_alg_len == 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "No signature algorithms defined." ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    /* Write extension_type */
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SIG_ALG, buf, 0 );
+    /* Write extension_data_length */
+    MBEDTLS_PUT_UINT16_BE( supported_sig_alg_len + 2, buf, 2 );
+    /* Write length of supported_signature_algorithms */
+    MBEDTLS_PUT_UINT16_BE( supported_sig_alg_len, buf, 4 );
+
+    /* Output the total length of signature algorithms extension. */
+    *out_len = p - buf;
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+    ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SIG_ALG;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+    return( 0 );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+
 #endif /* MBEDTLS_SSL_TLS_C */
diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c
index dcf1ff8..ca91d67 100644
--- a/library/ssl_tls13_client.c
+++ b/library/ssl_tls13_client.c
@@ -115,161 +115,26 @@
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
 
-/*
- * Functions for writing supported_groups extension.
- *
- * Stucture of supported_groups:
- *      enum {
- *          secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019),
- *          x25519(0x001D), x448(0x001E),
- *          ffdhe2048(0x0100), ffdhe3072(0x0101), ffdhe4096(0x0102),
- *          ffdhe6144(0x0103), ffdhe8192(0x0104),
- *          ffdhe_private_use(0x01FC..0x01FF),
- *          ecdhe_private_use(0xFE00..0xFEFF),
- *          (0xFFFF)
- *      } NamedGroup;
- *      struct {
- *          NamedGroup named_group_list<2..2^16-1>;
- *      } NamedGroupList;
- */
+static int ssl_tls13_reset_key_share( mbedtls_ssl_context *ssl )
+{
+    uint16_t group_id = ssl->handshake->offered_group_id;
+    if( group_id == 0 )
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+
 #if defined(MBEDTLS_ECDH_C)
-/*
- * In versions of TLS prior to TLS 1.3, this extension was named
- * 'elliptic_curves' and only contained elliptic curve groups.
- */
-static int ssl_tls13_write_named_group_list_ecdhe( mbedtls_ssl_context *ssl,
-                                                   unsigned char *buf,
-                                                   unsigned char *end,
-                                                   size_t *out_len )
-{
-    unsigned char *p = buf;
-
-    *out_len = 0;
-
-    const uint16_t *group_list = mbedtls_ssl_get_groups( ssl );
-
-    if( group_list == NULL )
-        return( MBEDTLS_ERR_SSL_BAD_CONFIG );
-
-    for ( ; *group_list != 0; group_list++ )
+    if( mbedtls_ssl_tls13_named_group_is_ecdhe( group_id ) )
     {
-        const mbedtls_ecp_curve_info *curve_info;
-        curve_info = mbedtls_ecp_curve_info_from_tls_id( *group_list );
-        if( curve_info == NULL )
-            continue;
-
-        if( !mbedtls_ssl_tls13_named_group_is_ecdhe( *group_list ) )
-            continue;
-
-        MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2);
-        MBEDTLS_PUT_UINT16_BE( *group_list, p, 0 );
-        p += 2;
-
-        MBEDTLS_SSL_DEBUG_MSG( 3, ( "NamedGroup: %s ( %x )",
-                                    curve_info->name, *group_list ) );
-    }
-
-    *out_len = p - buf;
-
-    return( 0 );
-}
-#else
-static int ssl_tls13_write_named_group_list_ecdhe( mbedtls_ssl_context *ssl,
-                                            unsigned char *buf,
-                                            unsigned char *end,
-                                            size_t *out_len )
-{
-    ((void) ssl);
-    ((void) buf);
-    ((void) end);
-    *out_len = 0;
-    return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
-}
-#endif /* MBEDTLS_ECDH_C */
-
-static int ssl_tls13_write_named_group_list_dhe( mbedtls_ssl_context *ssl,
-                                        unsigned char *buf,
-                                        unsigned char *end,
-                                        size_t *out_len )
-{
-    ((void) ssl);
-    ((void) buf);
-    ((void) end);
-    *out_len = 0;
-    MBEDTLS_SSL_DEBUG_MSG( 3, ( "write_named_group_dhe is not implemented" ) );
-    return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
-}
-
-static int ssl_tls13_write_supported_groups_ext( mbedtls_ssl_context *ssl,
-                                                 unsigned char *buf,
-                                                 unsigned char *end,
-                                                 size_t *out_len )
-{
-    unsigned char *p = buf ;
-    unsigned char *named_group_list; /* Start of named_group_list */
-    size_t named_group_list_len;     /* Length of named_group_list */
-    size_t output_len = 0;
-    int ret_ecdhe, ret_dhe;
-
-    *out_len = 0;
-
-    if( !mbedtls_ssl_conf_tls13_some_ephemeral_enabled( ssl ) )
+        mbedtls_ecdh_free( &ssl->handshake->ecdh_ctx );
         return( 0 );
-
-    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_groups extension" ) );
-
-    /* Check if we have space for header and length fields:
-     * - extension_type            (2 bytes)
-     * - extension_data_length     (2 bytes)
-     * - named_group_list_length   (2 bytes)
-     */
-    MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 );
-    p += 6;
-
-    named_group_list = p;
-    ret_ecdhe = ssl_tls13_write_named_group_list_ecdhe( ssl, p, end, &output_len );
-    if( ret_ecdhe != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls13_write_named_group_list_ecdhe", ret_ecdhe );
     }
-    p += output_len;
-
-    ret_dhe = ssl_tls13_write_named_group_list_dhe( ssl, p, end, &output_len );
-    if( ret_dhe != 0 )
+    else
+#endif /* MBEDTLS_ECDH_C */
+    if( 0 /* other KEMs? */ )
     {
-        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls13_write_named_group_list_dhe", ret_dhe );
-    }
-    p += output_len;
-
-    /* Both ECDHE and DHE failed. */
-    if( ret_ecdhe != 0 && ret_dhe != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Both ECDHE and DHE groups are fail. " ) );
-        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        /* Do something */
     }
 
-    /* Length of named_group_list*/
-    named_group_list_len = p - named_group_list;
-    if( named_group_list_len == 0 )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "No group available." ) );
-        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-    }
-
-    /* Write extension_type */
-    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SUPPORTED_GROUPS, buf, 0 );
-    /* Write extension_data_length */
-    MBEDTLS_PUT_UINT16_BE( named_group_list_len + 2, buf, 2 );
-    /* Write length of named_group_list */
-    MBEDTLS_PUT_UINT16_BE( named_group_list_len, buf, 4 );
-
-    MBEDTLS_SSL_DEBUG_BUF( 3, "Supported groups extension", buf + 4, named_group_list_len + 2 );
-
-    *out_len = p - buf;
-
-    ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SUPPORTED_GROUPS;
-
-    return( 0 );
+    return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
 }
 
 /*
@@ -376,9 +241,6 @@
 
     *out_len = 0;
 
-    if( !mbedtls_ssl_conf_tls13_some_ephemeral_enabled( ssl ) )
-        return( 0 );
-
     /* Check if we have space for header and length fields:
      * - extension_type         (2 bytes)
      * - extension_data_length  (2 bytes)
@@ -532,6 +394,76 @@
 #endif /* MBEDTLS_ECDH_C */
 
 /*
+ * ssl_tls13_parse_hrr_key_share_ext()
+ *      Parse key_share extension in Hello Retry Request
+ *
+ * struct {
+ *        NamedGroup selected_group;
+ * } KeyShareHelloRetryRequest;
+ */
+static int ssl_tls13_parse_hrr_key_share_ext( mbedtls_ssl_context *ssl,
+                                              const unsigned char *buf,
+                                              const unsigned char *end )
+{
+    const mbedtls_ecp_curve_info *curve_info = NULL;
+    const unsigned char *p = buf;
+    int selected_group;
+    int found = 0;
+
+    const uint16_t *group_list = mbedtls_ssl_get_groups( ssl );
+    if( group_list == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_CONFIG );
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "key_share extension", p, end - buf );
+
+    /* Read selected_group */
+    MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, 2 );
+    selected_group = MBEDTLS_GET_UINT16_BE( p, 0 );
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected_group ( %d )", selected_group ) );
+
+    /* Upon receipt of this extension in a HelloRetryRequest, the client
+     * MUST first verify that the selected_group field corresponds to a
+     * group which was provided in the "supported_groups" extension in the
+     * original ClientHello.
+     * The supported_group was based on the info in ssl->conf->group_list.
+     *
+     * If the server provided a key share that was not sent in the ClientHello
+     * then the client MUST abort the handshake with an "illegal_parameter" alert.
+     */
+    for( ; *group_list != 0; group_list++ )
+    {
+        curve_info = mbedtls_ecp_curve_info_from_tls_id( *group_list );
+        if( curve_info == NULL || curve_info->tls_id != selected_group )
+            continue;
+
+        /* We found a match */
+        found = 1;
+        break;
+    }
+
+    /* Client MUST verify that the selected_group field does not
+     * correspond to a group which was provided in the "key_share"
+     * extension in the original ClientHello. If the server sent an
+     * HRR message with a key share already provided in the
+     * ClientHello then the client MUST abort the handshake with
+     * an "illegal_parameter" alert.
+     */
+    if( found == 0 || selected_group == ssl->handshake->offered_group_id )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Invalid key share in HRR" ) );
+        MBEDTLS_SSL_PEND_FATAL_ALERT(
+                MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
+                MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
+        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
+    }
+
+    /* Remember server's preference for next ClientHello */
+    ssl->handshake->offered_group_id = selected_group;
+
+    return( 0 );
+}
+
+/*
  * ssl_tls13_parse_key_share_ext()
  *      Parse key_share extension in Server Hello
  *
@@ -594,6 +526,55 @@
 
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
+/*
+ * ssl_tls13_parse_cookie_ext()
+ *      Parse cookie extension in Hello Retry Request
+ *
+ * struct {
+ *        opaque cookie<1..2^16-1>;
+ * } Cookie;
+ *
+ * When sending a HelloRetryRequest, the server MAY provide a "cookie"
+ * extension to the client (this is an exception to the usual rule that
+ * the only extensions that may be sent are those that appear in the
+ * ClientHello).  When sending the new ClientHello, the client MUST copy
+ * the contents of the extension received in the HelloRetryRequest into
+ * a "cookie" extension in the new ClientHello.  Clients MUST NOT use
+ * cookies in their initial ClientHello in subsequent connections.
+ */
+static int ssl_tls13_parse_cookie_ext( mbedtls_ssl_context *ssl,
+                                       const unsigned char *buf,
+                                       const unsigned char *end )
+{
+    size_t cookie_len;
+    const unsigned char *p = buf;
+    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
+
+    /* Retrieve length field of cookie */
+    MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, 2 );
+    cookie_len = MBEDTLS_GET_UINT16_BE( p, 0 );
+    p += 2;
+
+    MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, cookie_len );
+    MBEDTLS_SSL_DEBUG_BUF( 3, "cookie extension", p, cookie_len );
+
+    mbedtls_free( handshake->verify_cookie );
+    handshake->verify_cookie_len = 0;
+    handshake->verify_cookie = mbedtls_calloc( 1, cookie_len );
+    if( handshake->verify_cookie == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1,
+                ( "alloc failed ( %" MBEDTLS_PRINTF_SIZET " bytes )",
+                  cookie_len ) );
+        return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+    }
+
+    memcpy( handshake->verify_cookie, p, cookie_len );
+    handshake->verify_cookie_len = (unsigned char) cookie_len;
+
+    return( 0 );
+}
+
 /* Write cipher_suites
  * CipherSuite cipher_suites<2..2^16-2>;
  */
@@ -773,40 +754,28 @@
     p += output_len;
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
-    /* Write supported_groups extension
-     *
-     * It is REQUIRED for ECDHE cipher_suites.
-     */
-    ret = ssl_tls13_write_supported_groups_ext( ssl, p, end, &output_len );
-    if( ret != 0 )
-        return( ret );
-    p += output_len;
 
-    /* Write key_share extension
-     *
-     * We need to send the key shares under three conditions:
-     * 1) A certificate-based ciphersuite is being offered. In this case
-     *    supported_groups and supported_signature extensions have been
-     *    successfully added.
-     * 2) A PSK-based ciphersuite with ECDHE is offered. In this case the
-     *    psk_key_exchange_modes has been added as the last extension.
-     * 3) Or, in case all ciphers are supported ( which includes #1 and #2
-     *    from above )
+    /*
+     * Add the extensions related to (EC)DHE ephemeral key establishment only if
+     * enabled as per the configuration.
      */
-    ret = ssl_tls13_write_key_share_ext( ssl, p, end, &output_len );
-    if( ret != 0 )
-        return( ret );
-    p += output_len;
+    if( mbedtls_ssl_conf_tls13_some_ephemeral_enabled( ssl ) )
+    {
+        ret = mbedtls_ssl_write_supported_groups_ext( ssl, p, end, &output_len );
+        if( ret != 0 )
+            return( ret );
+        p += output_len;
 
-    /* Write signature_algorithms extension
-     *
-     * It is REQUIRED for certificate authenticated cipher_suites.
-     */
-    ret = mbedtls_ssl_tls13_write_sig_alg_ext( ssl, p, end, &output_len );
-    if( ret != 0 )
-        return( ret );
-    p += output_len;
+        ret = ssl_tls13_write_key_share_ext( ssl, p, end, &output_len );
+        if( ret != 0 )
+            return( ret );
+        p += output_len;
 
+        ret = mbedtls_ssl_write_sig_alg_ext( ssl, p, end, &output_len );
+        if( ret != 0 )
+            return( ret );
+        p += output_len;
+    }
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
@@ -919,7 +888,8 @@
 /* Returns a negative value on failure, and otherwise
  * - SSL_SERVER_HELLO_COORDINATE_HELLO or
  * - SSL_SERVER_HELLO_COORDINATE_HRR
- * to indicate which message is expected and to be parsed next. */
+ * to indicate which message is expected and to be parsed next.
+ */
 #define SSL_SERVER_HELLO_COORDINATE_HELLO 0
 #define SSL_SERVER_HELLO_COORDINATE_HRR 1
 static int ssl_server_hello_is_hrr( mbedtls_ssl_context *ssl,
@@ -968,20 +938,9 @@
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
-    MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_read_record( ssl, 0 ) );
-
-    if( ( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) ||
-        ( ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO ) )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "unexpected message" ) );
-
-        MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
-                                      MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
-        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
-    }
-
-    *buf = ssl->in_msg + 4;
-    *buf_len = ssl->in_hslen - 4;
+    MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_tls13_fetch_handshake_msg( ssl,
+                                             MBEDTLS_SSL_HS_SERVER_HELLO,
+                                             buf, buf_len ) );
 
     ret = ssl_server_hello_is_hrr( ssl, *buf, *buf + *buf_len );
     switch( ret )
@@ -991,6 +950,36 @@
             break;
         case SSL_SERVER_HELLO_COORDINATE_HRR:
             MBEDTLS_SSL_DEBUG_MSG( 2, ( "received HelloRetryRequest message" ) );
+             /* If a client receives a second
+              * HelloRetryRequest in the same connection (i.e., where the ClientHello
+              * was itself in response to a HelloRetryRequest), it MUST abort the
+              * handshake with an "unexpected_message" alert.
+              */
+            if( ssl->handshake->hello_retry_request_count > 0 )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "Multiple HRRs received" ) );
+                MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
+                                    MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+                return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+            }
+            /*
+             * Clients must abort the handshake with an "illegal_parameter"
+             * alert if the HelloRetryRequest would not result in any change
+             * in the ClientHello.
+             * In a PSK only key exchange that what we expect.
+             */
+            if( ! mbedtls_ssl_conf_tls13_some_ephemeral_enabled( ssl ) )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1,
+                            ( "Unexpected HRR in pure PSK key exchange." ) );
+                MBEDTLS_SSL_PEND_FATAL_ALERT(
+                            MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
+                            MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
+                return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
+            }
+
+            ssl->handshake->hello_retry_request_count++;
+
             break;
     }
 
@@ -1064,14 +1053,18 @@
  */
 static int ssl_tls13_parse_server_hello( mbedtls_ssl_context *ssl,
                                          const unsigned char *buf,
-                                         const unsigned char *end )
+                                         const unsigned char *end,
+                                         int is_hrr )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     const unsigned char *p = buf;
+    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
     size_t extensions_len;
     const unsigned char *extensions_end;
     uint16_t cipher_suite;
     const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+    int supported_versions_ext_found = 0;
+    int fatal_alert = 0;
 
     /*
      * Check there is space for minimal fields
@@ -1099,7 +1092,8 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "Unsupported version of TLS." ) );
         MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION,
                                       MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION );
-        return( MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION );
+        ret = MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION;
+        goto cleanup;
     }
     p += 2;
 
@@ -1109,10 +1103,13 @@
      * with Random defined as:
      * opaque Random[MBEDTLS_SERVER_HELLO_RANDOM_LEN];
      */
-    memcpy( &ssl->handshake->randbytes[MBEDTLS_CLIENT_HELLO_RANDOM_LEN], p,
-            MBEDTLS_SERVER_HELLO_RANDOM_LEN );
-    MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes",
-                           p, MBEDTLS_SERVER_HELLO_RANDOM_LEN );
+    if( !is_hrr )
+    {
+        memcpy( &handshake->randbytes[MBEDTLS_CLIENT_HELLO_RANDOM_LEN], p,
+                MBEDTLS_SERVER_HELLO_RANDOM_LEN );
+        MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes",
+                               p, MBEDTLS_SERVER_HELLO_RANDOM_LEN );
+    }
     p += MBEDTLS_SERVER_HELLO_RANDOM_LEN;
 
     /* ...
@@ -1121,9 +1118,8 @@
      */
     if( ssl_tls13_check_server_hello_session_id_echo( ssl, &p, end ) != 0 )
     {
-        MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
-                                      MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
+        fatal_alert = MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER;
+        goto cleanup;
     }
 
     /* ...
@@ -1137,28 +1133,40 @@
     p += 2;
 
 
+    ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( cipher_suite );
     /*
      * Check whether this ciphersuite is supported and offered.
      * Via the force_ciphersuite version we may have instructed the client
      * to use a different ciphersuite.
      */
-    ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( cipher_suite );
     if( ciphersuite_info == NULL ||
         ssl_tls13_cipher_suite_is_offered( ssl, cipher_suite ) == 0 )
     {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite(%04x) not found or not offered",
-                                    cipher_suite ) );
-
-        MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
-                                      MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
+        fatal_alert = MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER;
+    }
+    /*
+     * If we received an HRR before and that the proposed selected
+     * ciphersuite in this server hello is not the same as the one
+     * proposed in the HRR, we abort the handshake and send an
+     * "illegal_parameter" alert.
+     */
+    else if( ( !is_hrr ) && ( handshake->hello_retry_request_count > 0 ) &&
+             ( cipher_suite != ssl->session_negotiate->ciphersuite ) )
+    {
+        fatal_alert = MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER;
     }
 
+    if( fatal_alert == MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid ciphersuite(%04x) parameter",
+                                    cipher_suite ) );
+        goto cleanup;
+    }
 
     /* Configure ciphersuites */
     mbedtls_ssl_optimize_checksum( ssl, ciphersuite_info );
 
-    ssl->handshake->ciphersuite_info = ciphersuite_info;
+    handshake->ciphersuite_info = ciphersuite_info;
     ssl->session_negotiate->ciphersuite = cipher_suite;
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: ( %04x ) - %s",
@@ -1176,9 +1184,8 @@
     if( p[0] != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad legacy compression method" ) );
-        MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
-                                      MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
+        fatal_alert = MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER;
+        goto cleanup;
     }
     p++;
 
@@ -1204,6 +1211,7 @@
     {
         unsigned int extension_type;
         size_t extension_data_len;
+        const unsigned char *extension_data_end;
 
         MBEDTLS_SSL_CHK_BUF_READ_PTR( p, extensions_end, 4 );
         extension_type = MBEDTLS_GET_UINT16_BE( p, 0 );
@@ -1211,39 +1219,69 @@
         p += 4;
 
         MBEDTLS_SSL_CHK_BUF_READ_PTR( p, extensions_end, extension_data_len );
+        extension_data_end = p + extension_data_len;
 
         switch( extension_type )
         {
+            case MBEDTLS_TLS_EXT_COOKIE:
+
+                if( !is_hrr )
+                {
+                    fatal_alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT;
+                    goto cleanup;
+                }
+
+                ret = ssl_tls13_parse_cookie_ext( ssl,
+                                                  p, extension_data_end );
+                if( ret != 0 )
+                {
+                    MBEDTLS_SSL_DEBUG_RET( 1,
+                                           "ssl_tls13_parse_cookie_ext",
+                                           ret );
+                    goto cleanup;
+                }
+                break;
+
             case MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS:
+                supported_versions_ext_found = 1;
                 MBEDTLS_SSL_DEBUG_MSG( 3,
                             ( "found supported_versions extension" ) );
 
                 ret = ssl_tls13_parse_supported_versions_ext( ssl,
                                                               p,
-                                                              p + extension_data_len );
+                                                              extension_data_end );
                 if( ret != 0 )
-                    return( ret );
+                    goto cleanup;
                 break;
 
             case MBEDTLS_TLS_EXT_PRE_SHARED_KEY:
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found pre_shared_key extension." ) );
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "pre_shared_key:Not supported yet" ) );
 
-                MBEDTLS_SSL_PEND_FATAL_ALERT(
-                    MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT,
-                    MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
-                return( MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
+                fatal_alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT;
+                goto cleanup;
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
             case MBEDTLS_TLS_EXT_KEY_SHARE:
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found key_shares extension" ) );
-                if( ( ret = ssl_tls13_parse_key_share_ext( ssl,
-                                            p, p + extension_data_len ) ) != 0 )
+                if( ! mbedtls_ssl_conf_tls13_some_ephemeral_enabled( ssl ) )
+                {
+                    fatal_alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT;
+                    goto cleanup;
+                }
+
+                if( is_hrr )
+                    ret = ssl_tls13_parse_hrr_key_share_ext( ssl,
+                                            p, extension_data_end );
+                else
+                    ret = ssl_tls13_parse_key_share_ext( ssl,
+                                            p, extension_data_end );
+                if( ret != 0 )
                 {
                     MBEDTLS_SSL_DEBUG_RET( 1,
                                            "ssl_tls13_parse_key_share_ext",
                                            ret );
-                    return( ret );
+                    goto cleanup;
                 }
                 break;
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
@@ -1254,19 +1292,38 @@
                     ( "unknown extension found: %u ( ignoring )",
                       extension_type ) );
 
-                MBEDTLS_SSL_PEND_FATAL_ALERT(
-                    MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT,
-                    MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
-                return( MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
+                fatal_alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT;
+                goto cleanup;
         }
 
         p += extension_data_len;
     }
 
-    return( 0 );
+    if( !supported_versions_ext_found )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "supported_versions not found" ) );
+        fatal_alert = MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER;
+        goto cleanup;
+    }
+
+cleanup:
+
+    if( fatal_alert == MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT )
+    {
+        MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT,
+                                      MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
+        ret = MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION;
+    }
+    else if ( fatal_alert == MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER )
+    {
+        MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
+                                      MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
+        ret = MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
+    }
+    return( ret );
 }
 
-static int ssl_tls13_finalize_server_hello( mbedtls_ssl_context *ssl )
+static int ssl_tls13_postprocess_server_hello( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     mbedtls_ssl_key_set traffic_keys;
@@ -1380,6 +1437,40 @@
     return( ret );
 }
 
+static int ssl_tls13_postprocess_hrr( mbedtls_ssl_context *ssl )
+{
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
+    /* If not offering early data, the client sends a dummy CCS record
+     * immediately before its second flight. This may either be before
+     * its second ClientHello or before its encrypted handshake flight.
+     */
+    mbedtls_ssl_handshake_set_state( ssl,
+            MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO );
+#else
+    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_HELLO );
+#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
+
+    mbedtls_ssl_session_reset_msg_layer( ssl, 0 );
+
+    /*
+     * We are going to re-generate a shared secret corresponding to the group
+     * selected by the server, which is different from the group for which we
+     * generated a shared secret in the first client hello.
+     * Thus, reset the shared secret.
+     */
+    ret = ssl_tls13_reset_key_share( ssl );
+    if( ret != 0 )
+        return( ret );
+#else
+    ((void) ssl);
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+
+    return( 0 );
+}
+
 /*
  * Wait and parse ServerHello handshake message.
  * Handler for MBEDTLS_SSL_SERVER_HELLO
@@ -1387,8 +1478,9 @@
 static int ssl_tls13_process_server_hello( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    unsigned char *buf;
-    size_t buf_len;
+    unsigned char *buf = NULL;
+    size_t buf_len = 0;
+    int is_hrr = 0;
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> %s", __func__ ) );
 
@@ -1401,31 +1493,29 @@
     ssl->handshake->extensions_present = MBEDTLS_SSL_EXT_NONE;
 
     ret = ssl_tls13_server_hello_coordinate( ssl, &buf, &buf_len );
-    /* Parsing step
-     * We know what message to expect by now and call
-     * the respective parsing function.
-     */
-    if( ret == SSL_SERVER_HELLO_COORDINATE_HELLO )
-    {
-        MBEDTLS_SSL_PROC_CHK( ssl_tls13_parse_server_hello( ssl, buf,
-                                                            buf + buf_len ) );
+    if( ret < 0 )
+        goto cleanup;
+    else
+        is_hrr = ( ret == SSL_SERVER_HELLO_COORDINATE_HRR );
 
-        mbedtls_ssl_tls13_add_hs_msg_to_checksum( ssl,
-                                                  MBEDTLS_SSL_HS_SERVER_HELLO,
-                                                  buf, buf_len );
+    MBEDTLS_SSL_PROC_CHK( ssl_tls13_parse_server_hello( ssl, buf,
+                                                        buf + buf_len,
+                                                        is_hrr ) );
+    if( is_hrr )
+        MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_reset_transcript_for_hrr( ssl ) );
 
-        MBEDTLS_SSL_PROC_CHK( ssl_tls13_finalize_server_hello( ssl ) );
-    }
-    else if( ret == SSL_SERVER_HELLO_COORDINATE_HRR )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "HRR not supported" ) );
-        MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ,
-                                      MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
-        ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
-    }
+    mbedtls_ssl_tls13_add_hs_msg_to_checksum( ssl,
+                                              MBEDTLS_SSL_HS_SERVER_HELLO,
+                                              buf, buf_len );
+
+    if( is_hrr )
+        MBEDTLS_SSL_PROC_CHK( ssl_tls13_postprocess_hrr( ssl ) );
+    else
+        MBEDTLS_SSL_PROC_CHK( ssl_tls13_postprocess_server_hello( ssl ) );
 
 cleanup:
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= %s", __func__ ) );
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= %s ( %s )", __func__,
+                                is_hrr?"HelloRetryRequest":"ServerHello" ) );
     return( ret );
 }
 
@@ -1664,8 +1754,6 @@
     if( ret != 0 )
         return( ret );
 
-    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_FINISHED );
-
     return( 0 );
 }
 #endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
@@ -1776,6 +1864,7 @@
          */
 #if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
         case MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED:
+        case MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO:
             ret = ssl_tls13_write_change_cipher_spec( ssl );
             break;
 #endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c
index 1260740..9aa2148 100644
--- a/library/ssl_tls13_generic.c
+++ b/library/ssl_tls13_generic.c
@@ -136,90 +136,6 @@
 }
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
-
-/*
- * mbedtls_ssl_tls13_write_sig_alg_ext( )
- *
- * enum {
- *    ....
- *   ecdsa_secp256r1_sha256( 0x0403 ),
- *   ecdsa_secp384r1_sha384( 0x0503 ),
- *   ecdsa_secp521r1_sha512( 0x0603 ),
- *    ....
- * } SignatureScheme;
- *
- * struct {
- *    SignatureScheme supported_signature_algorithms<2..2^16-2>;
- * } SignatureSchemeList;
- *
- * Only if we handle at least one key exchange that needs signatures.
- */
-int mbedtls_ssl_tls13_write_sig_alg_ext( mbedtls_ssl_context *ssl,
-                                         unsigned char *buf,
-                                         unsigned char *end,
-                                         size_t *out_len )
-{
-    unsigned char *p = buf;
-    unsigned char *supported_sig_alg; /* Start of supported_signature_algorithms */
-    size_t supported_sig_alg_len = 0; /* Length of supported_signature_algorithms */
-
-    *out_len = 0;
-
-    /* Skip the extension on the client if all allowed key exchanges
-     * are PSK-based. */
-#if defined(MBEDTLS_SSL_CLI_C)
-    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
-        !mbedtls_ssl_conf_tls13_some_ephemeral_enabled( ssl ) )
-    {
-        return( 0 );
-    }
-#endif /* MBEDTLS_SSL_CLI_C */
-
-    MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding signature_algorithms extension" ) );
-
-    /* Check if we have space for header and length field:
-     * - extension_type         (2 bytes)
-     * - extension_data_length  (2 bytes)
-     * - supported_signature_algorithms_length   (2 bytes)
-     */
-    MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 );
-    p += 6;
-
-    /*
-     * Write supported_signature_algorithms
-     */
-    supported_sig_alg = p;
-    for( const uint16_t *sig_alg = ssl->conf->tls13_sig_algs;
-         *sig_alg != MBEDTLS_TLS1_3_SIG_NONE; sig_alg++ )
-    {
-        MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
-        MBEDTLS_PUT_UINT16_BE( *sig_alg, p, 0 );
-        p += 2;
-        MBEDTLS_SSL_DEBUG_MSG( 3, ( "signature scheme [%x]", *sig_alg ) );
-    }
-
-    /* Length of supported_signature_algorithms */
-    supported_sig_alg_len = p - supported_sig_alg;
-    if( supported_sig_alg_len == 0 )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "No signature algorithms defined." ) );
-        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-    }
-
-    /* Write extension_type */
-    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SIG_ALG, buf, 0 );
-    /* Write extension_data_length */
-    MBEDTLS_PUT_UINT16_BE( supported_sig_alg_len + 2, buf, 2 );
-    /* Write length of supported_signature_algorithms */
-    MBEDTLS_PUT_UINT16_BE( supported_sig_alg_len, buf, 4 );
-
-    /* Output the total length of signature algorithms extension. */
-    *out_len = p - buf;
-
-    ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SIG_ALG;
-    return( 0 );
-}
-
 /*
  * STATE HANDLING: Read CertificateVerify
  */
@@ -293,19 +209,6 @@
     *verify_buffer_len = idx;
 }
 
-static int ssl_tls13_sig_alg_is_offered( const mbedtls_ssl_context *ssl,
-                                         uint16_t sig_alg )
-{
-    const uint16_t *tls13_sig_alg = ssl->conf->tls13_sig_algs;
-
-    for( ; *tls13_sig_alg != MBEDTLS_TLS1_3_SIG_NONE ; tls13_sig_alg++ )
-    {
-        if( *tls13_sig_alg == sig_alg )
-            return( 1 );
-    }
-    return( 0 );
-}
-
 static int ssl_tls13_parse_certificate_verify( mbedtls_ssl_context *ssl,
                                                const unsigned char *buf,
                                                const unsigned char *end,
@@ -350,7 +253,7 @@
      *
      * Check if algorithm is an offered signature algorithm.
      */
-    if( ! ssl_tls13_sig_alg_is_offered( ssl, algorithm ) )
+    if( ! mbedtls_ssl_sig_alg_is_offered( ssl, algorithm ) )
     {
         /* algorithm not in offered signature algorithms list */
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "Received signature algorithm(%04x) is not "
@@ -1155,6 +1058,32 @@
  */
 #if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
 
+static int ssl_tls13_finalize_change_cipher_spec( mbedtls_ssl_context* ssl )
+{
+
+#if defined(MBEDTLS_SSL_CLI_C)
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+    {
+        switch( ssl->state )
+        {
+            case MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO:
+                mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_HELLO );
+                break;
+            case MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED:
+                mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_FINISHED );
+                break;
+            default:
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+                return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+    }
+#else
+    ((void) ssl);
+#endif /* MBEDTLS_SSL_CLI_C */
+
+    return( 0 );
+}
+
 static int ssl_tls13_write_change_cipher_spec_body( mbedtls_ssl_context *ssl,
                                                     unsigned char *buf,
                                                     unsigned char *end,
@@ -1185,6 +1114,9 @@
 
     ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
 
+    /* Update state */
+    MBEDTLS_SSL_PROC_CHK( ssl_tls13_finalize_change_cipher_spec( ssl ) );
+
     /* Dispatch message */
     MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_write_record( ssl, 1 ) );
 
@@ -1196,6 +1128,80 @@
 
 #endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
 
+/* Reset SSL context and update hash for handling HRR.
+ *
+ * Replace Transcript-Hash(X) by
+ * Transcript-Hash( message_hash     ||
+ *                 00 00 Hash.length ||
+ *                 X )
+ * A few states of the handshake are preserved, including:
+ *   - session ID
+ *   - session ticket
+ *   - negotiated ciphersuite
+ */
+int mbedtls_ssl_reset_transcript_for_hrr( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    unsigned char hash_transcript[ MBEDTLS_MD_MAX_SIZE + 4 ];
+    size_t hash_len;
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+    uint16_t cipher_suite = ssl->session_negotiate->ciphersuite;
+    ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( cipher_suite );
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "Reset SSL session for HRR" ) );
+
+    ret = mbedtls_ssl_get_handshake_transcript( ssl, ciphersuite_info->mac,
+                                                hash_transcript + 4,
+                                                MBEDTLS_MD_MAX_SIZE,
+                                                &hash_len );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 4, "mbedtls_ssl_get_handshake_transcript", ret );
+        return( ret );
+    }
+
+    hash_transcript[0] = MBEDTLS_SSL_HS_MESSAGE_HASH;
+    hash_transcript[1] = 0;
+    hash_transcript[2] = 0;
+    hash_transcript[3] = (unsigned char) hash_len;
+
+    hash_len += 4;
+
+    if( ciphersuite_info->mac == MBEDTLS_MD_SHA256 )
+    {
+#if defined(MBEDTLS_SHA256_C)
+        MBEDTLS_SSL_DEBUG_BUF( 4, "Truncated SHA-256 handshake transcript",
+                               hash_transcript, hash_len );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+        psa_hash_abort( &ssl->handshake->fin_sha256_psa );
+        psa_hash_setup( &ssl->handshake->fin_sha256_psa, PSA_ALG_SHA_256 );
+#else
+        mbedtls_sha256_starts( &ssl->handshake->fin_sha256, 0 );
+#endif
+#endif /* MBEDTLS_SHA256_C */
+    }
+    else if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
+    {
+#if defined(MBEDTLS_SHA384_C)
+        MBEDTLS_SSL_DEBUG_BUF( 4, "Truncated SHA-384 handshake transcript",
+                               hash_transcript, hash_len );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+        psa_hash_abort( &ssl->handshake->fin_sha384_psa );
+        psa_hash_setup( &ssl->handshake->fin_sha384_psa, PSA_ALG_SHA_384 );
+#else
+        mbedtls_sha512_starts( &ssl->handshake->fin_sha512, 1 );
+#endif
+#endif /* MBEDTLS_SHA384_C */
+    }
+
+#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA384_C)
+    ssl->handshake->update_checksum( ssl, hash_transcript, hash_len );
+#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA384_C */
+    return( ret );
+}
+
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
 
 #endif /* MBEDTLS_SSL_TLS_C */
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 57f7d8f..1de8ce3 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -692,7 +692,7 @@
     const char *pers = "ssl_client2";
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-    psa_key_id_t slot = 0;
+    mbedtls_svc_key_id_t slot = MBEDTLS_SVC_KEY_ID_INIT;
     psa_algorithm_t alg = 0;
     psa_key_attributes_t key_attributes;
     psa_status_t status;
@@ -716,7 +716,7 @@
     mbedtls_x509_crt clicert;
     mbedtls_pk_context pkey;
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-    psa_key_id_t key_slot = 0; /* invalid key slot */
+    mbedtls_svc_key_id_t key_slot = MBEDTLS_SVC_KEY_ID_INIT; /* invalid key slot */
 #endif
 #endif  /* MBEDTLS_X509_CRT_PARSE_C */
     char *p, *q;
@@ -1729,7 +1729,7 @@
     {
         crt_profile_for_test.allowed_mds |= MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 );
         mbedtls_ssl_conf_cert_profile( &conf, &crt_profile_for_test );
-        mbedtls_ssl_conf_sig_hashes( &conf, ssl_sig_hashes_for_test );
+        mbedtls_ssl_conf_sig_algs( &conf, ssl_sig_algs_for_test );
     }
 
     if( opt.context_crt_cb == 0 )
@@ -2144,9 +2144,19 @@
         }
     }
 
-    mbedtls_printf( " ok\n    [ Protocol is %s ]\n    [ Ciphersuite is %s ]\n",
-                    mbedtls_ssl_get_version( &ssl ),
-                    mbedtls_ssl_get_ciphersuite( &ssl ) );
+    {
+        int suite_id = mbedtls_ssl_get_ciphersuite_id_from_ssl( &ssl );
+        const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+        ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( suite_id );
+
+        mbedtls_printf( " ok\n    [ Protocol is %s ]\n"
+                             "    [ Ciphersuite is %s ]\n"
+                             "    [ Key size is %u ]\n",
+          mbedtls_ssl_get_version( &ssl ),
+          mbedtls_ssl_ciphersuite_get_name( ciphersuite_info ),
+          (unsigned int)
+            mbedtls_ssl_ciphersuite_get_cipher_key_bitlen( ciphersuite_info ) );
+    }
 
     if( ( ret = mbedtls_ssl_get_record_expansion( &ssl ) ) >= 0 )
         mbedtls_printf( "    [ Record expansion is %d ]\n", ret );
@@ -3061,7 +3071,8 @@
             ( opt.query_config_mode == DFL_QUERY_CONFIG_MODE ) )
         {
             mbedtls_printf( "Failed to destroy key slot %u - error was %d",
-                            (unsigned) slot, (int) status );
+                            (unsigned) MBEDTLS_SVC_KEY_ID_GET_KEY_ID( slot ),
+                            (int) status );
             if( ret == 0 )
                 ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
         }
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 7cbdaf6..388ffe0 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -120,6 +120,7 @@
 #define DFL_TRUNC_HMAC          -1
 #define DFL_TICKETS             MBEDTLS_SSL_SESSION_TICKETS_ENABLED
 #define DFL_TICKET_TIMEOUT      86400
+#define DFL_TICKET_AEAD         MBEDTLS_CIPHER_AES_256_GCM
 #define DFL_CACHE_MAX           -1
 #define DFL_CACHE_TIMEOUT       -1
 #define DFL_SNI                 NULL
@@ -285,7 +286,8 @@
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
 #define USAGE_TICKETS                                       \
     "    tickets=%%d          default: 1 (enabled)\n"       \
-    "    ticket_timeout=%%d   default: 86400 (one day)\n"
+    "    ticket_timeout=%%d   default: 86400 (one day)\n"   \
+    "    ticket_aead=%%s      default: \"AES-256-GCM\"\n"
 #else
 #define USAGE_TICKETS ""
 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
@@ -612,6 +614,7 @@
     int trunc_hmac;             /* accept truncated hmac?                   */
     int tickets;                /* enable / disable session tickets         */
     int ticket_timeout;         /* session ticket lifetime                  */
+    int ticket_aead;            /* session ticket protection                */
     int cache_max;              /* max number of session cache entries      */
     int cache_timeout;          /* expiration delay of session cache entries */
     char *sni;                  /* string describing sni information        */
@@ -849,7 +852,7 @@
     size_t key_len;
     unsigned char key[MBEDTLS_PSK_MAX_LEN];
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-    psa_key_id_t slot;
+    mbedtls_svc_key_id_t slot;
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
     psk_entry *next;
 };
@@ -865,9 +868,9 @@
     {
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
         psa_status_t status;
-        psa_key_id_t const slot = head->slot;
+        mbedtls_svc_key_id_t const slot = head->slot;
 
-        if( slot != 0 )
+        if( MBEDTLS_SVC_KEY_ID_GET_KEY_ID( slot ) != 0 )
         {
             status = psa_destroy_key( slot );
             if( status != PSA_SUCCESS )
@@ -940,7 +943,7 @@
             memcmp( name, cur->name, name_len ) == 0 )
         {
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-            if( cur->slot != 0 )
+            if( MBEDTLS_SVC_KEY_ID_GET_KEY_ID( cur->slot ) != 0 )
                 return( mbedtls_ssl_set_hs_psk_opaque( ssl, cur->slot ) );
             else
 #endif
@@ -1208,7 +1211,7 @@
 #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-static psa_status_t psa_setup_psk_key_slot( psa_key_id_t *slot,
+static psa_status_t psa_setup_psk_key_slot( mbedtls_svc_key_id_t *slot,
                                             psa_algorithm_t alg,
                                             unsigned char *psk,
                                             size_t psk_len )
@@ -1291,7 +1294,7 @@
 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_algorithm_t alg = 0;
-    psa_key_id_t psk_slot = 0;
+    mbedtls_svc_key_id_t psk_slot = MBEDTLS_SVC_KEY_ID_INIT;
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
     unsigned char psk[MBEDTLS_PSK_MAX_LEN];
     size_t psk_len = 0;
@@ -1323,8 +1326,8 @@
     mbedtls_x509_crt srvcert2;
     mbedtls_pk_context pkey2;
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-    psa_key_id_t key_slot = 0; /* invalid key slot */
-    psa_key_id_t key_slot2 = 0; /* invalid key slot */
+    mbedtls_svc_key_id_t key_slot = MBEDTLS_SVC_KEY_ID_INIT; /* invalid key slot */
+    mbedtls_svc_key_id_t key_slot2 = MBEDTLS_SVC_KEY_ID_INIT; /* invalid key slot */
 #endif
     int key_cert_init = 0, key_cert_init2 = 0;
 #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
@@ -1538,6 +1541,7 @@
     opt.trunc_hmac          = DFL_TRUNC_HMAC;
     opt.tickets             = DFL_TICKETS;
     opt.ticket_timeout      = DFL_TICKET_TIMEOUT;
+    opt.ticket_aead         = DFL_TICKET_AEAD;
     opt.cache_max           = DFL_CACHE_MAX;
     opt.cache_timeout       = DFL_CACHE_TIMEOUT;
     opt.sni                 = DFL_SNI;
@@ -1915,6 +1919,14 @@
             if( opt.ticket_timeout < 0 )
                 goto usage;
         }
+        else if( strcmp( p, "ticket_aead" ) == 0 )
+        {
+            const mbedtls_cipher_info_t *ci = mbedtls_cipher_info_from_string( q );
+
+            if( ci == NULL )
+                goto usage;
+            opt.ticket_aead = mbedtls_cipher_info_get_type( ci );
+        }
         else if( strcmp( p, "cache_max" ) == 0 )
         {
             opt.cache_max = atoi( q );
@@ -2574,7 +2586,7 @@
     {
         crt_profile_for_test.allowed_mds |= MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 );
         mbedtls_ssl_conf_cert_profile( &conf, &crt_profile_for_test );
-        mbedtls_ssl_conf_sig_hashes( &conf, ssl_sig_hashes_for_test );
+        mbedtls_ssl_conf_sig_algs( &conf, ssl_sig_algs_for_test );
     }
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
@@ -2708,7 +2720,7 @@
     {
         if( ( ret = mbedtls_ssl_ticket_setup( &ticket_ctx,
                         rng_get, &rng,
-                        MBEDTLS_CIPHER_AES_256_GCM,
+                        opt.ticket_aead,
                         opt.ticket_timeout ) ) != 0 )
         {
             mbedtls_printf( " failed\n  ! mbedtls_ssl_ticket_setup returned %d\n\n", ret );
@@ -3231,8 +3243,17 @@
     }
     else /* ret == 0 */
     {
-        mbedtls_printf( " ok\n    [ Protocol is %s ]\n    [ Ciphersuite is %s ]\n",
-                mbedtls_ssl_get_version( &ssl ), mbedtls_ssl_get_ciphersuite( &ssl ) );
+        int suite_id = mbedtls_ssl_get_ciphersuite_id_from_ssl( &ssl );
+        const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+        ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( suite_id );
+
+        mbedtls_printf( " ok\n    [ Protocol is %s ]\n"
+                             "    [ Ciphersuite is %s ]\n"
+                             "    [ Key size is %u ]\n",
+          mbedtls_ssl_get_version( &ssl ),
+          mbedtls_ssl_ciphersuite_get_name( ciphersuite_info ),
+          (unsigned int)
+            mbedtls_ssl_ciphersuite_get_cipher_key_bitlen( ciphersuite_info ) );
     }
 
     if( ( ret = mbedtls_ssl_get_record_expansion( &ssl ) ) >= 0 )
@@ -4018,7 +4039,8 @@
             ( opt.query_config_mode == DFL_QUERY_CONFIG_MODE ) )
         {
             mbedtls_printf( "Failed to destroy key slot %u - error was %d",
-                            (unsigned) psk_slot, (int) status );
+                            (unsigned) MBEDTLS_SVC_KEY_ID_GET_KEY_ID( psk_slot ),
+                            (int) status );
         }
     }
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED &&
diff --git a/programs/ssl/ssl_test_common_source.c b/programs/ssl/ssl_test_common_source.c
index 62cd35d..0e66895 100644
--- a/programs/ssl/ssl_test_common_source.c
+++ b/programs/ssl/ssl_test_common_source.c
@@ -262,24 +262,34 @@
 }
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
-int ssl_sig_hashes_for_test[] = {
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_RSA_C)
+#define MBEDTLS_SSL_SIG_ALG( hash ) (( hash << 8 ) | MBEDTLS_SSL_SIG_ECDSA), \
+                                    (( hash << 8 ) | MBEDTLS_SSL_SIG_RSA),
+#elif defined(MBEDTLS_ECDSA_C)
+#define MBEDTLS_SSL_SIG_ALG( hash ) (( hash << 8 ) | MBEDTLS_SSL_SIG_ECDSA),
+#elif defined(MBEDTLS_RSA_C)
+#define MBEDTLS_SSL_SIG_ALG( hash ) (( hash << 8 ) | MBEDTLS_SSL_SIG_RSA),
+#else
+#define MBEDTLS_SSL_SIG_ALG( hash )
+#endif
+uint16_t ssl_sig_algs_for_test[] = {
 #if defined(MBEDTLS_SHA512_C)
-    MBEDTLS_MD_SHA512,
+    MBEDTLS_SSL_SIG_ALG( MBEDTLS_SSL_HASH_SHA512 )
 #endif
 #if defined(MBEDTLS_SHA384_C)
-    MBEDTLS_MD_SHA384,
+    MBEDTLS_SSL_SIG_ALG( MBEDTLS_SSL_HASH_SHA384 )
 #endif
 #if defined(MBEDTLS_SHA256_C)
-    MBEDTLS_MD_SHA256,
+    MBEDTLS_SSL_SIG_ALG( MBEDTLS_SSL_HASH_SHA256 )
 #endif
 #if defined(MBEDTLS_SHA224_C)
-    MBEDTLS_MD_SHA224,
+    MBEDTLS_SSL_SIG_ALG( MBEDTLS_SSL_HASH_SHA224 )
 #endif
 #if defined(MBEDTLS_SHA1_C)
     /* Allow SHA-1 as we use it extensively in tests. */
-    MBEDTLS_MD_SHA1,
+    MBEDTLS_SSL_SIG_ALG( MBEDTLS_SSL_HASH_SHA1 )
 #endif
-    MBEDTLS_MD_NONE
+    MBEDTLS_TLS1_3_SIG_NONE
 };
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
diff --git a/programs/ssl/ssl_test_lib.h b/programs/ssl/ssl_test_lib.h
index 6b9e7b8..ff02492 100644
--- a/programs/ssl/ssl_test_lib.h
+++ b/programs/ssl/ssl_test_lib.h
@@ -52,14 +52,12 @@
 #endif
 
 #if !defined(MBEDTLS_NET_C) ||                              \
-    !defined(MBEDTLS_SSL_TLS_C) ||                          \
-    defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
-#define MBEDTLS_SSL_TEST_IMPOSSIBLE                             \
-    "MBEDTLS_NET_C and/or "                                     \
-    "MBEDTLS_SSL_TLS_C not defined, "                           \
-    "and/or MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined.\n"
+    !defined(MBEDTLS_SSL_TLS_C)
+#define MBEDTLS_SSL_TEST_IMPOSSIBLE                         \
+    "MBEDTLS_NET_C and/or "                                 \
+    "MBEDTLS_SSL_TLS_C not defined."
 #elif !defined(HAVE_RNG)
-#define MBEDTLS_SSL_TEST_IMPOSSIBLE             \
+#define MBEDTLS_SSL_TEST_IMPOSSIBLE                         \
     "No random generator is available.\n"
 #else
 #undef MBEDTLS_SSL_TEST_IMPOSSIBLE
@@ -72,6 +70,7 @@
 
 #include "mbedtls/net_sockets.h"
 #include "mbedtls/ssl.h"
+#include "mbedtls/ssl_ciphersuites.h"
 #include "mbedtls/entropy.h"
 #include "mbedtls/ctr_drbg.h"
 #include "mbedtls/hmac_drbg.h"
diff --git a/library/psa_crypto_driver_wrappers.c b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja
similarity index 98%
rename from library/psa_crypto_driver_wrappers.c
rename to scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja
index 8d86478..4db30f5 100644
--- a/library/psa_crypto_driver_wrappers.c
+++ b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja
@@ -1615,6 +1615,22 @@
     }
 }
 
+psa_status_t psa_driver_get_tag_len( psa_aead_operation_t *operation,
+                                     uint8_t *tag_len )
+{
+    if( operation == NULL || tag_len == NULL )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+    *tag_len = operation->ctx.transparent_test_driver_ctx.tag_length;
+    return ( PSA_SUCCESS );
+#endif
+#endif
+    *tag_len = operation->ctx.mbedtls_ctx.tag_length;
+    return ( PSA_SUCCESS );
+}
+
 psa_status_t psa_driver_wrapper_aead_encrypt_setup(
    psa_aead_operation_t *operation,
    const psa_key_attributes_t *attributes,
diff --git a/scripts/generate_driver_wrappers.py b/scripts/generate_driver_wrappers.py
new file mode 100755
index 0000000..42331ac
--- /dev/null
+++ b/scripts/generate_driver_wrappers.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python3
+"""Generate library/psa_crypto_driver_wrappers.c
+
+   This module is invoked by the build sripts to auto generate the
+   psa_crypto_driver_wrappers.c based on template files in
+   script/data_files/driver_templates/.
+"""
+# 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.
+
+import sys
+import os
+import argparse
+import jinja2
+from mbedtls_dev import build_tree
+
+def render(template_path: str) -> str:
+    """
+    Render template from the input file.
+    """
+    environment = jinja2.Environment(
+        loader=jinja2.FileSystemLoader(os.path.dirname(template_path)),
+        keep_trailing_newline=True)
+    template = environment.get_template(os.path.basename(template_path))
+
+    return template.render()
+
+def generate_driver_wrapper_file(mbedtls_root: str, output_dir: str) -> None:
+    """
+    Generate the file psa_crypto_driver_wrapper.c.
+    """
+    driver_wrapper_template_filename = \
+        os.path.join(mbedtls_root, \
+        "scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja")
+
+    result = render(driver_wrapper_template_filename)
+
+    with open(os.path.join(output_dir, "psa_crypto_driver_wrappers.c"), 'w') as out_file:
+        out_file.write(result)
+
+def main() -> int:
+    """
+    Main with command line arguments.
+    """
+    def_arg_mbedtls_root = build_tree.guess_mbedtls_root()
+    def_arg_output_dir = os.path.join(def_arg_mbedtls_root, 'library')
+
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--mbedtls-root', nargs='?', default=def_arg_mbedtls_root,
+                        help='root directory of mbedtls source code')
+    parser.add_argument('output_directory', nargs='?',
+                        default=def_arg_output_dir, help='output file\'s location')
+    args = parser.parse_args()
+
+    mbedtls_root = os.path.abspath(args.mbedtls_root)
+    output_directory = args.output_directory
+
+    generate_driver_wrapper_file(mbedtls_root, output_directory)
+
+    return 0
+
+if __name__ == '__main__':
+    sys.exit(main())
diff --git a/scripts/make_generated_files.bat b/scripts/make_generated_files.bat
index d3a8b36..662da98 100644
--- a/scripts/make_generated_files.bat
+++ b/scripts/make_generated_files.bat
@@ -1,6 +1,9 @@
 @rem Generate automatically-generated configuration-independent source files

 @rem and build scripts.

 @rem Perl and Python 3 must be on the PATH.

+@rem psa_crypto_driver_wrappers.c needs to be generated prior to

+@rem generate_visualc_files.pl being invoked.

+python scripts\generate_driver_wrappers.py || exit /b 1

 perl scripts\generate_errors.pl || exit /b 1

 perl scripts\generate_query_config.pl || exit /b 1

 perl scripts\generate_features.pl || exit /b 1

diff --git a/tests/docker/bionic/Dockerfile b/tests/docker/bionic/Dockerfile
index 50f5a7f..28d33b7 100644
--- a/tests/docker/bionic/Dockerfile
+++ b/tests/docker/bionic/Dockerfile
@@ -60,6 +60,10 @@
     pkg-config \
     && rm -rf /var/lib/apt/lists/*
 
+# Jinja2 is required for driver dispatch code generation.
+RUN python3 -m pip install \
+    jinja2==2.10.1 types-jinja2
+
 # Build a static, legacy openssl from sources with sslv3 enabled
 # Based on https://gist.github.com/bmaupin/8caca3a1e8c3c5686141 (build-openssl.sh)
 # Note: openssl-1.0.2 and earlier has known build issues with parallel make.
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 6e17a91..1e0ff7a 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -940,9 +940,8 @@
 }
 
 component_test_psa_crypto_key_id_encodes_owner () {
-    msg "build: full config - USE_PSA_CRYPTO + PSA_CRYPTO_KEY_ID_ENCODES_OWNER, cmake, gcc, ASan"
+    msg "build: full config + PSA_CRYPTO_KEY_ID_ENCODES_OWNER, cmake, gcc, ASan"
     scripts/config.py full
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
     scripts/config.py set MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
     CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
     make
@@ -960,9 +959,8 @@
 }
 
 component_build_psa_crypto_spm () {
-    msg "build: full config - USE_PSA_CRYPTO + PSA_CRYPTO_KEY_ID_ENCODES_OWNER + PSA_CRYPTO_SPM, make, gcc"
+    msg "build: full config + PSA_CRYPTO_KEY_ID_ENCODES_OWNER + PSA_CRYPTO_SPM, make, gcc"
     scripts/config.py full
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
     scripts/config.py unset MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS
     scripts/config.py set MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
     scripts/config.py set MBEDTLS_PSA_CRYPTO_SPM
diff --git a/tests/scripts/check-generated-files.sh b/tests/scripts/check-generated-files.sh
index 994fd24..f42ecd6 100755
--- a/tests/scripts/check-generated-files.sh
+++ b/tests/scripts/check-generated-files.sh
@@ -117,6 +117,7 @@
 
 check scripts/generate_errors.pl library/error.c
 check scripts/generate_query_config.pl programs/test/query_config.c
+check scripts/generate_driver_wrappers.py library/psa_crypto_driver_wrappers.c
 check scripts/generate_features.pl library/version_features.c
 check scripts/generate_ssl_debug_helpers.py library/ssl_debug_helpers_generated.c
 # generate_visualc_files enumerates source files (library/*.c). It doesn't
diff --git a/tests/scripts/test_psa_compliance.py b/tests/scripts/test_psa_compliance.py
index ea52c93..da5229b 100755
--- a/tests/scripts/test_psa_compliance.py
+++ b/tests/scripts/test_psa_compliance.py
@@ -33,10 +33,6 @@
 # Test number 2xx corresponds to the files in the folder
 # psa-arch-tests/api-tests/dev_apis/crypto/test_c0xx
 EXPECTED_FAILURES = {
-    # Multipart CCM is not supported.
-    # - Tracked in issue #3721
-    252, 253, 254, 255, 256, 257, 258, 259, 261,
-
     # psa_hash_suspend() and psa_hash_resume() are not supported.
     # - Tracked in issue #3274
     262, 263
@@ -51,7 +47,7 @@
 #
 # Web URL: https://github.com/bensze01/psa-arch-tests/tree/fixes-for-mbedtls-3
 PSA_ARCH_TESTS_REPO = 'https://github.com/bensze01/psa-arch-tests.git'
-PSA_ARCH_TESTS_REF = 'fixes-for-mbedtls-3'
+PSA_ARCH_TESTS_REF = 'fix-pr-5272'
 
 #pylint: disable=too-many-branches,too-many-statements
 def main():
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 691c0e7..295b82e 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -1475,6 +1475,20 @@
             0 \
             -s "Verifying peer X.509 certificate... ok"
 
+run_test    "key size: TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256" \
+            "$P_SRV" \
+            "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256" \
+            0 \
+            -c "Ciphersuite is TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256" \
+            -c "Key size is 256"
+
+run_test    "key size: TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8" \
+            "$P_SRV" \
+            "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8" \
+            0 \
+            -c "Ciphersuite is TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8" \
+            -c "Key size is 128"
+
 requires_config_enabled MBEDTLS_X509_CRT_PARSE_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SHA256_C
@@ -2764,6 +2778,202 @@
             -s "session successfully restored from ticket" \
             -s "a session has been resumed"
 
+run_test    "Session resume using tickets: AES-128-GCM" \
+            "$P_SRV debug_level=3 tickets=1 ticket_aead=AES-128-GCM" \
+            "$P_CLI debug_level=3 tickets=1 reconnect=1" \
+            0 \
+            -c "client hello, adding session ticket extension" \
+            -s "found session ticket extension" \
+            -s "server hello, adding session ticket extension" \
+            -c "found session_ticket extension" \
+            -c "parse new session ticket" \
+            -S "session successfully restored from cache" \
+            -s "session successfully restored from ticket" \
+            -s "a session has been resumed" \
+            -c "a session has been resumed"
+
+run_test    "Session resume using tickets: AES-192-GCM" \
+            "$P_SRV debug_level=3 tickets=1 ticket_aead=AES-192-GCM" \
+            "$P_CLI debug_level=3 tickets=1 reconnect=1" \
+            0 \
+            -c "client hello, adding session ticket extension" \
+            -s "found session ticket extension" \
+            -s "server hello, adding session ticket extension" \
+            -c "found session_ticket extension" \
+            -c "parse new session ticket" \
+            -S "session successfully restored from cache" \
+            -s "session successfully restored from ticket" \
+            -s "a session has been resumed" \
+            -c "a session has been resumed"
+
+run_test    "Session resume using tickets: AES-128-CCM" \
+            "$P_SRV debug_level=3 tickets=1 ticket_aead=AES-128-CCM" \
+            "$P_CLI debug_level=3 tickets=1 reconnect=1" \
+            0 \
+            -c "client hello, adding session ticket extension" \
+            -s "found session ticket extension" \
+            -s "server hello, adding session ticket extension" \
+            -c "found session_ticket extension" \
+            -c "parse new session ticket" \
+            -S "session successfully restored from cache" \
+            -s "session successfully restored from ticket" \
+            -s "a session has been resumed" \
+            -c "a session has been resumed"
+
+run_test    "Session resume using tickets: AES-192-CCM" \
+            "$P_SRV debug_level=3 tickets=1 ticket_aead=AES-192-CCM" \
+            "$P_CLI debug_level=3 tickets=1 reconnect=1" \
+            0 \
+            -c "client hello, adding session ticket extension" \
+            -s "found session ticket extension" \
+            -s "server hello, adding session ticket extension" \
+            -c "found session_ticket extension" \
+            -c "parse new session ticket" \
+            -S "session successfully restored from cache" \
+            -s "session successfully restored from ticket" \
+            -s "a session has been resumed" \
+            -c "a session has been resumed"
+
+run_test    "Session resume using tickets: AES-256-CCM" \
+            "$P_SRV debug_level=3 tickets=1 ticket_aead=AES-256-CCM" \
+            "$P_CLI debug_level=3 tickets=1 reconnect=1" \
+            0 \
+            -c "client hello, adding session ticket extension" \
+            -s "found session ticket extension" \
+            -s "server hello, adding session ticket extension" \
+            -c "found session_ticket extension" \
+            -c "parse new session ticket" \
+            -S "session successfully restored from cache" \
+            -s "session successfully restored from ticket" \
+            -s "a session has been resumed" \
+            -c "a session has been resumed"
+
+run_test    "Session resume using tickets: CAMELLIA-128-CCM" \
+            "$P_SRV debug_level=3 tickets=1 ticket_aead=CAMELLIA-128-CCM" \
+            "$P_CLI debug_level=3 tickets=1 reconnect=1" \
+            0 \
+            -c "client hello, adding session ticket extension" \
+            -s "found session ticket extension" \
+            -s "server hello, adding session ticket extension" \
+            -c "found session_ticket extension" \
+            -c "parse new session ticket" \
+            -S "session successfully restored from cache" \
+            -s "session successfully restored from ticket" \
+            -s "a session has been resumed" \
+            -c "a session has been resumed"
+
+run_test    "Session resume using tickets: CAMELLIA-192-CCM" \
+            "$P_SRV debug_level=3 tickets=1 ticket_aead=CAMELLIA-192-CCM" \
+            "$P_CLI debug_level=3 tickets=1 reconnect=1" \
+            0 \
+            -c "client hello, adding session ticket extension" \
+            -s "found session ticket extension" \
+            -s "server hello, adding session ticket extension" \
+            -c "found session_ticket extension" \
+            -c "parse new session ticket" \
+            -S "session successfully restored from cache" \
+            -s "session successfully restored from ticket" \
+            -s "a session has been resumed" \
+            -c "a session has been resumed"
+
+run_test    "Session resume using tickets: CAMELLIA-256-CCM" \
+            "$P_SRV debug_level=3 tickets=1 ticket_aead=CAMELLIA-256-CCM" \
+            "$P_CLI debug_level=3 tickets=1 reconnect=1" \
+            0 \
+            -c "client hello, adding session ticket extension" \
+            -s "found session ticket extension" \
+            -s "server hello, adding session ticket extension" \
+            -c "found session_ticket extension" \
+            -c "parse new session ticket" \
+            -S "session successfully restored from cache" \
+            -s "session successfully restored from ticket" \
+            -s "a session has been resumed" \
+            -c "a session has been resumed"
+
+run_test    "Session resume using tickets: ARIA-128-GCM" \
+            "$P_SRV debug_level=3 tickets=1 ticket_aead=ARIA-128-GCM" \
+            "$P_CLI debug_level=3 tickets=1 reconnect=1" \
+            0 \
+            -c "client hello, adding session ticket extension" \
+            -s "found session ticket extension" \
+            -s "server hello, adding session ticket extension" \
+            -c "found session_ticket extension" \
+            -c "parse new session ticket" \
+            -S "session successfully restored from cache" \
+            -s "session successfully restored from ticket" \
+            -s "a session has been resumed" \
+            -c "a session has been resumed"
+
+run_test    "Session resume using tickets: ARIA-192-GCM" \
+            "$P_SRV debug_level=3 tickets=1 ticket_aead=ARIA-192-GCM" \
+            "$P_CLI debug_level=3 tickets=1 reconnect=1" \
+            0 \
+            -c "client hello, adding session ticket extension" \
+            -s "found session ticket extension" \
+            -s "server hello, adding session ticket extension" \
+            -c "found session_ticket extension" \
+            -c "parse new session ticket" \
+            -S "session successfully restored from cache" \
+            -s "session successfully restored from ticket" \
+            -s "a session has been resumed" \
+            -c "a session has been resumed"
+
+run_test    "Session resume using tickets: ARIA-256-GCM" \
+            "$P_SRV debug_level=3 tickets=1 ticket_aead=ARIA-256-GCM" \
+            "$P_CLI debug_level=3 tickets=1 reconnect=1" \
+            0 \
+            -c "client hello, adding session ticket extension" \
+            -s "found session ticket extension" \
+            -s "server hello, adding session ticket extension" \
+            -c "found session_ticket extension" \
+            -c "parse new session ticket" \
+            -S "session successfully restored from cache" \
+            -s "session successfully restored from ticket" \
+            -s "a session has been resumed" \
+            -c "a session has been resumed"
+
+run_test    "Session resume using tickets: ARIA-128-CCM" \
+            "$P_SRV debug_level=3 tickets=1 ticket_aead=ARIA-128-CCM" \
+            "$P_CLI debug_level=3 tickets=1 reconnect=1" \
+            0 \
+            -c "client hello, adding session ticket extension" \
+            -s "found session ticket extension" \
+            -s "server hello, adding session ticket extension" \
+            -c "found session_ticket extension" \
+            -c "parse new session ticket" \
+            -S "session successfully restored from cache" \
+            -s "session successfully restored from ticket" \
+            -s "a session has been resumed" \
+            -c "a session has been resumed"
+
+run_test    "Session resume using tickets: ARIA-192-CCM" \
+            "$P_SRV debug_level=3 tickets=1 ticket_aead=ARIA-192-CCM" \
+            "$P_CLI debug_level=3 tickets=1 reconnect=1" \
+            0 \
+            -c "client hello, adding session ticket extension" \
+            -s "found session ticket extension" \
+            -s "server hello, adding session ticket extension" \
+            -c "found session_ticket extension" \
+            -c "parse new session ticket" \
+            -S "session successfully restored from cache" \
+            -s "session successfully restored from ticket" \
+            -s "a session has been resumed" \
+            -c "a session has been resumed"
+
+run_test    "Session resume using tickets: ARIA-256-CCM" \
+            "$P_SRV debug_level=3 tickets=1 ticket_aead=ARIA-256-CCM" \
+            "$P_CLI debug_level=3 tickets=1 reconnect=1" \
+            0 \
+            -c "client hello, adding session ticket extension" \
+            -s "found session ticket extension" \
+            -s "server hello, adding session ticket extension" \
+            -c "found session_ticket extension" \
+            -c "parse new session ticket" \
+            -S "session successfully restored from cache" \
+            -s "session successfully restored from ticket" \
+            -s "a session has been resumed" \
+            -c "a session has been resumed"
+
 # Tests for Session Tickets with DTLS
 
 run_test    "Session resume using tickets, DTLS: basic" \
@@ -4090,6 +4300,21 @@
 # detect that its write end of the connection is closed and abort
 # before reading the alert message.
 
+run_test    "Authentication: client cert self-signed and trusted, server required" \
+            "$P_SRV debug_level=3 auth_mode=required ca_file=data_files/server5-selfsigned.crt" \
+            "$P_CLI debug_level=3 crt_file=data_files/server5-selfsigned.crt \
+             key_file=data_files/server5.key" \
+            0 \
+            -S "skip write certificate request" \
+            -C "skip parse certificate request" \
+            -c "got a certificate request" \
+            -C "skip write certificate" \
+            -C "skip write certificate verify" \
+            -S "skip parse certificate verify" \
+            -S "x509_verify_cert() returned" \
+            -S "! The certificate is not correctly signed" \
+            -S "X509 - Certificate verification failed"
+
 run_test    "Authentication: client cert not trusted, server required" \
             "$P_SRV debug_level=3 auth_mode=required" \
             "$P_CLI debug_level=3 crt_file=data_files/server5-selfsigned.crt \
@@ -6585,7 +6810,7 @@
             "$P_SRV debug_level=3" \
             "$P_CLI debug_level=3 force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA256" \
             0 \
-            -C "client hello, adding supported_elliptic_curves extension" \
+            -C "client hello, adding supported_groups extension" \
             -C "client hello, adding supported_point_formats extension" \
             -S "found supported elliptic curves extension" \
             -S "found supported point formats extension"
@@ -6609,7 +6834,7 @@
             "$P_SRV debug_level=3" \
             "$P_CLI debug_level=3 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256" \
             0 \
-            -c "client hello, adding supported_elliptic_curves extension" \
+            -c "client hello, adding supported_groups extension" \
             -c "client hello, adding supported_point_formats extension" \
             -s "found supported elliptic curves extension" \
             -s "found supported point formats extension"
@@ -8989,13 +9214,29 @@
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_openssl_tls1_3
-run_test    "TLS 1.3: HelloRetryRequest check - openssl" \
+run_test    "TLS 1.3: HelloRetryRequest check, ciphersuite TLS_AES_128_GCM_SHA256 - openssl" \
+            "$O_NEXT_SRV -ciphersuites TLS_AES_128_GCM_SHA256  -sigalgs ecdsa_secp256r1_sha256 -groups P-256 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
+            "$P_CLI debug_level=4 force_version=tls13" \
+            0 \
+            -c "received HelloRetryRequest message" \
+            -c "<= ssl_tls13_process_server_hello ( HelloRetryRequest )" \
+            -c "tls13 client state: MBEDTLS_SSL_CLIENT_HELLO" \
+            -c "HTTP/1.0 200 ok"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
+requires_openssl_tls1_3
+run_test    "TLS 1.3: HelloRetryRequest check, ciphersuite TLS_AES_256_GCM_SHA384 - openssl" \
             "$O_NEXT_SRV -ciphersuites TLS_AES_256_GCM_SHA384  -sigalgs ecdsa_secp256r1_sha256 -groups P-256 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
             "$P_CLI debug_level=4 force_version=tls13" \
-            1 \
+            0 \
             -c "received HelloRetryRequest message" \
-            -c "HRR not supported" \
-            -c "Last error was: -0x6E00 - SSL - The handshake negotiation failed"
+            -c "<= ssl_tls13_process_server_hello ( HelloRetryRequest )" \
+            -c "tls13 client state: MBEDTLS_SSL_CLIENT_HELLO" \
+            -c "HTTP/1.0 200 ok"
 
 requires_gnutls_tls1_3
 requires_gnutls_next_no_ticket
@@ -9004,14 +9245,30 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
-run_test    "TLS 1.3: HelloRetryRequest check - gnutls" \
-            "$G_NEXT_SRV -d 4 --priority=NONE:+GROUP-SECP256R1:+AES-256-GCM:+SHA384:+AEAD:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
+run_test    "TLS 1.3: HelloRetryRequest check, ciphersuite TLS_AES_128_GCM_SHA256 - gnutls" \
+            "$G_NEXT_SRV -d 4 --priority=NONE:+GROUP-SECP256R1:+AES-128-GCM:+SHA256:+AEAD:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS --disable-client-cert" \
             "$P_CLI debug_level=4 force_version=tls13" \
-            1 \
+            0 \
             -c "received HelloRetryRequest message" \
-            -c "HRR not supported" \
-            -c "Last error was: -0x6E00 - SSL - The handshake negotiation failed" \
-            -s "HELLO RETRY REQUEST was queued"
+            -c "<= ssl_tls13_process_server_hello ( HelloRetryRequest )" \
+            -c "tls13 client state: MBEDTLS_SSL_CLIENT_HELLO" \
+            -c "HTTP/1.0 200 OK"
+
+requires_gnutls_tls1_3
+requires_gnutls_next_no_ticket
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
+run_test    "TLS 1.3: HelloRetryRequest check, ciphersuite TLS_AES_256_GCM_SHA384 - gnutls" \
+            "$G_NEXT_SRV -d 4 --priority=NONE:+GROUP-SECP256R1:+AES-256-GCM:+SHA384:+AEAD:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS --disable-client-cert" \
+            "$P_CLI debug_level=4 force_version=tls13" \
+            0 \
+            -c "received HelloRetryRequest message" \
+            -c "<= ssl_tls13_process_server_hello ( HelloRetryRequest )" \
+            -c "tls13 client state: MBEDTLS_SSL_CLIENT_HELLO" \
+            -c "HTTP/1.0 200 OK"
 
 for i in $(ls opt-testcases/*.sh)
 do
diff --git a/tests/suites/test_suite_cipher.chacha20.data b/tests/suites/test_suite_cipher.chacha20.data
index 11de103..bcd0032 100644
--- a/tests/suites/test_suite_cipher.chacha20.data
+++ b/tests/suites/test_suite_cipher.chacha20.data
@@ -1,3 +1,7 @@
+Decrypt empty buffer
+depends_on:MBEDTLS_CHACHA20_C
+dec_empty_buf:MBEDTLS_CIPHER_CHACHA20:0:0
+
 Chacha20 RFC 7539 Test Vector #1
 depends_on:MBEDTLS_CHACHA20_C
 decrypt_test_vec:MBEDTLS_CIPHER_CHACHA20:-1:"0000000000000000000000000000000000000000000000000000000000000000":"000000000000000000000000":"76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":"":"":0:0
@@ -109,3 +113,23 @@
 ChaCha20 Encrypt and decrypt 32 bytes in multiple parts
 depends_on:MBEDTLS_CHACHA20_C
 enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:16:16:-1:16:16:16:16
+
+ChaCha20 IV Length 0
+depends_on:MBEDTLS_CHACHA20_C
+check_iv:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":0:MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
+
+ChaCha20 IV Length 11
+depends_on:MBEDTLS_CHACHA20_C
+check_iv:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":11:MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
+
+ChaCha20 IV Length 12
+depends_on:MBEDTLS_CHACHA20_C
+check_iv:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":12:0
+
+ChaCha20 IV Length 13
+depends_on:MBEDTLS_CHACHA20_C
+check_iv:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":13:MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
+
+ChaCha20 IV Length 16
+depends_on:MBEDTLS_CHACHA20_C
+check_iv:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":16:MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
diff --git a/tests/suites/test_suite_cipher.chachapoly.data b/tests/suites/test_suite_cipher.chachapoly.data
index 8c246ad..908951a 100644
--- a/tests/suites/test_suite_cipher.chachapoly.data
+++ b/tests/suites/test_suite_cipher.chachapoly.data
@@ -121,3 +121,23 @@
 Chacha20+Poly1305 RFC 7539 Test Vector #1 (streaming)
 depends_on:MBEDTLS_CHACHAPOLY_C
 decrypt_test_vec:MBEDTLS_CIPHER_CHACHA20_POLY1305:-1:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"f33388860000000000004e91":"eead9d67890cbb22392336fea1851f38":0:0
+
+ChaCha20+Poly1305 IV Length 0
+depends_on:MBEDTLS_CHACHAPOLY_C
+check_iv:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":0:MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
+
+ChaCha20+Poly1305 IV Length 11
+depends_on:MBEDTLS_CHACHAPOLY_C
+check_iv:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":11:MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
+
+ChaCha20+Poly1305 IV Length 12
+depends_on:MBEDTLS_CHACHAPOLY_C
+check_iv:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":12:0
+
+ChaCha20+Poly1305 IV Length 13
+depends_on:MBEDTLS_CHACHAPOLY_C
+check_iv:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":13:MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
+
+ChaCha20+Poly1305 IV Length 16
+depends_on:MBEDTLS_CHACHAPOLY_C
+check_iv:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":16:MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function
index fd2985b..cd79ba4 100644
--- a/tests/suites/test_suite_cipher.function
+++ b/tests/suites/test_suite_cipher.function
@@ -442,6 +442,9 @@
     if( NULL != strstr( cipher_info->name, "CCM*-NO-TAG") )
         iv_len = 13; /* For CCM, IV length is expected to be between 7 and 13 bytes.
                       * For CCM*-NO-TAG, IV length must be exactly 13 bytes long. */
+    else if( cipher_info->type == MBEDTLS_CIPHER_CHACHA20 ||
+             cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 )
+        iv_len = 12;
     else
         iv_len = sizeof(iv);
 
@@ -568,7 +571,9 @@
                     int expected_finish_ret )
 {
     unsigned char key[32];
-    unsigned char iv[16];
+
+    unsigned char *iv = NULL;
+    size_t iv_len = 16;
 
     mbedtls_cipher_context_t ctx_dec;
     const mbedtls_cipher_info_t *cipher_info;
@@ -579,7 +584,6 @@
     size_t outlen = 0;
 
     memset( key, 0, 32 );
-    memset( iv , 0, 16 );
 
     mbedtls_cipher_init( &ctx_dec );
 
@@ -589,6 +593,14 @@
     /* Initialise context */
     cipher_info = mbedtls_cipher_info_from_type( cipher );
     TEST_ASSERT( NULL != cipher_info);
+
+    if( cipher_info->type == MBEDTLS_CIPHER_CHACHA20 ||
+        cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 )
+        iv_len = 12;
+
+    ASSERT_ALLOC( iv, iv_len );
+    memset( iv , 0, iv_len );
+
     TEST_ASSERT( sizeof(key) * 8 >= cipher_info->key_bitlen );
 
     TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx_dec, cipher_info ) );
@@ -597,7 +609,7 @@
                                              key, cipher_info->key_bitlen,
                                              MBEDTLS_DECRYPT ) );
 
-    TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx_dec, iv, 16 ) );
+    TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx_dec, iv, iv_len ) );
 
     TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_dec ) );
 
@@ -627,6 +639,7 @@
     TEST_ASSERT( 0 == outlen );
 
 exit:
+    mbedtls_free( iv );
     mbedtls_cipher_free( &ctx_dec );
 }
 /* END_CASE */
@@ -689,6 +702,9 @@
     if( NULL != strstr( cipher_info->name, "CCM*-NO-TAG") )
         iv_len = 13; /* For CCM, IV length is expected to be between 7 and 13 bytes.
                       * For CCM*-NO-TAG, IV length must be exactly 13 bytes long. */
+    else if( cipher_info->type == MBEDTLS_CIPHER_CHACHA20 ||
+             cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 )
+        iv_len = 12;
     else
         iv_len = sizeof(iv);
 
@@ -1130,3 +1146,40 @@
         TEST_ASSERT( dlen == (size_t) dlen_check );
 }
 /* END_CASE */
+
+/* BEGIN_CASE */
+void check_iv( int cipher_id, char * cipher_string,
+               int iv_len_val, int ret )
+{
+    size_t iv_len = iv_len_val;
+    unsigned char iv[16];
+
+    const mbedtls_cipher_info_t *cipher_info;
+    mbedtls_cipher_context_t ctx_dec;
+    mbedtls_cipher_context_t ctx_enc;
+
+    /*
+     * Prepare contexts
+     */
+    mbedtls_cipher_init( &ctx_dec );
+    mbedtls_cipher_init( &ctx_enc );
+
+    /* Check and get info structures */
+    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 ) );
+    TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx_enc, cipher_info ) );
+
+    TEST_ASSERT( ret == mbedtls_cipher_set_iv( &ctx_dec, iv, iv_len ) );
+    TEST_ASSERT( ret == mbedtls_cipher_set_iv( &ctx_enc, iv, iv_len ) );
+
+exit:
+    mbedtls_cipher_free( &ctx_dec );
+    mbedtls_cipher_free( &ctx_enc );
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index c45f9f0..6bce6bb 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -842,7 +842,7 @@
 
 PSA key policy: AEAD, min-length policy used as algorithm
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(PSA_ALG_CCM, 8):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:8:PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(PSA_ALG_CCM, 8):PSA_ERROR_NOT_SUPPORTED
+aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(PSA_ALG_CCM, 8):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:8:PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(PSA_ALG_CCM, 8):PSA_ERROR_INVALID_ARGUMENT
 
 PSA key policy: AEAD, tag length > exact-length policy
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
@@ -2829,11 +2829,11 @@
 
 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
+aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CTR:"000102030405060708090A0B0C0D0E0F":"":"":PSA_ERROR_INVALID_ARGUMENT
 
 PSA AEAD encrypt/decrypt: invalid algorithm (ChaCha20)
 depends_on:MBEDTLS_CHACHA20_C
-aead_encrypt_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_STREAM_CIPHER:"":"":"":PSA_ERROR_NOT_SUPPORTED
+aead_encrypt_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_STREAM_CIPHER:"":"":"":PSA_ERROR_INVALID_ARGUMENT
 
 PSA Multipart AEAD encrypt: AES - CCM, 23 bytes (lengths set)
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
@@ -3341,75 +3341,107 @@
 
 PSA Multipart AEAD verify: AES - CCM, invalid signature
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26d56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6d80e8bf80f4a46cab06d4313f0db9be9":"7c0a61c9f825a48671ea05910748c8ef":1:PSA_ERROR_INVALID_SIGNATURE
+aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26d56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6d80e8bf80f4a46cab06d4313f0db9be9":"7c0a61c9f825a48671ea05910748c8ef":1:PSA_SUCCESS:PSA_ERROR_INVALID_SIGNATURE
 
 PSA Multipart AEAD verify: AES - CCM, invalid signature, T = 4
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,4):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6643b4f38":"0748c8ef":1:PSA_ERROR_INVALID_SIGNATURE
+aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,4):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6643b4f38":"0748c8ef":1:PSA_SUCCESS:PSA_ERROR_INVALID_SIGNATURE
 
 PSA Multipart AEAD verify: AES - CCM, T = 4, tag is truncated tag for T = 16
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,4):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d":"0748c8ef":1:PSA_ERROR_INVALID_SIGNATURE
+aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,4):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d":"0748c8ef":1:PSA_SUCCESS:PSA_ERROR_INVALID_SIGNATURE
 
 PSA Multipart AEAD verify: AES - CCM, invalid tag length 0
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,0):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"":1:PSA_ERROR_INVALID_ARGUMENT
+aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,0):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"":1:PSA_ERROR_INVALID_ARGUMENT:PSA_ERROR_INVALID_ARGUMENT
 
 PSA Multipart AEAD verify: AES - CCM, invalid tag length 2
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,2):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"c8ef":1:PSA_ERROR_INVALID_ARGUMENT
+aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,2):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"c8ef":1:PSA_ERROR_INVALID_ARGUMENT:PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart AEAD verify: AES - CCM, invalid tag length 3
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,3):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"c8ef":1:PSA_ERROR_INVALID_ARGUMENT:PSA_ERROR_INVALID_ARGUMENT
 
 PSA Multipart AEAD verify: AES - CCM, invalid tag length 15
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,15):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"0a61c9f825a48671ea05910748c8ef":1:PSA_ERROR_INVALID_ARGUMENT
+aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,15):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"c8ef":1:PSA_ERROR_INVALID_ARGUMENT:PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart AEAD verify: AES - CCM, invalid tag length 17
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,17):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"c8ef":1:PSA_ERROR_INVALID_ARGUMENT:PSA_ERROR_INVALID_ARGUMENT
 
 PSA Multipart AEAD verify: AES - CCM, T = 16, but passing 15 bytes
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"0a61c9f825a48671ea05910748c8ef":1:PSA_ERROR_INVALID_SIGNATURE
+aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"0a61c9f825a48671ea05910748c8ef":1:PSA_SUCCESS:PSA_ERROR_INVALID_SIGNATURE
 
 PSA Multipart AEAD verify: AES - CCM, T = 16, but passing 17 bytes
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"532b0a61c9f825a48671ea05910748c8ef":1:PSA_ERROR_INVALID_SIGNATURE
+aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"532b0a61c9f825a48671ea05910748c8ef":1:PSA_SUCCESS:PSA_ERROR_INVALID_SIGNATURE
 
 PSA Multipart AEAD verify: AES - CCM, T = 16 but passing 0 bytes (valid buffer)
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"":1:PSA_ERROR_INVALID_SIGNATURE
+aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"":1:PSA_SUCCESS:PSA_ERROR_INVALID_SIGNATURE
 
 PSA Multipart AEAD verify: AES - CCM, T = 16 but passing 0 bytes (NULL buffer)
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"":0:PSA_ERROR_INVALID_SIGNATURE
+aead_multipart_verify:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"":0:PSA_SUCCESS:PSA_ERROR_INVALID_SIGNATURE
 
 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
+aead_multipart_verify:PSA_KEY_TYPE_AES:"fe96eab10ff48c7942025422583d0377":PSA_ALG_GCM:"97ce3f848276783599c6875de324361e":"127628b6dcbce6fc8a8ef60798eb67b2088415635119697d20bb878c24d9c6f9c29e148521cb5e0feff892c7855d4f1c0bfb32ad33420976714dce87a0bbc18e4378bd1ef35197d0ca73051148f1199010f63caf122df5f71ad8d9c71df3eb2fbe3b2529d0ba657570358d3776f687bdb9c96d5e0e9e00c4b42d5d7a268d6a08":"12195120056ca3cac70d583603a476821bac6c57c9733b81cfb83538dc9e850f8bdf46065069591c23ebcbc6d1e2523375fb7efc80c09507fa25477ed07cee54fc4eb90168b3ef988f651fc40652474a644b1b311decf899660aef2347bb081af48950f06ebf799911e37120de94c55c20e5f0a77119be06e2b6e557f872fa0f":"6bac793bdc2190a195122c98544ccf56":1:PSA_SUCCESS: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
+aead_multipart_verify:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,15):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c87281":"4365847fe0b7b7fbed325953df344a96":1:PSA_SUCCESS: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
+aead_multipart_verify:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,15):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c87281":"4365847fe0b7b7fbed325953df34":1:PSA_SUCCESS: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
+aead_multipart_verify:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,15):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c87281":"":1:PSA_SUCCESS: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
+aead_multipart_verify:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,15):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c87281":"":0:PSA_SUCCESS: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
+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_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
+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_ERROR_INVALID_ARGUMENT
+
+PSA Multipart AEAD verify: AES - GCM, invalid tag length 3
+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,3):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd":"10b6":1:PSA_ERROR_INVALID_ARGUMENT:PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart AEAD verify: AES - GCM, invalid tag length 11
+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,11):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd":"10b6":1:PSA_ERROR_INVALID_ARGUMENT:PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart AEAD verify: AES - GCM, invalid tag length 17
+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,17):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd":"10b6":1:PSA_ERROR_INVALID_ARGUMENT:PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart AEAD verify: ChaCha20 - Poly1305, invalid tag length 0
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_verify:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305,0):"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"1ae10b594f09e26a7e902ecbd0600690":1:PSA_ERROR_NOT_SUPPORTED:PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart AEAD verify: ChaCha20 - Poly1305, invalid tag length 15
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_verify:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305,15):"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"1ae10b594f09e26a7e902ecbd0600690":1:PSA_ERROR_NOT_SUPPORTED:PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart AEAD verify: ChaCha20 - Poly1305, invalid tag length 17
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_multipart_verify:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305,17):"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"1ae10b594f09e26a7e902ecbd0600690":1:PSA_ERROR_NOT_SUPPORTED: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
+aead_multipart_verify:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"1ae10b594f09e26a7e902ecbd0600690":1:PSA_SUCCESS:PSA_ERROR_INVALID_SIGNATURE
 
 PSA Multipart Nonce Generation: AES - CCM, NONCE = (Req 13 / Expect 13)
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
@@ -3459,81 +3491,177 @@
 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 - CCM, NONCE = 0 (NULL)
+PSA Multipart Set Nonce: AES - CCM, NONCE = 0 (NULL), set lengths after nonce
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:0:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_ERROR_INVALID_ARGUMENT
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:0:SET_LENGTHS_AFTER_NONCE:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_ERROR_INVALID_ARGUMENT
 
-PSA Multipart Set Nonce: AES - CCM, NONCE = 0 (NON-NULL)
+PSA Multipart Set Nonce: AES - CCM, NONCE = 0 (NON-NULL), set lengths after nonce
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:-1:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_ERROR_INVALID_ARGUMENT
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:-1:SET_LENGTHS_AFTER_NONCE:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_ERROR_INVALID_ARGUMENT
 
-PSA Multipart Set Nonce: AES - CCM, NONCE = 6 (too small)
+PSA Multipart Set Nonce: AES - CCM, NONCE = 6 (too small), set lengths after nonce
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:6:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_ERROR_INVALID_ARGUMENT
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:6:SET_LENGTHS_AFTER_NONCE:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_ERROR_INVALID_ARGUMENT
 
-PSA Multipart Set Nonce: AES - CCM, NONCE = 14 (too long)
+PSA Multipart Set Nonce: AES - CCM, NONCE = 12, set lengths after nonce
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:14:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_ERROR_INVALID_ARGUMENT
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:12:SET_LENGTHS_AFTER_NONCE:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_SUCCESS
 
-PSA Multipart Set Nonce: AES - CCM_8, NONCE = 6 (too small)
+PSA Multipart Set Nonce: AES - CCM, NONCE = 14 (too long), set lengths after nonce
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,8):6:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_ERROR_INVALID_ARGUMENT
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:14:SET_LENGTHS_AFTER_NONCE:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_ERROR_INVALID_ARGUMENT
 
-PSA Multipart Set Nonce: AES - CCM_8, NONCE = 14 (too long)
+PSA Multipart Set Nonce: AES - CCM_8, NONCE = 6 (too small), set lengths after nonce
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,8):14:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_ERROR_INVALID_ARGUMENT
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,8):6:SET_LENGTHS_AFTER_NONCE:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_ERROR_INVALID_ARGUMENT
 
-PSA Multipart Set Nonce, AES - GCM, NONCE = 0 (NULL) (too small)
+PSA Multipart Set Nonce: AES - CCM_8, NONCE = 14 (too long), set lengths after nonce
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,8):14:SET_LENGTHS_AFTER_NONCE:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce, AES - GCM, NONCE = 0 (NULL) (too small), set lengths after nonce
 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
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_GCM:0:SET_LENGTHS_AFTER_NONCE:"":"":PSA_ERROR_INVALID_ARGUMENT
 
-PSA Multipart Set Nonce, AES - GCM, NONCE = 0 (Non-NULL) (too small)
+PSA Multipart Set Nonce, AES - GCM, NONCE = 0 (Non-NULL) (too small), set lengths after nonce
 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
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_GCM:-1:SET_LENGTHS_AFTER_NONCE:"":"":PSA_ERROR_INVALID_ARGUMENT
 
-PSA Multipart Set Nonce, AES - GCM, NONCE = 16
+PSA Multipart Set Nonce, AES - GCM, NONCE = 16, set lengths after nonce
 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
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_GCM:16:SET_LENGTHS_AFTER_NONCE:"290322092d57479e20f6281e331d95a9":"e7fb0631eebf9bdba87045b33650c4ce":PSA_SUCCESS
 
-PSA Multipart Set Nonce, AES - GCM, NONCE = 20
+PSA Multipart Set Nonce, AES - GCM, NONCE = 20, set lengths after nonce
 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
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_GCM:20:SET_LENGTHS_AFTER_NONCE:"290322092d57479e20f6281e331d95a9":"e7fb0631eebf9bdba87045b33650c4ce":PSA_SUCCESS
 
-PSA Multipart Set Nonce, AES - GCM_12, NONCE = 0 (NULL) (too small)
+PSA Multipart Set Nonce, AES - GCM_12, NONCE = 0 (NULL) (too small), set lengths after nonce
 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
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,12):0:SET_LENGTHS_AFTER_NONCE:"":"":PSA_ERROR_INVALID_ARGUMENT
 
-PSA Multipart Set Nonce, AES - GCM_12, NONCE = 0 (Non-NULL) (too small)
+PSA Multipart Set Nonce, AES - GCM_12, NONCE = 0 (Non-NULL) (too small), set lengths after nonce
 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
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,12):-1:SET_LENGTHS_AFTER_NONCE:"":"":PSA_ERROR_INVALID_ARGUMENT
 
-PSA Multipart Set Nonce, AES - GCM_12, NONCE = 16
+PSA Multipart Set Nonce, AES - GCM_12, NONCE = 16, set lengths after nonce
 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
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,12):16:SET_LENGTHS_AFTER_NONCE:"290322092d57479e20f6281e331d95a9":"e7fb0631eebf9bdba87045b33650c4ce":PSA_SUCCESS
 
-PSA Multipart Set Nonce, AES - GCM_12, NONCE = 20
+PSA Multipart Set Nonce, AES - GCM_12, NONCE = 20, set lengths after nonce
 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
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,12):20:SET_LENGTHS_AFTER_NONCE:"290322092d57479e20f6281e331d95a9":"e7fb0631eebf9bdba87045b33650c4ce":PSA_SUCCESS
 
-PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 11 (too small)
+PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 11 (too small), set lengths after nonce
 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
+aead_multipart_set_nonce:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:11:SET_LENGTHS_AFTER_NONCE:"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":PSA_ERROR_INVALID_ARGUMENT
 
-PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 12
+PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 12, set lengths after nonce
 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
+aead_multipart_set_nonce:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:12:SET_LENGTHS_AFTER_NONCE:"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":PSA_SUCCESS
 
-PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 13 (too big)
+PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 13 (too big), set lengths after nonce
 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
+aead_multipart_set_nonce:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:13:SET_LENGTHS_AFTER_NONCE:"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":PSA_ERROR_INVALID_ARGUMENT
 
-PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 0 (NULL) (too small)
+PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 0 (NULL) (too small), set lengths after nonce
 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
+aead_multipart_set_nonce:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:0:SET_LENGTHS_AFTER_NONCE:"":"":PSA_ERROR_INVALID_ARGUMENT
 
-PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 0 (Non-NULL) (too small)
+PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 0 (Non-NULL) (too small), set lengths after nonce
 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
+aead_multipart_set_nonce:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:-1:SET_LENGTHS_AFTER_NONCE:"":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce: AES - CCM, NONCE = 0 (NULL), set lengths before nonce
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:0:SET_LENGTHS_BEFORE_NONCE:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce: AES - CCM, NONCE = 0 (NON-NULL), set lengths before nonce
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:-1:SET_LENGTHS_BEFORE_NONCE:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce: AES - CCM, NONCE = 6 (too small), set lengths before nonce
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:6:SET_LENGTHS_BEFORE_NONCE:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce: AES - CCM, NONCE = 12, set lengths before nonce
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:12:SET_LENGTHS_BEFORE_NONCE:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_SUCCESS
+
+PSA Multipart Set Nonce: AES - CCM, NONCE = 14 (too long), set lengths before nonce
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:14:SET_LENGTHS_BEFORE_NONCE:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce: AES - CCM_8, NONCE = 6 (too small), set lengths before nonce
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,8):6:SET_LENGTHS_BEFORE_NONCE:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce: AES - CCM_8, NONCE = 14 (too long), set lengths before nonce
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,8):14:SET_LENGTHS_BEFORE_NONCE:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce, AES - GCM, NONCE = 0 (NULL) (too small), set lengths before nonce
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_GCM:0:SET_LENGTHS_BEFORE_NONCE:"":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce, AES - GCM, NONCE = 0 (Non-NULL) (too small), set lengths before nonce
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_GCM:-1:SET_LENGTHS_BEFORE_NONCE:"":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce, AES - GCM, NONCE = 16, set lengths before nonce
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_GCM:16:SET_LENGTHS_BEFORE_NONCE:"290322092d57479e20f6281e331d95a9":"e7fb0631eebf9bdba87045b33650c4ce":PSA_SUCCESS
+
+PSA Multipart Set Nonce, AES - GCM, NONCE = 20, set lengths before nonce
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":PSA_ALG_GCM:20:SET_LENGTHS_BEFORE_NONCE:"290322092d57479e20f6281e331d95a9":"e7fb0631eebf9bdba87045b33650c4ce":PSA_SUCCESS
+
+PSA Multipart Set Nonce, AES - GCM_12, NONCE = 0 (NULL) (too small), set lengths before nonce
+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:SET_LENGTHS_BEFORE_NONCE:"":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce, AES - GCM_12, NONCE = 0 (Non-NULL) (too small), set lengths before nonce
+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:SET_LENGTHS_BEFORE_NONCE:"":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce, AES - GCM_12, NONCE = 16, set lengths before nonce
+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:SET_LENGTHS_BEFORE_NONCE:"290322092d57479e20f6281e331d95a9":"e7fb0631eebf9bdba87045b33650c4ce":PSA_SUCCESS
+
+PSA Multipart Set Nonce, AES - GCM_12, NONCE = 20, set lengths before nonce
+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:SET_LENGTHS_BEFORE_NONCE:"290322092d57479e20f6281e331d95a9":"e7fb0631eebf9bdba87045b33650c4ce":PSA_SUCCESS
+
+PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 11 (too small), set lengths before nonce
+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:SET_LENGTHS_BEFORE_NONCE:"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 12, set lengths before nonce
+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:SET_LENGTHS_BEFORE_NONCE:"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":PSA_SUCCESS
+
+PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 13 (too big), set lengths before nonce
+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:SET_LENGTHS_BEFORE_NONCE:"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 0 (NULL) (too small), set lengths before nonce
+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:SET_LENGTHS_BEFORE_NONCE:"":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 0 (Non-NULL) (too small), set lengths before nonce
+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:SET_LENGTHS_BEFORE_NONCE:"":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA Multipart Set Nonce: AES - CCM, NONCE = 12, do not set lengths
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_set_nonce:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:12:DO_NOT_SET_LENGTHS:"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":PSA_SUCCESS
+
+PSA Multipart Set Nonce, AES - GCM_12, NONCE = 16, do not set lengths
+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:DO_NOT_SET_LENGTHS:"290322092d57479e20f6281e331d95a9":"e7fb0631eebf9bdba87045b33650c4ce":PSA_SUCCESS
+
+PSA Multipart Set Nonce: ChaCha20 - Poly1305, NONCE = 12, do not set lengths
+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:DO_NOT_SET_LENGTHS:"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":PSA_SUCCESS
 
 PSA AEAD output buffer test: AES - CCM, IN = 40 BUF = 39
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
@@ -3611,14 +3739,106 @@
 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 AEAD setup: AES - CCM, invalid tag length 18
+PSA AEAD setup: AES - CCM, invalid tag length 0
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_multipart_setup:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,18):PSA_ERROR_INVALID_ARGUMENT
+aead_multipart_setup:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,0):PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: AES - CCM, invalid tag length 2
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_setup:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,2):PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: AES - CCM, invalid tag length 3
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_setup:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,3):PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: AES - CCM, invalid tag length 5
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_setup:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,5):PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: AES - CCM, invalid tag length 7
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_setup:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,7):PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: AES - CCM, invalid tag length 9
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_setup:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,9):PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: AES - CCM, invalid tag length 11
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_setup:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,11):PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: AES - CCM, invalid tag length 13
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_setup:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,13):PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: AES - CCM, invalid tag length 15
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_setup:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,15):PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: AES - CCM, invalid tag length 17
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_setup:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM,17):PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: AES - GCM, invalid tag length 0
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_setup:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,0):PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: AES - GCM, invalid tag length 2
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_setup:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,2):PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: AES - GCM, invalid tag length 3
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_setup:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,3):PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: AES - GCM, invalid tag length 5
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_setup:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,5):PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: AES - GCM, invalid tag length 7
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_setup:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,7):PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: AES - GCM, invalid tag length 9
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_setup:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,9):PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: AES - GCM, invalid tag length 10
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_setup:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,10):PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: AES - GCM, invalid tag length 11
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_setup:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,11):PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: AES - GCM, invalid tag length 17
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_setup:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM,17):PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD setup: ChaCha20-Poly1305, invalid tag length 0
+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,0):PSA_ERROR_NOT_SUPPORTED
+
+PSA AEAD setup: ChaCha20-Poly1305, invalid tag length 15
+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,15):PSA_ERROR_NOT_SUPPORTED
+
+PSA AEAD setup: ChaCha20-Poly1305, invalid tag length 17
+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,17):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 Multipart State Checks, AES - CCM
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_multipart_state_test:PSA_KEY_TYPE_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":PSA_ALG_CCM:"000102030405060708090A0B0C":"000102030405060708090A0B":"0C0D0E0F101112131415161718191A1B1C1D1E"
+
+PSA Multipart State Checks, AES - CHACHAPOLY
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305
+aead_multipart_state_test:PSA_KEY_TYPE_CHACHA20:"0000000000000000000000000000000000000000000000000000000000000000":PSA_ALG_CHACHA20_POLY1305:"000102030405060708090A0B":"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 638a85c..8a08b1c 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -4117,6 +4117,7 @@
 void aead_multipart_set_nonce( int key_type_arg, data_t *key_data,
                                int alg_arg,
                                int nonce_length_arg,
+                               int set_lengths_method_arg,
                                data_t *additional_data,
                                data_t *input_data,
                                int expected_status_arg )
@@ -4139,6 +4140,7 @@
     size_t tag_length = 0;
     uint8_t tag_buffer[PSA_AEAD_TAG_MAX_SIZE];
     size_t index = 0;
+    set_lengths_method_t set_lengths_method = set_lengths_method_arg;
 
     PSA_ASSERT( psa_crypto_init( ) );
 
@@ -4196,26 +4198,40 @@
         }
     }
 
+    if( set_lengths_method == SET_LENGTHS_BEFORE_NONCE )
+    {
+        PSA_ASSERT( psa_aead_set_lengths( &operation, additional_data->len,
+                                          input_data->len ) );
+    }
+
     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_set_lengths( &operation, additional_data->len,
-                                          input_data->len ) );
+        if( set_lengths_method == SET_LENGTHS_AFTER_NONCE )
+        {
+            PSA_ASSERT( psa_aead_set_lengths( &operation, additional_data->len,
+                                              input_data->len ) );
+        }
+        if( operation.alg == PSA_ALG_CCM && set_lengths_method == DO_NOT_SET_LENGTHS )
+            expected_status = PSA_ERROR_BAD_STATE;
 
-        PSA_ASSERT( psa_aead_update_ad( &operation, additional_data->x,
-                                        additional_data->len ) );
+        /* Ensure we can still complete operation, unless it's CCM and we didn't set lengths. */
+        TEST_EQUAL( psa_aead_update_ad( &operation, additional_data->x,
+                                        additional_data->len ),
+                    expected_status );
 
-        PSA_ASSERT( psa_aead_update( &operation, input_data->x, input_data->len,
+        TEST_EQUAL( psa_aead_update( &operation, input_data->x, input_data->len,
                                      output, output_size,
-                                     &ciphertext_length ) );
+                                     &ciphertext_length ),
+                    expected_status );
 
-        PSA_ASSERT( psa_aead_finish( &operation, ciphertext, ciphertext_size,
+        TEST_EQUAL( psa_aead_finish( &operation, ciphertext, ciphertext_size,
                                      &ciphertext_length, tag_buffer,
-                                     PSA_AEAD_TAG_MAX_SIZE, &tag_length ) );
+                                     PSA_AEAD_TAG_MAX_SIZE, &tag_length ),
+                    expected_status );
     }
 
 exit:
@@ -4409,6 +4425,7 @@
                             data_t *input_data,
                             data_t *tag,
                             int tag_usage_arg,
+                            int expected_setup_status_arg,
                             int expected_status_arg )
 {
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
@@ -4418,6 +4435,7 @@
     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_status_t expected_setup_status = expected_setup_status_arg;
     unsigned char *plaintext = NULL;
     unsigned char *finish_plaintext = NULL;
     size_t plaintext_size = 0;
@@ -4457,6 +4475,10 @@
         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 );
     }
+    TEST_EQUAL( status, expected_setup_status );
+
+    if( status != PSA_SUCCESS )
+        goto exit;
 
     PSA_ASSERT( status );
 
@@ -4464,17 +4486,7 @@
 
     status = psa_aead_set_lengths( &operation, additional_data->len,
                                       input_data->len );
-
-    if( status != PSA_SUCCESS )
-    {
-        /* Invalid tag lengths are detected in CCM at this point, as they
-         * would be written into the first block. They should really be
-         * detected in psa_aead_encrypt/decrypt_setup, and will be fixed
-         * to do so in the future, until that point, this is a
-         * workaround.*/
-        TEST_EQUAL( status, expected_status );
-        goto exit;
-    }
+    PSA_ASSERT( status );
 
     PSA_ASSERT( psa_aead_update_ad( &operation, additional_data->x,
                                     additional_data->len ) );
@@ -4781,6 +4793,208 @@
 
     psa_aead_abort( &operation );
 
+    /* Test for generating nonce after calling set lengths */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_lengths( &operation, additional_data->len,
+                                      input_data->len ) );
+
+    PSA_ASSERT( psa_aead_generate_nonce( &operation, nonce_buffer,
+                                         PSA_AEAD_NONCE_MAX_SIZE,
+                                         &nonce_length ) );
+
+    psa_aead_abort( &operation );
+
+    /* Test for generating nonce after calling set lengths with UINT32_MAX ad_data length */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    if( operation.alg == PSA_ALG_CCM )
+    {
+        TEST_EQUAL( psa_aead_set_lengths( &operation, UINT32_MAX,
+                                          input_data->len ),
+                    PSA_ERROR_INVALID_ARGUMENT );
+        TEST_EQUAL( psa_aead_generate_nonce( &operation, nonce_buffer,
+                                             PSA_AEAD_NONCE_MAX_SIZE,
+                                             &nonce_length ),
+                    PSA_ERROR_BAD_STATE );
+    }
+    else
+    {
+        PSA_ASSERT( psa_aead_set_lengths( &operation, UINT32_MAX,
+                                          input_data->len ) );
+        PSA_ASSERT( psa_aead_generate_nonce( &operation, nonce_buffer,
+                                             PSA_AEAD_NONCE_MAX_SIZE,
+                                             &nonce_length ) );
+    }
+
+    psa_aead_abort( &operation );
+
+    /* Test for generating nonce after calling set lengths with SIZE_MAX ad_data length */
+#if SIZE_MAX > UINT32_MAX
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    if( operation.alg == PSA_ALG_CCM || operation.alg == PSA_ALG_GCM )
+    {
+        TEST_EQUAL( psa_aead_set_lengths( &operation, SIZE_MAX,
+                                          input_data->len ),
+                    PSA_ERROR_INVALID_ARGUMENT );
+        TEST_EQUAL( psa_aead_generate_nonce( &operation, nonce_buffer,
+                                             PSA_AEAD_NONCE_MAX_SIZE,
+                                             &nonce_length ),
+                    PSA_ERROR_BAD_STATE );
+    }
+    else
+    {
+        PSA_ASSERT( psa_aead_set_lengths( &operation, SIZE_MAX,
+                                          input_data->len ) );
+        PSA_ASSERT( psa_aead_generate_nonce( &operation, nonce_buffer,
+                                             PSA_AEAD_NONCE_MAX_SIZE,
+                                             &nonce_length ) );
+    }
+
+    psa_aead_abort( &operation );
+#endif
+
+    /* Test for calling set lengths with a UINT32_MAX ad_data length, after 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 ) );
+
+    if( operation.alg == PSA_ALG_CCM )
+    {
+        TEST_EQUAL( psa_aead_set_lengths( &operation, UINT32_MAX,
+                                          input_data->len ),
+                    PSA_ERROR_INVALID_ARGUMENT );
+    }
+    else
+    {
+        PSA_ASSERT( psa_aead_set_lengths( &operation, UINT32_MAX,
+                                          input_data->len ) );
+    }
+
+    psa_aead_abort( &operation );
+
+    /* ------------------------------------------------------- */
+    /* Test for setting nonce after calling set lengths */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_lengths( &operation, additional_data->len,
+                                      input_data->len ) );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    psa_aead_abort( &operation );
+
+    /* Test for setting nonce after calling set lengths with UINT32_MAX ad_data length */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    if( operation.alg == PSA_ALG_CCM )
+    {
+        TEST_EQUAL( psa_aead_set_lengths( &operation, UINT32_MAX,
+                                          input_data->len ),
+                    PSA_ERROR_INVALID_ARGUMENT );
+        TEST_EQUAL( psa_aead_set_nonce( &operation, nonce->x, nonce->len ),
+                    PSA_ERROR_BAD_STATE );
+    }
+    else
+    {
+        PSA_ASSERT( psa_aead_set_lengths( &operation, UINT32_MAX,
+                                          input_data->len ) );
+        PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+    }
+
+    psa_aead_abort( &operation );
+
+    /* Test for setting nonce after calling set lengths with SIZE_MAX ad_data length */
+#if SIZE_MAX > UINT32_MAX
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    if( operation.alg == PSA_ALG_CCM || operation.alg == PSA_ALG_GCM )
+    {
+        TEST_EQUAL( psa_aead_set_lengths( &operation, SIZE_MAX,
+                                          input_data->len ),
+                    PSA_ERROR_INVALID_ARGUMENT );
+        TEST_EQUAL( psa_aead_set_nonce( &operation, nonce->x, nonce->len ),
+                    PSA_ERROR_BAD_STATE );
+    }
+    else
+    {
+        PSA_ASSERT( psa_aead_set_lengths( &operation, SIZE_MAX,
+                                          input_data->len ) );
+        PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+    }
+
+    psa_aead_abort( &operation );
+#endif
+
+    /* Test for calling set lengths with an ad_data length of UINT32_MAX, after setting nonce */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    if( operation.alg == PSA_ALG_CCM )
+    {
+        TEST_EQUAL( psa_aead_set_lengths( &operation, UINT32_MAX,
+                                          input_data->len ),
+                    PSA_ERROR_INVALID_ARGUMENT );
+    }
+    else
+    {
+        PSA_ASSERT( psa_aead_set_lengths( &operation, UINT32_MAX,
+                                          input_data->len ) );
+    }
+
+    psa_aead_abort( &operation );
+
+    /* Test for setting nonce after calling set lengths with plaintext length of SIZE_MAX */
+#if SIZE_MAX > UINT32_MAX
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    if( operation.alg == PSA_ALG_GCM )
+    {
+        TEST_EQUAL( psa_aead_set_lengths( &operation, additional_data->len,
+                                          SIZE_MAX ),
+                    PSA_ERROR_INVALID_ARGUMENT );
+        TEST_EQUAL( psa_aead_set_nonce( &operation, nonce->x, nonce->len ),
+                    PSA_ERROR_BAD_STATE );
+    }
+    else if ( operation.alg != PSA_ALG_CCM )
+    {
+        PSA_ASSERT( psa_aead_set_lengths( &operation, additional_data->len,
+                                          SIZE_MAX ) );
+        PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+    }
+
+    psa_aead_abort( &operation );
+
+    /* Test for calling set lengths with an plaintext length of SIZE_MAX, after setting nonce */
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    if( operation.alg == PSA_ALG_GCM )
+    {
+        TEST_EQUAL( psa_aead_set_lengths( &operation, additional_data->len,
+                                          SIZE_MAX ),
+                    PSA_ERROR_INVALID_ARGUMENT );
+    }
+    else if ( operation.alg != PSA_ALG_CCM )
+    {
+        PSA_ASSERT( psa_aead_set_lengths( &operation, additional_data->len,
+                                          SIZE_MAX ) );
+    }
+
+    psa_aead_abort( &operation );
+#endif
+
     /* ------------------------------------------------------- */
 
     PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
@@ -4820,19 +5034,28 @@
 
     psa_aead_abort( &operation );
 
-    /* Test for setting lengths after already starting data. */
+    /* Test for setting lengths after setting nonce + 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 ) );
+    if( operation.alg == PSA_ALG_CCM )
+    {
 
-    TEST_EQUAL( psa_aead_set_lengths( &operation, additional_data->len,
-                                      input_data->len ),
-                PSA_ERROR_BAD_STATE );
+        TEST_EQUAL( psa_aead_update_ad( &operation, additional_data->x,
+                                        additional_data->len ),
+                    PSA_ERROR_BAD_STATE );
+    }
+    else
+    {
+        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 );
 
     /* ------------------------------------------------------- */
@@ -4841,14 +5064,133 @@
 
     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 ) );
+    if( operation.alg == PSA_ALG_CCM )
+    {
+        TEST_EQUAL( psa_aead_update( &operation, input_data->x,
+                                     input_data->len, output_data,
+                                     output_size, &output_length ),
+                    PSA_ERROR_BAD_STATE );
 
-    TEST_EQUAL( psa_aead_set_lengths( &operation, additional_data->len,
-                                      input_data->len ),
-                PSA_ERROR_BAD_STATE );
+    }
+    else
+    {
+        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 );
+
+    /* ------------------------------------------------------- */
+
+    PSA_ASSERT( psa_aead_encrypt_setup( &operation, key, alg ) );
+
+    PSA_ASSERT( psa_aead_set_nonce( &operation, nonce->x, nonce->len ) );
+
+    if( operation.alg == PSA_ALG_CCM )
+    {
+        PSA_ASSERT( psa_aead_finish( &operation, final_data,
+                                     finish_output_size,
+                                     &output_part_length,
+                                     tag_buffer, tag_length,
+                                     &tag_size ) );
+    }
+    else
+    {
+        PSA_ASSERT( psa_aead_finish( &operation, final_data,
+                                     finish_output_size,
+                                     &output_part_length,
+                                     tag_buffer, tag_length,
+                                     &tag_size ) );
+
+        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 generating nonce + already starting data. */
+
+    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 ) );
+    if( operation.alg == PSA_ALG_CCM )
+    {
+
+        TEST_EQUAL( psa_aead_update_ad( &operation, additional_data->x,
+                                        additional_data->len ),
+                    PSA_ERROR_BAD_STATE );
+    }
+    else
+    {
+        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_generate_nonce( &operation, nonce_buffer,
+                                         PSA_AEAD_NONCE_MAX_SIZE,
+                                         &nonce_length ) );
+    if( operation.alg == PSA_ALG_CCM )
+    {
+        TEST_EQUAL( psa_aead_update( &operation, input_data->x,
+                                     input_data->len, output_data,
+                                     output_size, &output_length ),
+                    PSA_ERROR_BAD_STATE );
+
+    }
+    else
+    {
+        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 );
+
+    /* ------------------------------------------------------- */
+
+    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 ) );
+    if( operation.alg == PSA_ALG_CCM )
+    {
+        PSA_ASSERT( psa_aead_finish( &operation, final_data,
+                                     finish_output_size,
+                                     &output_part_length,
+                                     tag_buffer, tag_length,
+                                     &tag_size ) );
+    }
+    else
+    {
+        PSA_ASSERT( psa_aead_finish( &operation, final_data,
+                                     finish_output_size,
+                                     &output_part_length,
+                                     tag_buffer, tag_length,
+                                     &tag_size ) );
+
+        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
@@ -5004,14 +5346,16 @@
 
     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 ) );
+    if( operation.alg != PSA_ALG_CCM )
+    {
+        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 );
-
+        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. */
diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.data b/tests/suites/test_suite_psa_crypto_driver_wrappers.data
index ea6c9b3..08a8b29 100644
--- a/tests/suites/test_suite_psa_crypto_driver_wrappers.data
+++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.data
@@ -305,6 +305,22 @@
 depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
 aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":PSA_ERROR_INSUFFICIENT_MEMORY
 
+PSA MAC sign multipart, through driver: HMAC-SHA-224, parts: 0
+depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC:MBEDTLS_PSA_ACCEL_ALG_HMAC
+mac_sign_multipart:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"ba7d81028e07b30466b867d8fefaa52db111d56b45df5a0e1465bf39":0:PSA_SUCCESS
+
+PSA MAC sign multipart, through driver: HMAC-SHA-224, parts: 1
+depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC:MBEDTLS_PSA_ACCEL_ALG_HMAC
+mac_sign_multipart:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":1:PSA_SUCCESS
+
+PSA MAC sign multipart, through driver: HMAC-SHA-224, parts: 2
+depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC:MBEDTLS_PSA_ACCEL_ALG_HMAC
+mac_sign_multipart:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":2:PSA_SUCCESS
+
+PSA MAC sign multipart, through driver: HMAC-SHA-224, parts: 3
+depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC:MBEDTLS_PSA_ACCEL_ALG_HMAC
+mac_sign_multipart:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":3:PSA_SUCCESS
+
 PSA MAC sign, through driver: HMAC-SHA-224
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC:MBEDTLS_PSA_ACCEL_ALG_HMAC
 mac_sign:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":PSA_SUCCESS
@@ -329,6 +345,22 @@
 depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES
 mac_sign:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_CMAC:"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827":PSA_ERROR_GENERIC_ERROR
 
+PSA MAC verify multipart, through driver: HMAC-SHA-224, parts: 0
+depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC:MBEDTLS_PSA_ACCEL_ALG_HMAC
+mac_verify_multipart:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"ba7d81028e07b30466b867d8fefaa52db111d56b45df5a0e1465bf39":0:PSA_SUCCESS
+
+PSA MAC verify multipart, through driver: HMAC-SHA-224, parts: 1
+depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC:MBEDTLS_PSA_ACCEL_ALG_HMAC
+mac_verify_multipart:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":1:PSA_SUCCESS
+
+PSA MAC verify multipart, through driver: HMAC-SHA-224, parts: 2
+depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC:MBEDTLS_PSA_ACCEL_ALG_HMAC
+mac_verify_multipart:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":2:PSA_SUCCESS
+
+PSA MAC verify multipart, through driver: HMAC-SHA-224, parts: 3
+depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC:MBEDTLS_PSA_ACCEL_ALG_HMAC
+mac_verify_multipart:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":3:PSA_SUCCESS
+
 PSA MAC verify, through driver: HMAC-SHA-224
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC:MBEDTLS_PSA_ACCEL_ALG_HMAC
 mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":PSA_SUCCESS
diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function
index 64adba9..aab81fb 100644
--- a/tests/suites/test_suite_psa_crypto_driver_wrappers.function
+++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.function
@@ -1247,9 +1247,64 @@
     else
         TEST_EQUAL( forced_status, status );
 
-    if( mac_buffer_size > 0 )
-        memset( actual_mac, 0, mac_buffer_size );
+    PSA_ASSERT( psa_mac_abort( &operation ) );
+    TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 );
+
+    if( forced_status == PSA_SUCCESS )
+    {
+        ASSERT_COMPARE( expected_mac->x, expected_mac->len,
+                        actual_mac, mac_length );
+    }
+
+    mbedtls_free( actual_mac );
+    actual_mac = NULL;
+
+exit:
+    psa_mac_abort( &operation );
+    psa_destroy_key( key );
+    PSA_DONE( );
+    mbedtls_free( actual_mac );
     mbedtls_test_driver_mac_hooks = mbedtls_test_driver_mac_hooks_init();
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mac_sign_multipart( int key_type_arg,
+                         data_t *key_data,
+                         int alg_arg,
+                         data_t *input,
+                         data_t *expected_mac,
+                         int fragments_count,
+                         int forced_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_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    uint8_t *actual_mac = NULL;
+    size_t mac_buffer_size =
+        PSA_MAC_LENGTH( key_type, PSA_BYTES_TO_BITS( key_data->len ), alg );
+    size_t mac_length = 0;
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_status_t forced_status = forced_status_arg;
+    uint8_t *input_x = input->x;
+    mbedtls_test_driver_mac_hooks = mbedtls_test_driver_mac_hooks_init();
+
+    TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
+    /* We expect PSA_MAC_LENGTH to be exact. */
+    TEST_ASSERT( expected_mac->len == mac_buffer_size );
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH );
+    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 ) );
+
+    ASSERT_ALLOC( actual_mac, mac_buffer_size );
     mbedtls_test_driver_mac_hooks.forced_status = forced_status;
 
     /*
@@ -1266,25 +1321,38 @@
     else
         TEST_EQUAL( forced_status, status );
 
-    status = psa_mac_update( &operation,
-                             input->x, input->len );
-    if( forced_status == PSA_SUCCESS )
-        TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 2 );
-    else
-        TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 );
-    if( forced_status == PSA_SUCCESS ||
-        forced_status == PSA_ERROR_NOT_SUPPORTED )
+    if ( fragments_count )
     {
-        PSA_ASSERT( status );
+        TEST_ASSERT( ( input->len / fragments_count ) > 0 );
     }
-    else
-        TEST_EQUAL( PSA_ERROR_BAD_STATE, status );
+
+    for ( int i = 0; i < fragments_count; i++)
+    {
+        int fragment_size = input->len / fragments_count;
+        if ( i == fragments_count - 1 )
+            fragment_size += ( input->len % fragments_count );
+
+        status = psa_mac_update( &operation,
+                                input_x, fragment_size );
+        if( forced_status == PSA_SUCCESS )
+            TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 2 + i );
+        else
+            TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 );
+        if( forced_status == PSA_SUCCESS ||
+            forced_status == PSA_ERROR_NOT_SUPPORTED )
+        {
+            PSA_ASSERT( status );
+        }
+        else
+            TEST_EQUAL( PSA_ERROR_BAD_STATE, status );
+        input_x += fragment_size;
+    }
 
     status = psa_mac_sign_finish( &operation,
                                   actual_mac, mac_buffer_size,
                                   &mac_length );
     if( forced_status == PSA_SUCCESS )
-        TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 4 );
+        TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 3 + fragments_count );
     else
         TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 );
 
@@ -1298,7 +1366,7 @@
 
     PSA_ASSERT( psa_mac_abort( &operation ) );
     if( forced_status == PSA_SUCCESS )
-        TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 4 );
+        TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 3 + fragments_count );
     else
         TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 );
 
@@ -1365,7 +1433,46 @@
     else
         TEST_EQUAL( forced_status, status );
 
+    PSA_ASSERT( psa_mac_abort( &operation ) );
+    TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 );
+exit:
+    psa_mac_abort( &operation );
+    psa_destroy_key( key );
+    PSA_DONE( );
     mbedtls_test_driver_mac_hooks = mbedtls_test_driver_mac_hooks_init();
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mac_verify_multipart( int key_type_arg,
+                           data_t *key_data,
+                           int alg_arg,
+                           data_t *input,
+                           data_t *expected_mac,
+                           int fragments_count,
+                           int forced_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_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_status_t status = PSA_ERROR_GENERIC_ERROR;
+    psa_status_t forced_status = forced_status_arg;
+    uint8_t *input_x = input->x;
+    mbedtls_test_driver_mac_hooks = mbedtls_test_driver_mac_hooks_init();
+
+    TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY_HASH );
+    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 ) );
+
     mbedtls_test_driver_mac_hooks.forced_status = forced_status;
 
     /*
@@ -1382,26 +1489,39 @@
     else
         TEST_EQUAL( forced_status, status );
 
-    status = psa_mac_update( &operation,
-                             input->x, input->len );
-    if( forced_status == PSA_SUCCESS )
-        TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 2 );
-    else
-        TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 );
-
-    if( forced_status == PSA_SUCCESS ||
-        forced_status == PSA_ERROR_NOT_SUPPORTED )
+    if ( fragments_count )
     {
-        PSA_ASSERT( status );
+        TEST_ASSERT( ( input->len / fragments_count ) > 0 );
     }
-    else
-        TEST_EQUAL( PSA_ERROR_BAD_STATE, status );
+
+    for ( int i = 0; i < fragments_count; i++)
+    {
+        int fragment_size = input->len / fragments_count;
+        if ( i == fragments_count - 1 )
+            fragment_size += ( input->len % fragments_count );
+
+        status = psa_mac_update( &operation,
+                                input_x, fragment_size );
+        if( forced_status == PSA_SUCCESS )
+            TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 2 + i );
+        else
+            TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 );
+
+        if( forced_status == PSA_SUCCESS ||
+            forced_status == PSA_ERROR_NOT_SUPPORTED )
+        {
+            PSA_ASSERT( status );
+        }
+        else
+            TEST_EQUAL( PSA_ERROR_BAD_STATE, status );
+        input_x += fragment_size;
+    }
 
     status = psa_mac_verify_finish( &operation,
                                     expected_mac->x,
                                     expected_mac->len );
     if( forced_status == PSA_SUCCESS )
-        TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 4 );
+        TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 3 + fragments_count );
     else
         TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 );
 
@@ -1416,7 +1536,7 @@
 
     PSA_ASSERT( psa_mac_abort( &operation ) );
     if( forced_status == PSA_SUCCESS )
-        TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 4 );
+        TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 3 + fragments_count );
     else
         TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 );
 
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index ce934b0..7a0b1f7 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -4815,13 +4815,15 @@
     unsigned char psk0_raw[10] = { 0 };
     unsigned char psk0_raw_identity[] = { 'f', 'o', 'o' };
 
-    psa_key_id_t psk0_opaque = (psa_key_id_t) 1;
+    mbedtls_svc_key_id_t psk0_opaque = mbedtls_svc_key_id_make( 0x1, (psa_key_id_t) 1 );
+
     unsigned char psk0_opaque_identity[] = { 'f', 'o', 'o' };
 
     unsigned char psk1_raw[10] = { 0 };
     unsigned char psk1_raw_identity[] = { 'b', 'a', 'r' };
 
-    psa_key_id_t psk1_opaque = (psa_key_id_t) 2;
+    mbedtls_svc_key_id_t psk1_opaque = mbedtls_svc_key_id_make( 0x1, (psa_key_id_t) 2 );
+
     unsigned char psk1_opaque_identity[] = { 'b', 'a', 'r' };
 
     mbedtls_ssl_config conf;