Merge pull request #5813 from mprse/deprecate_mbedtls_cipher_setup_psa

Deprecate mbedtls_cipher_setup_psa()
diff --git a/.travis.yml b/.travis.yml
index 82e7d30..67cb3ca 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -54,7 +54,7 @@
 env:
   global:
     - SEED=1
-    - secure: "FrI5d2s+ckckC17T66c8jm2jV6i2DkBPU5nyWzwbedjmEBeocREfQLd/x8yKpPzLDz7ghOvr+/GQvsPPn0dVkGlNzm3Q+hGHc/ujnASuUtGrcuMM+0ALnJ3k4rFr9xEvjJeWb4SmhJO5UCAZYvTItW4k7+bj9L+R6lt3TzQbXzg="
+    - secure: "JECCru6HASpKZ0OLfHh8f/KXhKkdrCwjquZghd/qbA4ksxsWImjR7KEPERcaPndXEilzhDbKwuFvJiQX2duVgTGoq745YGhLZIjzo1i8tySkceCVd48P8WceYGz+F/bmY7r+m6fFNuxDSoGGSVeA4Lnjvmm8PFUP45YodDV9no4="
 
 install:
   - $PYTHON scripts/min_requirements.py
@@ -65,7 +65,7 @@
     - gnutls-bin
   coverity_scan:
     project:
-      name: "Mbed-TLS/mbedtls"
+      name: "ARMmbed/mbedtls"
     notification_email: support-mbedtls@arm.com
     build_command_prepend:
     build_command: make
diff --git a/3rdparty/everest/CMakeLists.txt b/3rdparty/everest/CMakeLists.txt
index ff9da7a..4ad367e 100644
--- a/3rdparty/everest/CMakeLists.txt
+++ b/3rdparty/everest/CMakeLists.txt
@@ -23,5 +23,5 @@
 
 install(TARGETS everest
   EXPORT MbedTLSTargets
-  DESTINATION ${LIB_INSTALL_DIR}
+  DESTINATION ${CMAKE_INSTALL_LIBDIR}
   PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
diff --git a/3rdparty/everest/README.md b/3rdparty/everest/README.md
index 0e25466..bcf12c0 100644
--- a/3rdparty/everest/README.md
+++ b/3rdparty/everest/README.md
@@ -2,4 +2,4 @@
 
 This is a formally verified implementation of Curve25519-based handshakes. The C code is automatically derived from the (verified) [original implementation](https://github.com/project-everest/hacl-star/tree/master/code/curve25519) in the [F* language](https://github.com/fstarlang/fstar) by [KreMLin](https://github.com/fstarlang/kremlin). In addition to the improved safety and security of the implementation, it is also significantly faster than the default implementation of Curve25519 in mbedTLS.
 
-The caveat is that not all platforms are supported, although the version in `everest/library/legacy` should work on most systems. The main issue is that some platforms do not provide a 128-bit integer type and KreMLin therefore has to use additional (also verified) code to simulate them, resulting in less of a performance gain overall. Explictly supported platforms are currently `x86` and `x86_64` using gcc or clang, and Visual C (2010 and later).
+The caveat is that not all platforms are supported, although the version in `everest/library/legacy` should work on most systems. The main issue is that some platforms do not provide a 128-bit integer type and KreMLin therefore has to use additional (also verified) code to simulate them, resulting in less of a performance gain overall. Explicitly supported platforms are currently `x86` and `x86_64` using gcc or clang, and Visual C (2010 and later).
diff --git a/3rdparty/everest/include/everest/everest.h b/3rdparty/everest/include/everest/everest.h
index 5806500..392e792 100644
--- a/3rdparty/everest/include/everest/everest.h
+++ b/3rdparty/everest/include/everest/everest.h
@@ -96,7 +96,7 @@
                                  void *p_rng );
 
 /**
- * \brief           This function parses and processes a TLS ServerKeyExhange
+ * \brief           This function parses and processes a TLS ServerKeyExchange
  *                  payload.
  *
  *                  This is the first function used by a TLS client for ECDHE
@@ -116,7 +116,7 @@
                                  const unsigned char **buf, const unsigned char *end );
 
 /**
- * \brief           This function parses and processes a TLS ServerKeyExhange
+ * \brief           This function parses and processes a TLS ServerKeyExchange
  *                  payload.
  *
  *                  This is the first function used by a TLS client for ECDHE
diff --git a/3rdparty/everest/library/Hacl_Curve25519_joined.c b/3rdparty/everest/library/Hacl_Curve25519_joined.c
index ee62be1..957294f 100644
--- a/3rdparty/everest/library/Hacl_Curve25519_joined.c
+++ b/3rdparty/everest/library/Hacl_Curve25519_joined.c
@@ -18,6 +18,15 @@
  *
  *  This file is part of mbed TLS (https://tls.mbed.org)
  */
+#ifndef _BSD_SOURCE
+/* Required to get htole64() from gcc/glibc's endian.h (older systems)
+ * when we compile with -std=c99 */
+#define _BSD_SOURCE
+#endif
+#ifndef _DEFAULT_SOURCE
+/* (modern version of _BSD_SOURCE) */
+#define _DEFAULT_SOURCE
+#endif
 
 #include "common.h"
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0fccd3d..b97368f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,9 +6,9 @@
 #     command but rather at the target level using the
 #     target_include_directories command. That way, it is easier to guarantee
 #     that targets are built using the proper list of include directories.
-#   + Use the PUBLIC and PRIVATE keywords to specifiy the scope of include
+#   + Use the PUBLIC and PRIVATE keywords to specify the scope of include
 #     directories. That way, a target linking to a library (using the
-#     target_link_librairies command) inherits from the library PUBLIC include
+#     target_link_libraries command) inherits from the library PUBLIC include
 #     directories and not from the PRIVATE ones.
 # - MBEDTLS_TARGET_PREFIX: CMake targets are designed to be alterable by calling
 #   CMake in order to avoid target name clashes, via the use of
@@ -39,6 +39,8 @@
     project("mbed TLS" C)
 endif()
 
+include(GNUInstallDirs)
+
 # Determine if mbed TLS is being built as a subproject using add_subdirectory()
 if(NOT DEFINED MBEDTLS_AS_SUBPROJECT)
   set(MBEDTLS_AS_SUBPROJECT ON)
@@ -170,6 +172,9 @@
 
 include(CheckCCompilerFlag)
 
+set(CMAKE_C_EXTENSIONS OFF)
+set(CMAKE_C_STANDARD 99)
+
 if(CMAKE_COMPILER_IS_GNU)
     # some warnings we want are not available with old GCC versions
     # note: starting with CMake 2.8 we could use CMAKE_C_COMPILER_VERSION
@@ -249,8 +254,7 @@
 endif(CMAKE_BUILD_TYPE STREQUAL "Coverage")
 
 if(LIB_INSTALL_DIR)
-else()
-    set(LIB_INSTALL_DIR lib)
+    set(CMAKE_INSTALL_LIBDIR "${LIB_INSTALL_DIR}")
 endif()
 
 add_subdirectory(include)
diff --git a/ChangeLog.d/cmake_fix_dll_install.txt b/ChangeLog.d/cmake_fix_dll_install.txt
new file mode 100644
index 0000000..df51c65
--- /dev/null
+++ b/ChangeLog.d/cmake_fix_dll_install.txt
@@ -0,0 +1,3 @@
+Changes
+   * cmake: Fix runtime library install location in mingw
+     This install DLLs in bin directory instead of lib.
diff --git a/ChangeLog.d/cmake_use_GnuInstallDirs.txt b/ChangeLog.d/cmake_use_GnuInstallDirs.txt
new file mode 100644
index 0000000..d848755
--- /dev/null
+++ b/ChangeLog.d/cmake_use_GnuInstallDirs.txt
@@ -0,0 +1,5 @@
+Changes
+   * cmake: Use GnuInstallDirs to customize install directories
+     Replace custom LIB_INSTALL_DIR variable with standard CMAKE_INSTALL_LIBDIR
+     variable. For backward compatibility, set CMAKE_INSTALL_LIBDIR if
+     LIB_INSTALL_DIR is set.
diff --git a/ChangeLog.d/mingw.txt b/ChangeLog.d/mingw.txt
new file mode 100644
index 0000000..ac4e741
--- /dev/null
+++ b/ChangeLog.d/mingw.txt
@@ -0,0 +1,4 @@
+Bugfix
+   * Fix compilation error with mingw32. Fixed by Cameron Cawley in #4211.
+   * Fix compilation error when using C++ Builder on Windows. Reported by
+     Miroslav Mastny in #4015.
diff --git a/ChangeLog.d/psa_raw_key_agreement-buffer_too_small.txt b/ChangeLog.d/psa_raw_key_agreement-buffer_too_small.txt
new file mode 100644
index 0000000..415c849
--- /dev/null
+++ b/ChangeLog.d/psa_raw_key_agreement-buffer_too_small.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * psa_raw_key_agreement() now returns PSA_ERROR_BUFFER_TOO_SMALL when
+     applicable. Fixes #5735.
diff --git a/ChangeLog.d/static_link_common_runtime_msvc.txt b/ChangeLog.d/static_link_common_runtime_msvc.txt
new file mode 100644
index 0000000..6104943
--- /dev/null
+++ b/ChangeLog.d/static_link_common_runtime_msvc.txt
@@ -0,0 +1,3 @@
+Changes
+   * Add a CMake option that enables static linking of the runtime library
+     in Microsoft Visual C++ compiler. Contributed by Microplankton.
diff --git a/SECURITY.md b/SECURITY.md
index bd18f6c..26b77ab 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -6,7 +6,7 @@
 
 ## Security Incident Handling Process
 
-Our security process is detailled in our
+Our security process is detailed in our
 [security
 center](https://developer.trustedfirmware.org/w/mbed-tls/security-center/).
 
diff --git a/configs/config-suite-b.h b/configs/config-suite-b.h
index 68ccf10..35622fc 100644
--- a/configs/config-suite-b.h
+++ b/configs/config-suite-b.h
@@ -104,7 +104,7 @@
 
 /*
  * Save RAM at the expense of interoperability: do this only if you control
- * both ends of the connection!  (See coments in "mbedtls/ssl.h".)
+ * both ends of the connection!  (See comments in "mbedtls/ssl.h".)
  * The minimum size here depends on the certificate chain used as well as the
  * typical size of records.
  */
diff --git a/docs/architecture/psa-migration/psa-limitations.md b/docs/architecture/psa-migration/psa-limitations.md
index 31adec3..f5b5700 100644
--- a/docs/architecture/psa-migration/psa-limitations.md
+++ b/docs/architecture/psa-migration/psa-limitations.md
@@ -84,7 +84,7 @@
   - most commonly MGF1, which in turn is parametrized by a hash algorithm
 - a salt length
 - a trailer field - the value is fixed to 0xBC by PKCS#1 v2.1, but was left
-  configurable in the original scheme; 0xBC is used everywhere in pratice.
+  configurable in the original scheme; 0xBC is used everywhere in practice.
 
 Both the existing `mbedtls_` API and the PSA API support only MGF1 as the
 generation function (and only 0xBC as the trailer field), but there are
@@ -317,7 +317,7 @@
 HKDF: Expand not exposed on its own (TLS 1.3)
 ---------------------------------------------
 
-The HKDF function uses and Extract-then-Expand approch, that is:
+The HKDF function uses an Extract-then-Expand approach, that is:
 
         HKDF(x, ...) = HKDF-Expand(HKDF-Extract(x, ...), ...)
 
diff --git a/docs/architecture/psa-migration/strategy.md b/docs/architecture/psa-migration/strategy.md
index d63bb8e..2bb0284 100644
--- a/docs/architecture/psa-migration/strategy.md
+++ b/docs/architecture/psa-migration/strategy.md
@@ -360,7 +360,7 @@
 
 2. APIs the accept list of identifiers: for example
    `mbedtls_ssl_conf_curves()` taking a list of `mbedtls_ecp_group_id`s. This
-could be changed to accept a list of pairs (`psa_ecc_familiy_t`, size) but we
+could be changed to accept a list of pairs (`psa_ecc_family_t`, size) but we
 should probably take this opportunity to move to a identifier independent from
 the underlying crypto implementation and use TLS-specific identifiers instead
 (based on IANA values or custom enums), as is currently done in the new
diff --git a/docs/architecture/testing/driver-interface-test-strategy.md b/docs/architecture/testing/driver-interface-test-strategy.md
index 086fc1a..a726c43 100644
--- a/docs/architecture/testing/driver-interface-test-strategy.md
+++ b/docs/architecture/testing/driver-interface-test-strategy.md
@@ -87,7 +87,7 @@
 * This must be done for each possible flow, including error cases (e.g. a key creation that fails midway due to `OUT_OF_MEMORY`).
 * The recovery during `psa_crypto_init` can itself be interrupted. Test those interruptions too.
 * Two things need to be tested: the key that is being created or destroyed, and the driver's persistent storage.
-* Check both that the storage has the expected content (this can be done by e.g. using a key that is supposed to be present) and does not have any unexpected content (for keys, this can be done by checking that `psa_open_key` fails with `PSA_ERRROR_DOES_NOT_EXIST`).
+* Check both that the storage has the expected content (this can be done by e.g. using a key that is supposed to be present) and does not have any unexpected content (for keys, this can be done by checking that `psa_open_key` fails with `PSA_ERROR_DOES_NOT_EXIST`).
 
 This requires instrumenting the storage implementation, either to force it to fail at each point or to record successive storage states and replay each of them. Each `psa_its_xxx` function call is assumed to be atomic.
 
diff --git a/docs/architecture/testing/psa-storage-format-testing.md b/docs/architecture/testing/psa-storage-format-testing.md
index 0e20a8b..5514dfa 100644
--- a/docs/architecture/testing/psa-storage-format-testing.md
+++ b/docs/architecture/testing/psa-storage-format-testing.md
@@ -40,7 +40,7 @@
 
 ## Storage architecture overview
 
-The PSA subsystem provides storage on top of the PSA trusted storage interface. The state of the storage is a mapping from file identifer (a 64-bit number) to file content (a byte array). These files include:
+The PSA subsystem provides storage on top of the PSA trusted storage interface. The state of the storage is a mapping from file identifier (a 64-bit number) to file content (a byte array). These files include:
 
 * [Key files](#key-storage) (files containing one key's metadata and, except for some secure element keys, key material).
 * The [random generator injected seed or state file](#random-generator-state) (`PSA_CRYPTO_ITS_RANDOM_SEED_UID`).
diff --git a/include/mbedtls/aes.h b/include/mbedtls/aes.h
index e381c11..144bd89 100644
--- a/include/mbedtls/aes.h
+++ b/include/mbedtls/aes.h
@@ -553,7 +553,7 @@
  *             for example, with 96-bit random nonces, you should not encrypt
  *             more than 2**32 messages with the same key.
  *
- *             Note that for both stategies, sizes are measured in blocks and
+ *             Note that for both strategies, sizes are measured in blocks and
  *             that an AES block is 16 bytes.
  *
  * \warning    Upon return, \p stream_block contains sensitive data. Its
diff --git a/include/mbedtls/aria.h b/include/mbedtls/aria.h
index 1a96d15..71540c8 100644
--- a/include/mbedtls/aria.h
+++ b/include/mbedtls/aria.h
@@ -41,7 +41,7 @@
 #define MBEDTLS_ARIA_DECRYPT     0 /**< ARIA decryption. */
 
 #define MBEDTLS_ARIA_BLOCKSIZE   16 /**< ARIA block size in bytes. */
-#define MBEDTLS_ARIA_MAX_ROUNDS  16 /**< Maxiumum number of rounds in ARIA. */
+#define MBEDTLS_ARIA_MAX_ROUNDS  16 /**< Maximum number of rounds in ARIA. */
 #define MBEDTLS_ARIA_MAX_KEYSIZE 32 /**< Maximum size of an ARIA key in bytes. */
 
 /** Bad input data. */
@@ -306,7 +306,7 @@
  *             for example, with 96-bit random nonces, you should not encrypt
  *             more than 2**32 messages with the same key.
  *
- *             Note that for both stategies, sizes are measured in blocks and
+ *             Note that for both strategies, sizes are measured in blocks and
  *             that an ARIA block is 16 bytes.
  *
  * \warning    Upon return, \p stream_block contains sensitive data. Its
diff --git a/include/mbedtls/asn1.h b/include/mbedtls/asn1.h
index 30b0ed2..be2cae7 100644
--- a/include/mbedtls/asn1.h
+++ b/include/mbedtls/asn1.h
@@ -228,7 +228,7 @@
  * \return      0 if successful.
  * \return      #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element
  *              would end beyond \p end.
- * \return      #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparseable.
+ * \return      #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparsable.
  */
 int mbedtls_asn1_get_len( unsigned char **p,
                           const unsigned char *end,
@@ -253,7 +253,7 @@
  *              with the requested tag.
  * \return      #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element
  *              would end beyond \p end.
- * \return      #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparseable.
+ * \return      #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparsable.
  */
 int mbedtls_asn1_get_tag( unsigned char **p,
                           const unsigned char *end,
diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h
index 45d3119..5277f56 100644
--- a/include/mbedtls/bignum.h
+++ b/include/mbedtls/bignum.h
@@ -955,7 +955,7 @@
  *                 generate yourself and that are supposed to be prime, then
  *                 \p rounds should be at least the half of the security
  *                 strength of the cryptographic algorithm. On the other hand,
- *                 if \p X is chosen uniformly or non-adversially (as is the
+ *                 if \p X is chosen uniformly or non-adversarially (as is the
  *                 case when mbedtls_mpi_gen_prime calls this function), then
  *                 \p rounds can be much lower.
  *
diff --git a/include/mbedtls/camellia.h b/include/mbedtls/camellia.h
index 6feeaf0..6b0a871 100644
--- a/include/mbedtls/camellia.h
+++ b/include/mbedtls/camellia.h
@@ -262,7 +262,7 @@
  *             encrypted: for example, with 96-bit random nonces, you should
  *             not encrypt more than 2**32 messages with the same key.
  *
- *             Note that for both stategies, sizes are measured in blocks and
+ *             Note that for both strategies, sizes are measured in blocks and
  *             that a CAMELLIA block is \c 16 Bytes.
  *
  * \warning    Upon return, \p stream_block contains sensitive data. Its
diff --git a/include/mbedtls/chachapoly.h b/include/mbedtls/chachapoly.h
index 3f4318f..2b49402 100644
--- a/include/mbedtls/chachapoly.h
+++ b/include/mbedtls/chachapoly.h
@@ -158,7 +158,7 @@
  * \param ctx       The ChaCha20-Poly1305 context. This must be initialized
  *                  and bound to a key.
  * \param nonce     The nonce/IV to use for the message.
- *                  This must be a redable buffer of length \c 12 Bytes.
+ *                  This must be a readable buffer of length \c 12 Bytes.
  * \param mode      The operation to perform: #MBEDTLS_CHACHAPOLY_ENCRYPT or
  *                  #MBEDTLS_CHACHAPOLY_DECRYPT (discouraged, see warning).
  *
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 1ced6e5..bdc32e1 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -76,7 +76,7 @@
 #endif
 
 #if defined(MBEDTLS_CMAC_C) && \
-    !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C)
+    ( !defined(MBEDTLS_CIPHER_C ) || ( !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C) ) )
 #error "MBEDTLS_CMAC_C defined, but not all prerequisites"
 #endif
 
@@ -146,11 +146,28 @@
 #endif
 
 #if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_ASN1_PARSE_C)
-#error "MBEDTLS_PK_PARSE_C defined, but not all prerequesites"
+#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites"
 #endif
 
-#if defined(MBEDTLS_PKCS5_C) && !defined(MBEDTLS_MD_C)
-#error "MBEDTLS_PKCS5_C defined, but not all prerequesites"
+#if defined(MBEDTLS_PKCS12_C) && !defined(MBEDTLS_CIPHER_C)
+#error "MBEDTLS_PKCS12_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PKCS5_C) && (!defined(MBEDTLS_MD_C) || \
+                                 !defined(MBEDTLS_CIPHER_C))
+#error "MBEDTLS_PKCS5_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PKCS12_C) && !defined(MBEDTLS_MD_C)
+#error "MBEDTLS_PKCS12_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PKCS1_V15) && !defined(MBEDTLS_MD_C)
+#error "MBEDTLS_PKCS1_V15 defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PKCS1_V21) && !defined(MBEDTLS_MD_C)
+#error "MBEDTLS_PKCS1_V21 defined, but not all prerequisites"
 #endif
 
 #if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) &&      \
@@ -322,11 +339,11 @@
 #endif
 
 #if defined(MBEDTLS_MEMORY_BACKTRACE) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
-#error "MBEDTLS_MEMORY_BACKTRACE defined, but not all prerequesites"
+#error "MBEDTLS_MEMORY_BACKTRACE defined, but not all prerequisites"
 #endif
 
 #if defined(MBEDTLS_MEMORY_DEBUG) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
-#error "MBEDTLS_MEMORY_DEBUG defined, but not all prerequesites"
+#error "MBEDTLS_MEMORY_DEBUG defined, but not all prerequisites"
 #endif
 
 #if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM)
@@ -342,7 +359,7 @@
 #endif
 
 #if defined(MBEDTLS_PK_C) && \
-    ( !defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_C) )
+    ( !defined(MBEDTLS_MD_C) || ( !defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_C) ) )
 #error "MBEDTLS_PK_C defined, but not all prerequisites"
 #endif
 
@@ -550,6 +567,10 @@
 #error "MBEDTLS_PSA_CRYPTO_C defined, but not all prerequisites (missing RNG)"
 #endif
 
+#if defined(MBEDTLS_PSA_CRYPTO_C) && !defined(MBEDTLS_CIPHER_C )
+#error "MBEDTLS_PSA_CRYPTO_C defined, but not all prerequisites"
+#endif
+
 #if defined(MBEDTLS_PSA_CRYPTO_SPM) && !defined(MBEDTLS_PSA_CRYPTO_C)
 #error "MBEDTLS_PSA_CRYPTO_SPM defined, but not all prerequisites"
 #endif
@@ -780,15 +801,16 @@
 
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) &&   \
     !defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequsites"
+#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequisites"
 #endif
 
 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \
     !defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequsites"
+#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequisites"
 #endif
 
-#if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C)
+#if defined(MBEDTLS_SSL_TICKET_C) && ( !defined(MBEDTLS_CIPHER_C) && \
+                                       !defined(MBEDTLS_USE_PSA_CRYPTO) )
 #error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites"
 #endif
 
diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h
index 9545cd9..a3f52ea 100644
--- a/include/mbedtls/cipher.h
+++ b/include/mbedtls/cipher.h
@@ -850,6 +850,12 @@
  * \note            Some ciphers do not use IVs nor nonce. For these
  *                  ciphers, this function has no effect.
  *
+ * \note            For #MBEDTLS_CIPHER_CHACHA20, the nonce length must
+ *                  be 12, and the initial counter value is 0.
+ *
+ * \note            For #MBEDTLS_CIPHER_CHACHA20_POLY1305, the nonce length
+ *                  must be 12.
+ *
  * \param ctx       The generic cipher context. This must be initialized and
  *                  bound to a cipher information structure.
  * \param iv        The IV to use, or NONCE_COUNTER for CTR-mode ciphers. This
diff --git a/include/mbedtls/debug.h b/include/mbedtls/debug.h
index 0aed596..5c8aba8 100644
--- a/include/mbedtls/debug.h
+++ b/include/mbedtls/debug.h
@@ -139,7 +139,7 @@
  *          discarded.
  *          (Default value: 0 = No debug )
  *
- * \param threshold     theshold level of messages to filter on. Messages at a
+ * \param threshold     threshold level of messages to filter on. Messages at a
  *                      higher level will be discarded.
  *                          - Debug levels
  *                              - 0 No debug
diff --git a/include/mbedtls/ecjpake.h b/include/mbedtls/ecjpake.h
index a73f624..7853a6a 100644
--- a/include/mbedtls/ecjpake.h
+++ b/include/mbedtls/ecjpake.h
@@ -65,7 +65,7 @@
  * (KeyExchange) as defined by the Thread spec.
  *
  * In order to benefit from this symmetry, we choose a different naming
- * convetion from the Thread v1.0 spec. Correspondance is indicated in the
+ * convention from the Thread v1.0 spec. Correspondence is indicated in the
  * description as a pair C: client name, S: server name
  */
 typedef struct mbedtls_ecjpake_context
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index 395db14..ac8b7c0 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -262,7 +262,7 @@
 #if !defined(MBEDTLS_ECP_WINDOW_SIZE)
 /*
  * Maximum "window" size used for point multiplication.
- * Default: a point where higher memory usage yields disminishing performance
+ * Default: a point where higher memory usage yields diminishing performance
  *          returns.
  * Minimum value: 2. Maximum value: 7.
  *
diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h
index 37702b5..f2cf2c0 100644
--- a/include/mbedtls/hmac_drbg.h
+++ b/include/mbedtls/hmac_drbg.h
@@ -204,7 +204,7 @@
                     size_t len );
 
 /**
- * \brief               Initilisation of simpified HMAC_DRBG (never reseeds).
+ * \brief               Initialisation of simplified HMAC_DRBG (never reseeds).
  *
  * This function is meant for use in algorithms that need a pseudorandom
  * input such as deterministic ECDSA.
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index 2d32f67..9c8ec11 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -25,7 +25,7 @@
  */
 
 /**
- * This is an optional version symbol that enables comatibility handling of
+ * This is an optional version symbol that enables compatibility handling of
  * config files.
  *
  * It is equal to the #MBEDTLS_VERSION_NUMBER of the Mbed TLS version that
@@ -330,7 +330,7 @@
 //#define MBEDTLS_SHA512_ALT
 
 /*
- * When replacing the elliptic curve module, pleace consider, that it is
+ * When replacing the elliptic curve module, please consider, that it is
  * implemented with two .c files:
  *      - ecp.c
  *      - ecp_curves.c
@@ -1129,7 +1129,7 @@
  *
  * Enable support for PKCS#1 v1.5 encoding.
  *
- * Requires: MBEDTLS_RSA_C
+ * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C
  *
  * This enables support for PKCS#1 v1.5 operations.
  */
@@ -1416,7 +1416,7 @@
  * Enable support for RFC 7627: Session Hash and Extended Master Secret
  * Extension.
  *
- * This was introduced as "the proper fix" to the Triple Handshake familiy of
+ * This was introduced as "the proper fix" to the Triple Handshake family of
  * attacks, but it is recommended to always use it (even if you disable
  * renegotiation), since it actually fixes a more fundamental issue in the
  * original SSL/TLS design, and has implications beyond Triple Handshake.
@@ -1442,7 +1442,7 @@
  * \note This option has no influence on the protection against the
  *       triple handshake attack. Even if it is disabled, Mbed TLS will
  *       still ensure that certificates do not change during renegotiation,
- *       for exaple by keeping a hash of the peer's certificate.
+ *       for example by keeping a hash of the peer's certificate.
  *
  * Comment this macro to disable storing the peer's certificate
  * after the handshake.
@@ -1576,7 +1576,7 @@
  * unless you know for sure amplification cannot be a problem in the
  * environment in which your server operates.
  *
- * \warning Disabling this can ba a security risk! (see above)
+ * \warning Disabling this can be a security risk! (see above)
  *
  * Requires: MBEDTLS_SSL_PROTO_DTLS
  *
@@ -2115,7 +2115,8 @@
  *
  * Module:  library/ccm.c
  *
- * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C
+ * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or
+ *                             MBEDTLS_ARIA_C
  *
  * This module enables the AES-CCM ciphersuites, if other requisites are
  * enabled as well.
@@ -2148,7 +2149,17 @@
  * Enable the generic cipher layer.
  *
  * Module:  library/cipher.c
- * Caller:  library/ssl_tls.c
+ * Caller:  library/ccm.c
+ *          library/cmac.c
+ *          library/gcm.c
+ *          library/nist_kw.c
+ *          library/pkcs12.c
+ *          library/pkcs5.c
+ *          library/psa_crypto_aead.c
+ *          library/psa_crypto_mac.c
+ *          library/ssl_ciphersuites.c
+ *          library/ssl_msg.c
+ *          library/ssl_ticket.c (unless MBEDTLS_USE_PSA_CRYPTO is enabled)
  *
  * Uncomment to enable generic cipher wrappers.
  */
@@ -2167,7 +2178,7 @@
  *
  * Module:  library/cmac.c
  *
- * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C
+ * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_DES_C
  *
  */
 #define MBEDTLS_CMAC_C
@@ -2346,7 +2357,8 @@
  *
  * Module:  library/gcm.c
  *
- * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or MBEDTLS_ARIA_C
+ * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or
+ *                             MBEDTLS_ARIA_C
  *
  * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other
  * requisites are enabled as well.
@@ -2378,7 +2390,7 @@
  *
  * Requires: MBEDTLS_MD_C
  *
- * Uncomment to enable the HMAC_DRBG random number geerator.
+ * Uncomment to enable the HMAC_DRBG random number generator.
  */
 #define MBEDTLS_HMAC_DRBG_C
 
@@ -2401,7 +2413,24 @@
  * Enable the generic message digest layer.
  *
  * Module:  library/md.c
- * Caller:
+ * Caller:  library/constant_time.c
+ *          library/ecdsa.c
+ *          library/ecjpake.c
+ *          library/hkdf.c
+ *          library/hmac_drbg.c
+ *          library/pk.c
+ *          library/pkcs5.c
+ *          library/pkcs12.c
+ *          library/psa_crypto_ecp.c
+ *          library/psa_crypto_rsa.c
+ *          library/rsa.c
+ *          library/ssl_cookie.c
+ *          library/ssl_msg.c
+ *          library/ssl_tls.c
+ *          library/x509.c
+ *          library/x509_crt.c
+ *          library/x509write_crt.c
+ *          library/x509write_csr.c
  *
  * Uncomment to enable generic message digest wrappers.
  */
@@ -2537,7 +2566,7 @@
 /**
  * \def MBEDTLS_PK_C
  *
- * Enable the generic public (asymetric) key layer.
+ * Enable the generic public (asymmetric) key layer.
  *
  * Module:  library/pk.c
  * Caller:  library/psa_crypto_rsa.c
@@ -2546,7 +2575,7 @@
  *          library/ssl*_server.c
  *          library/x509.c
  *
- * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C
+ * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C or MBEDTLS_ECP_C
  *
  * Uncomment to enable generic public key wrappers.
  */
@@ -2555,7 +2584,7 @@
 /**
  * \def MBEDTLS_PK_PARSE_C
  *
- * Enable the generic public (asymetric) key parser.
+ * Enable the generic public (asymmetric) key parser.
  *
  * Module:  library/pkparse.c
  * Caller:  library/x509_crt.c
@@ -2570,7 +2599,7 @@
 /**
  * \def MBEDTLS_PK_WRITE_C
  *
- * Enable the generic public (asymetric) key writer.
+ * Enable the generic public (asymmetric) key writer.
  *
  * Module:  library/pkwrite.c
  * Caller:  library/x509write.c
@@ -2588,7 +2617,7 @@
  *
  * Module:  library/pkcs5.c
  *
- * Requires: MBEDTLS_MD_C
+ * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C
  *
  * This module adds support for the PKCS#5 functions.
  */
@@ -2646,7 +2675,8 @@
  *
  * Module:  library/psa_crypto.c
  *
- * Requires: either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C,
+ * Requires: MBEDTLS_CIPHER_C,
+ *           either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C,
  *           or MBEDTLS_HMAC_DRBG_C and MBEDTLS_ENTROPY_C,
  *           or MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG.
  *
@@ -2947,7 +2977,7 @@
  * Module:  library/ssl_ticket.c
  * Caller:
  *
- * Requires: MBEDTLS_CIPHER_C
+ * Requires: MBEDTLS_CIPHER_C || MBEDTLS_USE_PSA_CRYPTO
  */
 #define MBEDTLS_SSL_TICKET_C
 
diff --git a/include/mbedtls/oid.h b/include/mbedtls/oid.h
index 836e455..a031fe2 100644
--- a/include/mbedtls/oid.h
+++ b/include/mbedtls/oid.h
@@ -140,7 +140,7 @@
 #define MBEDTLS_OID_AT_GIVEN_NAME               MBEDTLS_OID_AT "\x2A" /**< id-at-givenName AttributeType:= {id-at 42} */
 #define MBEDTLS_OID_AT_INITIALS                 MBEDTLS_OID_AT "\x2B" /**< id-at-initials AttributeType:= {id-at 43} */
 #define MBEDTLS_OID_AT_GENERATION_QUALIFIER     MBEDTLS_OID_AT "\x2C" /**< id-at-generationQualifier AttributeType:= {id-at 44} */
-#define MBEDTLS_OID_AT_UNIQUE_IDENTIFIER        MBEDTLS_OID_AT "\x2D" /**< id-at-uniqueIdentifier AttributType:= {id-at 45} */
+#define MBEDTLS_OID_AT_UNIQUE_IDENTIFIER        MBEDTLS_OID_AT "\x2D" /**< id-at-uniqueIdentifier AttributeType:= {id-at 45} */
 #define MBEDTLS_OID_AT_DN_QUALIFIER             MBEDTLS_OID_AT "\x2E" /**< id-at-dnQualifier AttributeType:= {id-at 46} */
 #define MBEDTLS_OID_AT_PSEUDONYM                MBEDTLS_OID_AT "\x41" /**< id-at-pseudonym AttributeType:= {id-at 65} */
 
diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h
index 5225c57..207aed0 100644
--- a/include/mbedtls/pk.h
+++ b/include/mbedtls/pk.h
@@ -411,6 +411,38 @@
  */
 int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type );
 
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/**
+ * \brief           Tell if context can do the operation given by PSA algorithm
+ *
+ * \param ctx       The context to query. It must have been initialized.
+ * \param alg       PSA algorithm to check against, the following are allowed:
+ *                  PSA_ALG_RSA_PKCS1V15_SIGN(hash),
+ *                  PSA_ALG_RSA_PSS(hash),
+ *                  PSA_ALG_RSA_PKCS1V15_CRYPT,
+ *                  PSA_ALG_ECDSA(hash),
+ *                  PSA_ALG_ECDH, where hash is a specific hash.
+ * \param usage  PSA usage flag to check against, must be composed of:
+ *                  PSA_KEY_USAGE_SIGN_HASH
+ *                  PSA_KEY_USAGE_DECRYPT
+ *                  PSA_KEY_USAGE_DERIVE.
+ *                  Context key must match all passed usage flags.
+ *
+ * \warning         Since the set of allowed algorithms and usage flags may be
+ *                  expanded in the future, the return value \c 0 should not
+ *                  be taken in account for non-allowed algorithms and usage
+ *                  flags.
+ *
+ * \return          1 if the context can do operations on the given type.
+ * \return          0 if the context cannot do the operations on the given
+ *                  type, for non-allowed algorithms and usage flags, or
+ *                  for a context that has been initialized but not set up
+ *                  or that has been cleared with mbedtls_pk_free().
+ */
+int mbedtls_pk_can_do_ext( const mbedtls_pk_context *ctx, psa_algorithm_t alg,
+                           psa_key_usage_t usage );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
 /**
  * \brief           Verify signature (including padding if relevant).
  *
diff --git a/include/mbedtls/platform_util.h b/include/mbedtls/platform_util.h
index 5d2fefc..ecd36da 100644
--- a/include/mbedtls/platform_util.h
+++ b/include/mbedtls/platform_util.h
@@ -122,7 +122,7 @@
  *
  * This macro has an empty expansion. It exists for documentation purposes:
  * a #MBEDTLS_CHECK_RETURN_OPTIONAL annotation indicates that the function
- * has been analyzed for return-check usefuless, whereas the lack of
+ * has been analyzed for return-check usefulness, whereas the lack of
  * an annotation indicates that the function has not been analyzed and its
  * return-check usefulness is unknown.
  */
diff --git a/include/mbedtls/private_access.h b/include/mbedtls/private_access.h
index 98d3419..85461f6 100644
--- a/include/mbedtls/private_access.h
+++ b/include/mbedtls/private_access.h
@@ -1,7 +1,7 @@
  /**
  * \file private_access.h
  *
- * \brief Macro wrapper for struct's memebrs.
+ * \brief Macro wrapper for struct's members.
  */
 /*
  *  Copyright The Mbed TLS Contributors
diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h
index d03c31d..e43ef96 100644
--- a/include/mbedtls/rsa.h
+++ b/include/mbedtls/rsa.h
@@ -74,7 +74,7 @@
 
 /*
  * The above constants may be used even if the RSA module is compile out,
- * eg for alternative (PKCS#11) RSA implemenations in the PK layers.
+ * eg for alternative (PKCS#11) RSA implementations in the PK layers.
  */
 
 #ifdef __cplusplus
@@ -540,7 +540,7 @@
  *
  * \note           Blinding is used if and only if a PRNG is provided.
  *
- * \note           If blinding is used, both the base of exponentation
+ * \note           If blinding is used, both the base of exponentiation
  *                 and the exponent are blinded, providing protection
  *                 against some side-channel attacks.
  *
@@ -634,7 +634,7 @@
  * \note             The output buffer must be as large as the size
  *                   of ctx->N. For example, 128 Bytes if RSA-1024 is used.
  *
- * \param ctx        The initnialized RSA context to use.
+ * \param ctx        The initialized RSA context to use.
  * \param f_rng      The RNG function to use. This is needed for padding
  *                   generation and is mandatory.
  * \param p_rng      The RNG context to be passed to \p f_rng. This may
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 6dac3d1..0a99693 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -492,6 +492,7 @@
 #define MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT      110  /* 0x6E */
 #define MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME    112  /* 0x70 */
 #define MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY 115  /* 0x73 */
+#define MBEDTLS_SSL_ALERT_MSG_CERT_REQUIRED        116  /* 0x74 */
 #define MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL 120 /* 0x78 */
 
 #define MBEDTLS_SSL_HS_HELLO_REQUEST            0
@@ -1357,7 +1358,7 @@
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
-    /** Callback to create & write a cookie for ClientHello veirifcation    */
+    /** Callback to create & write a cookie for ClientHello verification    */
     int (*MBEDTLS_PRIVATE(f_cookie_write))( void *, unsigned char **, unsigned char *,
                            const unsigned char *, size_t );
     /** Callback to verify validity of a ClientHello cookie                 */
@@ -1428,7 +1429,6 @@
                               *   configured, this has value \c 0.
                               */
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
-
     unsigned char *MBEDTLS_PRIVATE(psk);      /*!< The raw pre-shared key. This field should
                               *   only be set via mbedtls_ssl_conf_psk().
                               *   If either no PSK or an opaque PSK
@@ -1939,7 +1939,7 @@
  *
  * \note           The two most common use cases are:
  *                 - non-blocking I/O, f_recv != NULL, f_recv_timeout == NULL
- *                 - blocking I/O, f_recv == NULL, f_recv_timout != NULL
+ *                 - blocking I/O, f_recv == NULL, f_recv_timeout != NULL
  *
  * \note           For DTLS, you need to provide either a non-NULL
  *                 f_recv_timeout callback, or a f_recv that doesn't block.
@@ -2131,7 +2131,7 @@
 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
 
 /**
- * \brief          Set the Maximum Tranport Unit (MTU).
+ * \brief          Set the Maximum Transport Unit (MTU).
  *                 Special value: 0 means unset (no limit).
  *                 This represents the maximum size of a datagram payload
  *                 handled by the transport layer (usually UDP) as determined
@@ -2736,7 +2736,7 @@
  *                 ones going through the authentication-decryption phase.
  *
  * \note           This is a security trade-off related to the fact that it's
- *                 often relatively easy for an active attacker ot inject UDP
+ *                 often relatively easy for an active attacker to inject UDP
  *                 datagrams. On one hand, setting a low limit here makes it
  *                 easier for such an attacker to forcibly terminated a
  *                 connection. On the other hand, a high limit or no limit
@@ -2846,7 +2846,7 @@
  *                 successfully cached, return 1 otherwise.
  *
  * \param conf           SSL configuration
- * \param p_cache        parmater (context) for both callbacks
+ * \param p_cache        parameter (context) for both callbacks
  * \param f_get_cache    session get callback
  * \param f_set_cache    session set callback
  */
@@ -2908,7 +2908,7 @@
 /**
  * \brief          Load serialized session data into a session structure.
  *                 On client, this can be used for loading saved sessions
- *                 before resuming them with mbedstls_ssl_set_session().
+ *                 before resuming them with mbedtls_ssl_set_session().
  *                 On server, this can be used for alternative implementations
  *                 of session cache or session tickets.
  *
@@ -3204,7 +3204,7 @@
  *
  * \note           On client, only the first call has any effect. That is,
  *                 only one client certificate can be provisioned. The
- *                 server's preferences in its CertficateRequest message will
+ *                 server's preferences in its CertificateRequest message will
  *                 be ignored and our only cert will be sent regardless of
  *                 whether it matches those preferences - the server can then
  *                 decide what it wants to do with it.
@@ -3455,7 +3455,7 @@
  *                 Both sides: limits the set of curves accepted for use in
  *                 ECDHE and in the peer's end-entity certificate.
  *
- * \deprecated     Superseeded by mbedtls_ssl_conf_groups().
+ * \deprecated     Superseded by mbedtls_ssl_conf_groups().
  *
  * \note           This has no influence on which curves are allowed inside the
  *                 certificate chains, see \c mbedtls_ssl_conf_cert_profile()
@@ -3726,7 +3726,7 @@
  * \param protos   Pointer to a NULL-terminated list of supported protocols,
  *                 in decreasing preference order. The pointer to the list is
  *                 recorded by the library for later reference as required, so
- *                 the lifetime of the table must be atleast as long as the
+ *                 the lifetime of the table must be at least as long as the
  *                 lifetime of the SSL configuration structure.
  *
  * \return         0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA.
@@ -3740,7 +3740,7 @@
  *
  * \param ssl      SSL context
  *
- * \return         Protcol name, or NULL if no protocol was negotiated.
+ * \return         Protocol name, or NULL if no protocol was negotiated.
  */
 const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl );
 #endif /* MBEDTLS_SSL_ALPN */
@@ -3823,7 +3823,7 @@
                                          unsigned char *mki_value,
                                          uint16_t mki_len );
 /**
- * \brief                  Get the negotiated DTLS-SRTP informations:
+ * \brief                  Get the negotiated DTLS-SRTP information:
  *                         Protection profile and MKI value.
  *
  * \warning                This function must be called after the handshake is
@@ -3831,7 +3831,7 @@
  *                         not be trusted or acted upon before the handshake completes.
  *
  * \param ssl              The SSL context to query.
- * \param dtls_srtp_info   The negotiated DTLS-SRTP informations:
+ * \param dtls_srtp_info   The negotiated DTLS-SRTP information:
  *                         - Protection profile in use.
  *                         A direct mapping of the iana defined value for protection
  *                         profile on an uint16_t.
@@ -4008,7 +4008,7 @@
  *                 \c mbedtls_ssl_get_record_expansion().
  *
  * \note           For DTLS, it is also possible to set a limit for the total
- *                 size of daragrams passed to the transport layer, including
+ *                 size of datagrams passed to the transport layer, including
  *                 record overhead, see \c mbedtls_ssl_set_mtu().
  *
  * \param conf     SSL configuration
@@ -4054,7 +4054,7 @@
  *                 initiated by peer
  *                 (Default: MBEDTLS_SSL_RENEGOTIATION_DISABLED)
  *
- * \warning        It is recommended to always disable renegotation unless you
+ * \warning        It is recommended to always disable renegotiation unless you
  *                 know you need it and you know what you're doing. In the
  *                 past, there have been several issues associated with
  *                 renegotiation or a poor understanding of its properties.
@@ -4117,7 +4117,7 @@
  *                 scenario.
  *
  * \note           With DTLS and server-initiated renegotiation, the
- *                 HelloRequest is retransmited every time mbedtls_ssl_read() times
+ *                 HelloRequest is retransmitted every time mbedtls_ssl_read() times
  *                 out or receives Application Data, until:
  *                 - max_records records have beens seen, if it is >= 0, or
  *                 - the number of retransmits that would happen during an
@@ -4776,7 +4776,7 @@
  * \return         \c 0 if successful.
  * \return         #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if \p buf is too small.
  * \return         #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed
- *                 while reseting the context.
+ *                 while resetting the context.
  * \return         #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if a handshake is in
  *                 progress, or there is pending data for reading or sending,
  *                 or the connection does not use DTLS 1.2 with an AEAD
diff --git a/include/mbedtls/ssl_cookie.h b/include/mbedtls/ssl_cookie.h
index c5b80d9..a1ca74b 100644
--- a/include/mbedtls/ssl_cookie.h
+++ b/include/mbedtls/ssl_cookie.h
@@ -90,7 +90,7 @@
  * \brief          Set expiration delay for cookies
  *                 (Default MBEDTLS_SSL_COOKIE_TIMEOUT)
  *
- * \param ctx      Cookie contex
+ * \param ctx      Cookie context
  * \param delay    Delay, in seconds if HAVE_TIME, or in number of cookies
  *                 issued in the meantime.
  *                 0 to disable expiration (NOT recommended)
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index 51ce257..3e331d4 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -114,7 +114,7 @@
 typedef struct mbedtls_x509_san_other_name
 {
     /**
-     * The type_id is an OID as deifned in RFC 5280.
+     * The type_id is an OID as defined in RFC 5280.
      * To check the value of the type id, you should use
      * \p MBEDTLS_OID_CMP with a known OID mbedtls_x509_buf.
      */
@@ -968,7 +968,7 @@
 void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx );
 
 /**
- * \brief           Set the verion for a Certificate
+ * \brief           Set the version for a Certificate
  *                  Default: MBEDTLS_X509_CRT_VERSION_3
  *
  * \param ctx       CRT context to use
@@ -1084,7 +1084,7 @@
  * \param is_ca     is this a CA certificate
  * \param max_pathlen   maximum length of certificate chains below this
  *                      certificate (only for CA certificates, -1 is
- *                      inlimited)
+ *                      unlimited)
  *
  * \return          0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED
  */
diff --git a/include/mbedtls/x509_csr.h b/include/mbedtls/x509_csr.h
index 20a516e..44b7aab 100644
--- a/include/mbedtls/x509_csr.h
+++ b/include/mbedtls/x509_csr.h
@@ -184,7 +184,7 @@
  *                  private key used to sign the CSR when writing it)
  *
  * \param ctx       CSR context to use
- * \param key       Asymetric key to include
+ * \param key       Asymmetric key to include
  */
 void mbedtls_x509write_csr_set_key( mbedtls_x509write_csr *ctx, mbedtls_pk_context *key );
 
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 5f4a9be..211ea8a 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -1023,7 +1023,7 @@
  * This function calculates the hash of the message formed by concatenating
  * the inputs passed to preceding calls to psa_hash_update().
  *
- * When this function returns successfuly, the operation becomes inactive.
+ * When this function returns successfully, the operation becomes inactive.
  * If this function returns an error status, the operation enters an error
  * state and must be aborted by calling psa_hash_abort().
  *
@@ -1073,7 +1073,7 @@
  * compares the calculated hash with the expected hash passed as a
  * parameter to this function.
  *
- * When this function returns successfuly, the operation becomes inactive.
+ * When this function returns successfully, the operation becomes inactive.
  * If this function returns an error status, the operation enters an error
  * state and must be aborted by calling psa_hash_abort().
  *
@@ -1458,7 +1458,7 @@
  * This function calculates the MAC of the message formed by concatenating
  * the inputs passed to preceding calls to psa_mac_update().
  *
- * When this function returns successfuly, the operation becomes inactive.
+ * When this function returns successfully, the operation becomes inactive.
  * If this function returns an error status, the operation enters an error
  * state and must be aborted by calling psa_mac_abort().
  *
@@ -1511,7 +1511,7 @@
  * compares the calculated MAC with the expected MAC passed as a
  * parameter to this function.
  *
- * When this function returns successfuly, the operation becomes inactive.
+ * When this function returns successfully, the operation becomes inactive.
  * If this function returns an error status, the operation enters an error
  * state and must be aborted by calling psa_mac_abort().
  *
@@ -1971,7 +1971,7 @@
  * formed by concatenating the inputs passed to preceding calls to
  * psa_cipher_update().
  *
- * When this function returns successfuly, the operation becomes inactive.
+ * When this function returns successfully, the operation becomes inactive.
  * If this function returns an error status, the operation enters an error
  * state and must be aborted by calling psa_cipher_abort().
  *
@@ -2638,7 +2638,7 @@
  *   preceding calls to psa_aead_update().
  * - \p tag contains the authentication tag.
  *
- * When this function returns successfuly, the operation becomes inactive.
+ * When this function returns successfully, the operation becomes inactive.
  * If this function returns an error status, the operation enters an error
  * state and must be aborted by calling psa_aead_abort().
  *
@@ -2728,7 +2728,7 @@
  * plaintext and reports success. If the authentication tag is not correct,
  * this function returns #PSA_ERROR_INVALID_SIGNATURE.
  *
- * When this function returns successfuly, the operation becomes inactive.
+ * When this function returns successfully, the operation becomes inactive.
  * If this function returns an error status, the operation enters an error
  * state and must be aborted by calling psa_aead_abort().
  *
@@ -3026,7 +3026,7 @@
  * \retval #PSA_ERROR_INVALID_HANDLE
  * \retval #PSA_ERROR_NOT_PERMITTED
  * \retval #PSA_ERROR_INVALID_SIGNATURE
- *         The calculation was perfomed successfully, but the passed
+ *         The calculation was performed successfully, but the passed
  *         signature is not a valid signature.
  * \retval #PSA_ERROR_NOT_SUPPORTED
  * \retval #PSA_ERROR_INVALID_ARGUMENT
@@ -3050,7 +3050,7 @@
 /**
  * \brief Encrypt a short message with a public key.
  *
- * \param key                   Identifer of the key to use for the operation.
+ * \param key                   Identifier of the key to use for the operation.
  *                              It must be a public key or an asymmetric key
  *                              pair. It must allow the usage
  *                              #PSA_KEY_USAGE_ENCRYPT.
@@ -3783,7 +3783,7 @@
  *
  * \param[in,out] operation The key derivation operation object to read from.
  * \param[in] expected_output Buffer containing the expected derivation output.
- * \param output_length     Length ot the expected output; this is also the
+ * \param output_length     Length of the expected output; this is also the
  *                          number of bytes that will be read.
  *
  * \retval #PSA_SUCCESS
diff --git a/include/psa/crypto_config.h b/include/psa/crypto_config.h
index 46cf126..e437750 100644
--- a/include/psa/crypto_config.h
+++ b/include/psa/crypto_config.h
@@ -60,7 +60,6 @@
 #define PSA_WANT_ALG_CMAC                       1
 #define PSA_WANT_ALG_CFB                        1
 #define PSA_WANT_ALG_CHACHA20_POLY1305          1
-#define PSA_WANT_ALG_CMAC                       1
 #define PSA_WANT_ALG_CTR                        1
 #define PSA_WANT_ALG_DETERMINISTIC_ECDSA        1
 #define PSA_WANT_ALG_ECB_NO_PADDING             1
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index df28fef..73da364 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -348,7 +348,7 @@
  * length of the byte string is the private key size in bytes (leading zeroes
  * are not stripped).
  *
- * Determinstic DSA key derivation with psa_generate_derived_key follows
+ * Deterministic DSA key derivation with psa_generate_derived_key follows
  * FIPS 186-4 &sect;B.1.2: interpret the byte string as integer
  * in big-endian order. Discard it if it is not in the range
  * [0, *N* - 2] where *N* is the boundary of the private key domain
@@ -448,9 +448,9 @@
  *   As an exception, the public exponent 65537 is represented by an empty
  *   byte string.
  * - For DSA keys (#PSA_KEY_TYPE_DSA_PUBLIC_KEY or #PSA_KEY_TYPE_DSA_KEY_PAIR),
- *   the `Dss-Parms` format as defined by RFC 3279 &sect;2.3.2.
+ *   the `Dss-Params` format as defined by RFC 3279 &sect;2.3.2.
  *   ```
- *   Dss-Parms ::= SEQUENCE  {
+ *   Dss-Params ::= SEQUENCE  {
  *      p       INTEGER,
  *      q       INTEGER,
  *      g       INTEGER
@@ -466,9 +466,9 @@
  *      g               INTEGER,                    -- generator, g
  *      q               INTEGER,                    -- factor of p-1
  *      j               INTEGER OPTIONAL,           -- subgroup factor
- *      validationParms ValidationParms OPTIONAL
+ *      validationParams ValidationParams OPTIONAL
  *   }
- *   ValidationParms ::= SEQUENCE {
+ *   ValidationParams ::= SEQUENCE {
  *      seed            BIT STRING,
  *      pgenCounter     INTEGER
  *   }
@@ -862,15 +862,15 @@
  * psa_pake_set_password_key(operation, ...);
  * \endcode
  *
- * The password is read as a byte array and must be non-empty. This can be the
- * password itself (in some pre-defined character encoding) or some value
- * derived from the password as mandated by some higher level protocol.
+ * The password is provided as a key. This can be the password text itself,
+ * in an agreed character encoding, or some value derived from the password
+ * as required by a higher level protocol.
  *
- * (The implementation converts this byte array to a number as described in
+ * (The implementation converts the key material to a number as described in
  * Section 2.3.8 of _SEC 1: Elliptic Curve Cryptography_
  * (https://www.secg.org/sec1-v2.pdf), before reducing it modulo \c q. Here
  * \c q is order of the group defined by the primitive set in the cipher suite.
- * The \c psa_pake_set_password_xxx() functions return an error if the result
+ * The \c psa_pake_set_password_key() function returns an error if the result
  * of the reduction is 0.)
  *
  * The key exchange flow for J-PAKE is as follows:
@@ -961,12 +961,13 @@
  * @{
  */
 
-/** \brief Encoding of the side of PAKE
+/** \brief Encoding of the application role of PAKE
  *
- * Encodes which side of the algorithm is being executed. For more information
- * see the documentation of individual \c PSA_PAKE_SIDE_XXX constants.
+ * Encodes the application's role in the algorithm is being executed. For more
+ * information see the documentation of individual \c PSA_PAKE_ROLE_XXX
+ * constants.
  */
-typedef uint8_t psa_pake_side_t;
+typedef uint8_t psa_pake_role_t;
 
 /** Encoding of input and output indicators for PAKE.
  *
@@ -999,35 +1000,41 @@
  */
 typedef uint32_t psa_pake_primitive_t;
 
+/** A value to indicate no role in a PAKE algorithm.
+ * This value can be used in a call to psa_pake_set_role() for symmetric PAKE
+ * algorithms which do not assign roles.
+ */
+#define PSA_PAKE_ROLE_NONE                  ((psa_pake_role_t)0x00)
+
 /** The first peer in a balanced PAKE.
  *
  * Although balanced PAKE algorithms are symmetric, some of them needs an
  * ordering of peers for the transcript calculations. If the algorithm does not
- * need this, both #PSA_PAKE_SIDE_FIRST and #PSA_PAKE_SIDE_SECOND are
+ * need this, both #PSA_PAKE_ROLE_FIRST and #PSA_PAKE_ROLE_SECOND are
  * accepted.
  */
-#define PSA_PAKE_SIDE_FIRST                ((psa_pake_side_t)0x01)
+#define PSA_PAKE_ROLE_FIRST                ((psa_pake_role_t)0x01)
 
 /** The second peer in a balanced PAKE.
  *
  * Although balanced PAKE algorithms are symmetric, some of them needs an
  * ordering of peers for the transcript calculations. If the algorithm does not
- * need this, either #PSA_PAKE_SIDE_FIRST or #PSA_PAKE_SIDE_SECOND are
+ * need this, either #PSA_PAKE_ROLE_FIRST or #PSA_PAKE_ROLE_SECOND are
  * accepted.
  */
-#define PSA_PAKE_SIDE_SECOND                ((psa_pake_side_t)0x02)
+#define PSA_PAKE_ROLE_SECOND                ((psa_pake_role_t)0x02)
 
 /** The client in an augmented PAKE.
  *
  * Augmented PAKE algorithms need to differentiate between client and server.
  */
-#define PSA_PAKE_SIDE_CLIENT                ((psa_pake_side_t)0x11)
+#define PSA_PAKE_ROLE_CLIENT                ((psa_pake_role_t)0x11)
 
 /** The server in an augmented PAKE.
  *
  * Augmented PAKE algorithms need to differentiate between client and server.
  */
-#define PSA_PAKE_SIDE_SERVER                ((psa_pake_side_t)0x12)
+#define PSA_PAKE_ROLE_SERVER                ((psa_pake_role_t)0x12)
 
 /** The PAKE primitive type indicating the use of elliptic curves.
  *
@@ -1145,7 +1152,7 @@
  */
 #define PSA_PAKE_STEP_ZK_PROOF                  ((psa_pake_step_t)0x03)
 
-/** The type of the data strucure for PAKE cipher suites.
+/** The type of the data structure for PAKE cipher suites.
  *
  * This is an implementation-defined \c struct. Applications should not
  * make any assumptions about the content of this structure.
@@ -1153,29 +1160,24 @@
  */
 typedef struct psa_pake_cipher_suite_s psa_pake_cipher_suite_t;
 
+/** Return an initial value for a PAKE cipher suite object.
+ */
+static psa_pake_cipher_suite_t psa_pake_cipher_suite_init( void );
+
 /** Retrieve the PAKE algorithm from a PAKE cipher suite.
  *
- * This function may be declared as `static` (i.e. without external
- * linkage). This function may be provided as a function-like macro,
- * but in this case it must evaluate its argument exactly once.
- *
  * \param[in] cipher_suite     The cipher suite structure to query.
  *
  * \return The PAKE algorithm stored in the cipher suite structure.
  */
 static psa_algorithm_t psa_pake_cs_get_algorithm(
-                           const psa_pake_cipher_suite_t* cipher_suite
-                           );
+                           const psa_pake_cipher_suite_t *cipher_suite );
 
 /** Declare the PAKE algorithm for the cipher suite.
  *
  * This function overwrites any PAKE algorithm
  * previously set in \p cipher_suite.
  *
- * This function may be declared as `static` (i.e. without external
- * linkage). This function may be provided as a function-like macro,
- * but in this case it must evaluate each of its arguments exactly once.
- *
  * \param[out] cipher_suite    The cipher suite structure to write to.
  * \param algorithm            The PAKE algorithm to write.
  *                             (`PSA_ALG_XXX` values of type ::psa_algorithm_t
@@ -1183,49 +1185,50 @@
  *                             If this is 0, the PAKE algorithm in
  *                             \p cipher_suite becomes unspecified.
  */
-static void psa_pake_cs_set_algorithm(
-                           psa_pake_cipher_suite_t* cipher_suite,
-                           psa_algorithm_t algorithm
-                           );
+static void psa_pake_cs_set_algorithm( psa_pake_cipher_suite_t *cipher_suite,
+                                       psa_algorithm_t algorithm );
 
 /** Retrieve the primitive from a PAKE cipher suite.
  *
- * This function may be declared as `static` (i.e. without external linkage).
- * This function may be provided as a function-like macro, but in this case it
- * must evaluate its argument exactly once.
- *
  * \param[in] cipher_suite     The cipher suite structure to query.
  *
  * \return The primitive stored in the cipher suite structure.
  */
 static psa_pake_primitive_t psa_pake_cs_get_primitive(
-                           const psa_pake_cipher_suite_t* cipher_suite
-                           );
+                           const psa_pake_cipher_suite_t *cipher_suite );
 
 /** Declare the primitive for a PAKE cipher suite.
  *
  * This function overwrites any primitive previously set in \p cipher_suite.
  *
- * This function may be declared as `static` (i.e. without external
- * linkage). This function may be provided as a function-like macro,
- * but in this case it must evaluate each of its arguments exactly once.
- *
  * \param[out] cipher_suite    The cipher suite structure to write to.
  * \param primitive            The primitive to write. If this is 0, the
  *                             primitive type in \p cipher_suite becomes
  *                             unspecified.
  */
-static void psa_pake_cs_set_primitive(
-                           psa_pake_cipher_suite_t* cipher_suite,
-                           psa_pake_primitive_t primitive
-                           );
+static void psa_pake_cs_set_primitive( psa_pake_cipher_suite_t *cipher_suite,
+                                       psa_pake_primitive_t primitive );
+
+/** Retrieve the PAKE family from a PAKE cipher suite.
+ *
+ * \param[in] cipher_suite     The cipher suite structure to query.
+ *
+ * \return The PAKE family stored in the cipher suite structure.
+ */
+static psa_pake_family_t psa_pake_cs_get_family(
+                           const psa_pake_cipher_suite_t *cipher_suite );
+
+/** Retrieve the PAKE primitive bit-size from a PAKE cipher suite.
+ *
+ * \param[in] cipher_suite     The cipher suite structure to query.
+ *
+ * \return The PAKE primitive bit-size stored in the cipher suite structure.
+ */
+static uint16_t psa_pake_cs_get_bits(
+                           const psa_pake_cipher_suite_t *cipher_suite );
 
 /** Retrieve the hash algorithm from a PAKE cipher suite.
  *
- * This function may be declared as `static` (i.e. without external
- * linkage). This function may be provided as a function-like macro,
- * but in this case it must evaluate its argument exactly once.
- *
  * \param[in] cipher_suite      The cipher suite structure to query.
  *
  * \return The hash algorithm stored in the cipher suite structure. The return
@@ -1233,18 +1236,13 @@
  *         the hash algorithm is not set.
  */
 static psa_algorithm_t psa_pake_cs_get_hash(
-                           const psa_pake_cipher_suite_t* cipher_suite
-                           );
+                           const psa_pake_cipher_suite_t *cipher_suite );
 
 /** Declare the hash algorithm for a PAKE cipher suite.
  *
  * This function overwrites any hash algorithm
  * previously set in \p cipher_suite.
  *
- * This function may be declared as `static` (i.e. without external
- * linkage). This function may be provided as a function-like macro,
- * but in this case it must evaluate each of its arguments exactly once.
- *
  * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX`
  * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true)
  * for more information.
@@ -1256,10 +1254,8 @@
  *                              If this is 0, the hash algorithm in
  *                              \p cipher_suite becomes unspecified.
  */
-static void psa_pake_cs_set_hash(
-                           psa_pake_cipher_suite_t* cipher_suite,
-                           psa_algorithm_t hash
-                           );
+static void psa_pake_cs_set_hash( psa_pake_cipher_suite_t *cipher_suite,
+                                  psa_algorithm_t hash );
 
 /** The type of the state data structure for PAKE operations.
  *
@@ -1293,7 +1289,7 @@
 
 /** Return an initial value for an PAKE operation object.
  */
-static psa_pake_operation_t psa_pake_operation_init(void);
+static psa_pake_operation_t psa_pake_operation_init( void );
 
 /** Set the session information for a password-authenticated key exchange.
  *
@@ -1340,16 +1336,24 @@
  *
  * \param[in,out] operation     The operation object to set up. It must have
  *                              been initialized but not set up yet.
- * \param cipher_suite          The cipher suite to use. (A cipher suite fully
+ * \param[in] cipher_suite      The cipher suite to use. (A cipher suite fully
  *                              characterizes a PAKE algorithm and determines
  *                              the algorithm as well.)
  *
  * \retval #PSA_SUCCESS
  *         Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         The algorithm in \p cipher_suite is not a PAKE algorithm, or the
+ *         PAKE primitive in \p cipher_suite is not compatible with the
+ *         PAKE algorithm, or the hash algorithm in \p cipher_suite is invalid
+ *         or not compatible with the PAKE algorithm and primitive.
  * \retval #PSA_ERROR_NOT_SUPPORTED
- *         The \p cipher_suite is not supported or is not valid.
+ *         The algorithm in \p cipher_suite is not a supported PAKE algorithm,
+ *         or the PAKE primitive in \p cipher_suite is not supported or not
+ *         compatible with the PAKE algorithm, or the hash algorithm in
+ *         \p cipher_suite is not supported or not compatible with the PAKE
+ *         algorithm and primitive.
  * \retval #PSA_ERROR_COMMUNICATION_FAILURE
- * \retval #PSA_ERROR_HARDWARE_FAILURE
  * \retval #PSA_ERROR_CORRUPTION_DETECTED
  * \retval #PSA_ERROR_BAD_STATE
  *         The operation state is not valid, or
@@ -1357,8 +1361,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_pake_setup(psa_pake_operation_t *operation,
-                            psa_pake_cipher_suite_t cipher_suite);
+psa_status_t psa_pake_setup( psa_pake_operation_t *operation,
+                             const psa_pake_cipher_suite_t *cipher_suite );
 
 /** Set the password for a password-authenticated key exchange from key ID.
  *
@@ -1382,22 +1386,31 @@
  *
  * \retval #PSA_SUCCESS
  *         Success.
- * \retval #PSA_ERROR_INVALID_ARGUMENT
- *         \p key is not compatible with the algorithm or the cipher suite.
- * \retval #PSA_ERROR_CORRUPTION_DETECTED
  * \retval #PSA_ERROR_INVALID_HANDLE
- * \retval #PSA_ERROR_COMMUNICATION_FAILURE
- * \retval #PSA_ERROR_HARDWARE_FAILURE
- * \retval #PSA_ERROR_STORAGE_FAILURE
+ *         \p password is not a valid key identifier.
  * \retval #PSA_ERROR_NOT_PERMITTED
+ *         The key does not have the #PSA_KEY_USAGE_DERIVE flag, or it does not
+ *         permit the \p operation's algorithm.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         The key type for \p password is not #PSA_KEY_TYPE_PASSWORD or
+ *         #PSA_KEY_TYPE_PASSWORD_HASH, or \p password is not compatible with
+ *         the \p operation's cipher suite.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         The key type or key size of \p password is not supported with the
+ *         \p operation's cipher suite.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_DATA_CORRUPT
+ * \retval #PSA_ERROR_DATA_INVALID
  * \retval #PSA_ERROR_BAD_STATE
  *         The operation state is not valid (it must have been set up.), or
  *         the library has not been previously initialized by psa_crypto_init().
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_pake_set_password_key(psa_pake_operation_t *operation,
-                                       mbedtls_svc_key_id_t password);
+psa_status_t psa_pake_set_password_key( psa_pake_operation_t *operation,
+                                        mbedtls_svc_key_id_t password );
 
 /** Set the user ID for a password-authenticated key exchange.
  *
@@ -1423,10 +1436,12 @@
  * \retval #PSA_SUCCESS
  *         Success.
  * \retval #PSA_ERROR_INVALID_ARGUMENT
- *         \p user_id is NULL.
+ *         \p user_id is not valid for the \p operation's algorithm and cipher
+ *         suite.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         The value of \p user_id is not supported by the implementation.
  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
  * \retval #PSA_ERROR_COMMUNICATION_FAILURE
- * \retval #PSA_ERROR_HARDWARE_FAILURE
  * \retval #PSA_ERROR_CORRUPTION_DETECTED
  * \retval #PSA_ERROR_BAD_STATE
  *         The operation state is not valid, or
@@ -1434,9 +1449,9 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_pake_set_user(psa_pake_operation_t *operation,
-                               const uint8_t *user_id,
-                               size_t user_id_len);
+psa_status_t psa_pake_set_user( psa_pake_operation_t *operation,
+                                const uint8_t *user_id,
+                                size_t user_id_len );
 
 /** Set the peer ID for a password-authenticated key exchange.
  *
@@ -1461,52 +1476,56 @@
  *
  * \retval #PSA_SUCCESS
  *         Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         \p user_id is not valid for the \p operation's algorithm and cipher
+ *         suite.
  * \retval #PSA_ERROR_NOT_SUPPORTED
  *         The algorithm doesn't associate a second identity with the session.
- * \retval #PSA_ERROR_INVALID_ARGUMENT
- *         \p user_id is NULL.
  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
  * \retval #PSA_ERROR_COMMUNICATION_FAILURE
- * \retval #PSA_ERROR_HARDWARE_FAILURE
  * \retval #PSA_ERROR_CORRUPTION_DETECTED
  * \retval #PSA_ERROR_BAD_STATE
- *         The operation state is not valid, or the library has not
+ *         Calling psa_pake_set_peer() is invalid with the \p operation's
+ *         algorithm, the operation state is not valid, or the library has not
  *         been previously initialized by psa_crypto_init().
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_pake_set_peer(psa_pake_operation_t *operation,
-                               const uint8_t *peer_id,
-                               size_t peer_id_len);
+psa_status_t psa_pake_set_peer( psa_pake_operation_t *operation,
+                                const uint8_t *peer_id,
+                                size_t peer_id_len );
 
-/** Set the side for a password-authenticated key exchange.
+/** Set the application role for a password-authenticated key exchange.
  *
  * Not all PAKE algorithms need to differentiate the communicating entities.
- * It is optional to call this function for PAKEs that don't require a side
- * parameter. For such PAKEs the side parameter is ignored.
+ * It is optional to call this function for PAKEs that don't require a role
+ * to be specified. For such PAKEs the application role parameter is ignored,
+ * or #PSA_PAKE_ROLE_NONE can be passed as \c role.
  *
  * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX`
  * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true)
  * for more information.
  *
- * \param[in,out] operation     The operation object to set the side for. It
- *                              must have been set up by psa_pake_setup() and
- *                              not yet in use (neither psa_pake_output() nor
- *                              psa_pake_input() has been called yet). It must
- *                              be on operation for which the side hasn't been
- *                              set (psa_pake_set_side() hasn't been called
- *                              yet).
- * \param side                  A value of type ::psa_pake_side_t signaling the
- *                              side of the algorithm that is being set up. For
- *                              more information see the documentation of
- *                              \c PSA_PAKE_SIDE_XXX constants.
+ * \param[in,out] operation     The operation object to specify the
+ *                              application's role for. It must have been set up
+ *                              by psa_pake_setup() and not yet in use (neither
+ *                              psa_pake_output() nor psa_pake_input() has been
+ *                              called yet). It must be on operation for which
+ *                              the application's role hasn't been specified
+ *                              (psa_pake_set_role() hasn't been called yet).
+ * \param role                  A value of type ::psa_pake_role_t indicating the
+ *                              application's role in the PAKE the algorithm
+ *                              that is being set up. For more information see
+ *                              the documentation of \c PSA_PAKE_ROLE_XXX
+ *                              constants.
  *
  * \retval #PSA_SUCCESS
  *         Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         The \p role is not a valid PAKE role in the \p operation’s algorithm.
  * \retval #PSA_ERROR_NOT_SUPPORTED
- *         The \p side for this algorithm is not supported or is not valid.
+ *         The \p role for this algorithm is not supported or is not valid.
  * \retval #PSA_ERROR_COMMUNICATION_FAILURE
- * \retval #PSA_ERROR_HARDWARE_FAILURE
  * \retval #PSA_ERROR_CORRUPTION_DETECTED
  * \retval #PSA_ERROR_BAD_STATE
  *         The operation state is not valid, or
@@ -1514,8 +1533,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_pake_set_side(psa_pake_operation_t *operation,
-                               psa_pake_side_t side);
+psa_status_t psa_pake_set_role( psa_pake_operation_t *operation,
+                                psa_pake_role_t role );
 
 /** Get output for a step of a password-authenticated key exchange.
  *
@@ -1540,8 +1559,11 @@
  *                             \c PSA_PAKE_STEP_XXX constants for more
  *                             information.
  * \param output_size          Size of the \p output buffer in bytes. This must
- *                             be at least #PSA_PAKE_OUTPUT_SIZE(\p alg, \c
- *                             cipher_suite, \p type).
+ *                             be at least #PSA_PAKE_OUTPUT_SIZE(\p alg, \p
+ *                             primitive, \p step) where \p alg and
+ *                             \p primitive are the PAKE algorithm and primitive
+ *                             in the operation's cipher suite, and \p step is
+ *                             the output step.
  *
  * \param[out] output_length   On success, the number of bytes of the returned
  *                             output.
@@ -1550,23 +1572,30 @@
  *         Success.
  * \retval #PSA_ERROR_BUFFER_TOO_SMALL
  *         The size of the \p output buffer is too small.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         \p step is not compatible with the operation's algorithm.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         \p step is not supported with the operation's algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
  * \retval #PSA_ERROR_COMMUNICATION_FAILURE
- * \retval #PSA_ERROR_HARDWARE_FAILURE
  * \retval #PSA_ERROR_CORRUPTION_DETECTED
  * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_DATA_CORRUPT
+ * \retval #PSA_ERROR_DATA_INVALID
  * \retval #PSA_ERROR_BAD_STATE
- *         The operation state is not valid (it must be active, but beyond that
- *         validity is specific to the algorithm), or
+ *         The operation state is not valid (it must be active, and fully set
+ *         up, and this call must conform to the algorithm's requirements
+ *         for ordering of input and output steps), or
  *         the library has not been previously initialized by psa_crypto_init().
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_pake_output(psa_pake_operation_t *operation,
-                             psa_pake_step_t step,
-                             uint8_t *output,
-                             size_t output_size,
-                             size_t *output_length);
+psa_status_t psa_pake_output( psa_pake_operation_t *operation,
+                              psa_pake_step_t step,
+                              uint8_t *output,
+                              size_t output_size,
+                              size_t *output_length );
 
 /** Provide input for a step of a password-authenticated key exchange.
  *
@@ -1584,33 +1613,43 @@
  *
  * \param[in,out] operation    Active PAKE operation.
  * \param step                 The step for which the input is provided.
- * \param[out] input           Buffer containing the input in the format
+ * \param[in] input            Buffer containing the input in the format
  *                             appropriate for this \p step. Refer to the
  *                             documentation of the individual
  *                             \c PSA_PAKE_STEP_XXX constants for more
  *                             information.
- * \param[out] input_length    Size of the \p input buffer in bytes.
+ * \param input_length         Size of the \p input buffer in bytes.
  *
  * \retval #PSA_SUCCESS
  *         Success.
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ *         The verification fails for a #PSA_PAKE_STEP_ZK_PROOF input step.
  * \retval #PSA_ERROR_INVALID_ARGUMENT
- *         The input is not valid for the algorithm, ciphersuite or \p step.
+ *         \p is not compatible with the \p operation’s algorithm, or the
+ *         \p input is not valid for the \p operation's algorithm, cipher suite
+ *         or \p step.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         \p step p is not supported with the \p operation's algorithm, or the
+ *         \p input is not supported for the \p operation's algorithm, cipher
+ *         suite or \p step.
  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
  * \retval #PSA_ERROR_COMMUNICATION_FAILURE
- * \retval #PSA_ERROR_HARDWARE_FAILURE
  * \retval #PSA_ERROR_CORRUPTION_DETECTED
  * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_DATA_CORRUPT
+ * \retval #PSA_ERROR_DATA_INVALID
  * \retval #PSA_ERROR_BAD_STATE
- *         The operation state is not valid (it must be active, but beyond that
- *         validity is specific to the algorithm), or
+ *         The operation state is not valid (it must be active, and fully set
+ *         up, and this call must conform to the algorithm's requirements
+ *         for ordering of input and output steps), or
  *         the library has not been previously initialized by psa_crypto_init().
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_pake_input(psa_pake_operation_t *operation,
-                            psa_pake_step_t step,
-                            uint8_t *input,
-                            size_t input_length);
+psa_status_t psa_pake_input( psa_pake_operation_t *operation,
+                             psa_pake_step_t step,
+                             const uint8_t *input,
+                             size_t input_length );
 
 /** Get implicitly confirmed shared secret from a PAKE.
  *
@@ -1648,13 +1687,17 @@
  * \retval #PSA_SUCCESS
  *         Success.
  * \retval #PSA_ERROR_INVALID_ARGUMENT
- *         #PSA_KEY_DERIVATION_INPUT_SECRET is not compatible with the output’s
- *         algorithm.
+ *         #PSA_KEY_DERIVATION_INPUT_SECRET is not compatible with the
+ *         algorithm in the \p output key derivation operation.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         Input from a PAKE is not supported by the algorithm in the \p output
+ *         key derivation operation.
  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
  * \retval #PSA_ERROR_COMMUNICATION_FAILURE
- * \retval #PSA_ERROR_HARDWARE_FAILURE
  * \retval #PSA_ERROR_CORRUPTION_DETECTED
  * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_DATA_CORRUPT
+ * \retval #PSA_ERROR_DATA_INVALID
  * \retval #PSA_ERROR_BAD_STATE
  *         The PAKE operation state is not valid (it must be active, but beyond
  *         that validity is specific to the algorithm), or
@@ -1666,8 +1709,34 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation,
-                                       psa_key_derivation_operation_t *output);
+psa_status_t psa_pake_get_implicit_key( psa_pake_operation_t *operation,
+                                        psa_key_derivation_operation_t *output );
+
+/** Abort a PAKE operation.
+ *
+ * Aborting an operation frees all associated resources except for the \c
+ * operation structure itself. Once aborted, the operation object can be reused
+ * for another operation by calling psa_pake_setup() again.
+ *
+ * This function may be called at any time after the operation
+ * object has been initialized as described in #psa_pake_operation_t.
+ *
+ * In particular, calling psa_pake_abort() after the operation has been
+ * terminated by a call to psa_pake_abort() or psa_pake_get_implicit_key()
+ * is safe and has no effect.
+ *
+ * \param[in,out] operation    The operation to abort.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ *         The library has not been previously initialized by psa_crypto_init().
+ *         It is implementation-dependent whether a failure to initialize
+ *         results in this error code.
+ */
+psa_status_t psa_pake_abort( psa_pake_operation_t * operation );
 
 /**@}*/
 
@@ -1686,9 +1755,10 @@
  * \param output_step   A value of type ::psa_pake_step_t that is valid for the
  *                      algorithm \p alg.
  * \return              A sufficient output buffer size for the specified
- *                      output, cipher suite and algorithm. If the cipher suite,
- *                      the output type or PAKE algorithm is not recognized, or
- *                      the parameters are incompatible, return 0.
+ *                      PAKE algorithm, primitive, and output step. If the
+ *                      PAKE algorithm, primitive, or output step is not
+ *                      recognized, or the parameters are incompatible,
+ *                      return 0.
  */
 #define PSA_PAKE_OUTPUT_SIZE(alg, primitive, output_step) 0
 
@@ -1713,24 +1783,34 @@
  */
 #define PSA_PAKE_INPUT_SIZE(alg, primitive, input_step) 0
 
-/** Output buffer size for psa_pake_output() for any of the supported cipher
- * suites and PAKE algorithms.
+/** Output buffer size for psa_pake_output() for any of the supported PAKE
+ * algorithm and primitive suites and output step.
  *
  * This macro must expand to a compile-time constant integer.
  *
- * See also #PSA_PAKE_OUTPUT_SIZE(\p alg, \p cipher_suite, \p output).
+ * See also #PSA_PAKE_OUTPUT_SIZE(\p alg, \p primitive, \p step).
  */
 #define PSA_PAKE_OUTPUT_MAX_SIZE 0
 
-/** Input buffer size for psa_pake_input() for any of the supported cipher
- * suites and PAKE algorithms.
+/** Input buffer size for psa_pake_input() for any of the supported PAKE
+ * algorithm and primitive suites and input step.
  *
  * This macro must expand to a compile-time constant integer.
  *
- * See also #PSA_PAKE_INPUT_SIZE(\p alg, \p cipher_suite, \p input).
+ * See also #PSA_PAKE_INPUT_SIZE(\p alg, \p primitive, \p step).
  */
 #define PSA_PAKE_INPUT_MAX_SIZE 0
 
+/** Returns a suitable initializer for a PAKE cipher suite object of type
+ * psa_pake_cipher_suite_t.
+ */
+#define PSA_PAKE_CIPHER_SUITE_INIT {PSA_ALG_NONE, 0, 0, 0, PSA_ALG_NONE}
+
+/** Returns a suitable initializer for a PAKE operation object of type
+ * psa_pake_operation_t.
+ */
+#define PSA_PAKE_OPERATION_INIT {PSA_ALG_NONE, {0}}
+
 struct psa_pake_cipher_suite_s
 {
     psa_algorithm_t algorithm;
@@ -1741,48 +1821,59 @@
 };
 
 static inline psa_algorithm_t psa_pake_cs_get_algorithm(
-    const psa_pake_cipher_suite_t *cipher_suite)
+                        const psa_pake_cipher_suite_t *cipher_suite )
 {
-    return(cipher_suite->algorithm);
+    return( cipher_suite->algorithm );
 }
 
 static inline void psa_pake_cs_set_algorithm(
     psa_pake_cipher_suite_t *cipher_suite,
     psa_algorithm_t algorithm)
 {
-    if(!PSA_ALG_IS_PAKE(algorithm))
+    if( !PSA_ALG_IS_PAKE( algorithm ) )
         cipher_suite->algorithm = 0;
     else
         cipher_suite->algorithm = algorithm;
 }
 
 static inline psa_pake_primitive_t psa_pake_cs_get_primitive(
-    const psa_pake_cipher_suite_t *cipher_suite)
+                        const psa_pake_cipher_suite_t *cipher_suite )
 {
-    return(PSA_PAKE_PRIMITIVE(cipher_suite->type, cipher_suite->family,
-                cipher_suite->bits));
+    return( PSA_PAKE_PRIMITIVE( cipher_suite->type, cipher_suite->family,
+                                cipher_suite->bits ) );
 }
 
 static inline void psa_pake_cs_set_primitive(
-    psa_pake_cipher_suite_t *cipher_suite,
-    psa_pake_primitive_t primitive)
+                        psa_pake_cipher_suite_t *cipher_suite,
+                        psa_pake_primitive_t primitive )
 {
     cipher_suite->type = (psa_pake_primitive_type_t) (primitive >> 24);
     cipher_suite->family = (psa_pake_family_t) (0xFF & (primitive >> 16));
     cipher_suite->bits = (uint16_t) (0xFFFF & primitive);
 }
 
-static inline psa_algorithm_t psa_pake_cs_get_hash(
-    const psa_pake_cipher_suite_t *cipher_suite)
+static inline psa_pake_family_t psa_pake_cs_get_family(
+                        const psa_pake_cipher_suite_t *cipher_suite )
 {
-    return(cipher_suite->hash);
+    return( cipher_suite->family );
 }
 
-static inline void psa_pake_cs_set_hash(
-    psa_pake_cipher_suite_t *cipher_suite,
-    psa_algorithm_t hash)
+static inline uint16_t psa_pake_cs_get_bits(
+                        const psa_pake_cipher_suite_t *cipher_suite )
 {
-    if(!PSA_ALG_IS_HASH(hash))
+    return( cipher_suite->bits );
+}
+
+static inline psa_algorithm_t psa_pake_cs_get_hash(
+                        const psa_pake_cipher_suite_t *cipher_suite )
+{
+    return( cipher_suite->hash );
+}
+
+static inline void psa_pake_cs_set_hash( psa_pake_cipher_suite_t *cipher_suite,
+                                         psa_algorithm_t hash )
+{
+    if( !PSA_ALG_IS_HASH( hash ) )
         cipher_suite->hash = 0;
     else
         cipher_suite->hash = hash;
@@ -1798,12 +1889,16 @@
     } ctx;
 };
 
-/* This only zeroes out the first byte in the union, the rest is unspecified. */
-#define PSA_PAKE_OPERATION_INIT {0, {0}}
-static inline struct psa_pake_operation_s psa_pake_operation_init(void)
+static inline struct psa_pake_cipher_suite_s psa_pake_cipher_suite_init( void )
+{
+    const struct psa_pake_cipher_suite_s v = PSA_PAKE_CIPHER_SUITE_INIT;
+    return( v );
+}
+
+static inline struct psa_pake_operation_s psa_pake_operation_init( void )
 {
     const struct psa_pake_operation_s v = PSA_PAKE_OPERATION_INIT;
-    return(v);
+    return( v );
 }
 
 #ifdef __cplusplus
diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h
index 9bbcb34..1024d6b 100644
--- a/include/psa/crypto_sizes.h
+++ b/include/psa/crypto_sizes.h
@@ -739,7 +739,7 @@
  *      subjectPublicKey     BIT STRING  } -- contains DSAPublicKey
  * AlgorithmIdentifier  ::=  SEQUENCE  {
  *      algorithm               OBJECT IDENTIFIER,
- *      parameters              Dss-Parms  } -- SEQUENCE of 3 INTEGERs
+ *      parameters              Dss-Params  } -- SEQUENCE of 3 INTEGERs
  * DSAPublicKey  ::=  INTEGER -- public key, Y
  *
  * - 3 * 4 bytes of SEQUENCE overhead;
diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h
index f333db1..434554d 100644
--- a/include/psa/crypto_struct.h
+++ b/include/psa/crypto_struct.h
@@ -462,7 +462,7 @@
     }
     else
     {
-        /* Call the bigger function to free the old domain paramteres.
+        /* Call the bigger function to free the old domain parameters.
          * Ignore any errors which may arise due to type requiring
          * non-default domain parameters, since this function can't
          * report errors. */
diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h
index 2f9a15a..17d7a9b 100644
--- a/include/psa/crypto_values.h
+++ b/include/psa/crypto_values.h
@@ -489,8 +489,12 @@
  *
  * ChaCha20 and the ChaCha20_Poly1305 construction are defined in RFC 7539.
  *
- * Implementations must support 12-byte nonces, may support 8-byte nonces,
- * and should reject other sizes.
+ * \note For ChaCha20 and ChaCha20_Poly1305, Mbed TLS only supports
+ *       12-byte nonces.
+ *
+ * \note For ChaCha20, the initial counter value is 0. To encrypt or decrypt
+ *       with the initial counter value 1, you can process and discard a
+ *       64-byte block before the real data.
  */
 #define PSA_KEY_TYPE_CHACHA20                       ((psa_key_type_t)0x2004)
 
@@ -1456,7 +1460,7 @@
  * with a random per-message secret number (*k*).
  *
  * The representation of the signature as a byte string consists of
- * the concatentation of the signature values *r* and *s*. Each of
+ * the concatenation of the signature values *r* and *s*. Each of
  * *r* and *s* is encoded as an *N*-octet string, where *N* is the length
  * of the base point of the curve in octets. Each value is represented
  * in big-endian order (most significant octet first).
@@ -2269,8 +2273,8 @@
 #else /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */
 
 #define MBEDTLS_SVC_KEY_ID_INIT ( (mbedtls_svc_key_id_t){ 0, 0 } )
-#define MBEDTLS_SVC_KEY_ID_GET_KEY_ID( id ) ( ( id ).key_id )
-#define MBEDTLS_SVC_KEY_ID_GET_OWNER_ID( id ) ( ( id ).owner )
+#define MBEDTLS_SVC_KEY_ID_GET_KEY_ID( id ) ( ( id ).MBEDTLS_PRIVATE(key_id) )
+#define MBEDTLS_SVC_KEY_ID_GET_OWNER_ID( id ) ( ( id ).MBEDTLS_PRIVATE(owner) )
 
 /** Utility to initialize a key identifier at runtime.
  *
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 6bb2ad3..886fc68 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -187,6 +187,18 @@
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-declarations -Wmissing-prototypes -Wdocumentation -Wno-documentation-deprecated-sync -Wunreachable-code")
 endif(CMAKE_COMPILER_IS_CLANG)
 
+if(CMAKE_COMPILER_IS_MSVC)
+    option(MSVC_STATIC_RUNTIME "Build the libraries with /MT compiler flag" OFF)
+    if(MSVC_STATIC_RUNTIME)
+        foreach(flag_var
+            CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
+            CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
+            CMAKE_C_FLAGS_CHECK)
+            string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
+        endforeach(flag_var)
+    endif()
+endif()
+
 if(WIN32)
     set(libs ${libs} ws2_32)
 endif(WIN32)
@@ -291,7 +303,9 @@
     install(
         TARGETS ${target}
         EXPORT MbedTLSTargets
-        DESTINATION ${LIB_INSTALL_DIR}
+        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
         PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
 endforeach(target)
 
diff --git a/library/aes.c b/library/aes.c
index d2b05e2..bf5d432 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -1089,7 +1089,7 @@
  *
  * This function multiplies a field element by x in the polynomial field
  * representation. It uses 64-bit word operations to gain speed but compensates
- * for machine endianess and hence works correctly on both big and little
+ * for machine endianness and hence works correctly on both big and little
  * endian machines.
  */
 static void mbedtls_gf128mul_x_ble( unsigned char r[16],
@@ -1189,7 +1189,7 @@
         unsigned char *prev_output = output - 16;
 
         /* Copy ciphertext bytes from the previous block to our output for each
-         * byte of cyphertext we won't steal. At the same time, copy the
+         * byte of ciphertext we won't steal. At the same time, copy the
          * remainder of the input for this final round (since the loop bounds
          * are the same). */
         for( i = 0; i < leftover; i++ )
diff --git a/library/bignum.c b/library/bignum.c
index f06eff0..11acc01 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -2278,7 +2278,7 @@
          * TA-TB is even so the division by 2 has an integer result.
          * Invariant (I) is preserved since any odd divisor of both TA and TB
          * also divides |TA-TB|/2, and any odd divisor of both TA and |TA-TB|/2
-         * also divides TB, and any odd divisior of both TB and |TA-TB|/2 also
+         * also divides TB, and any odd divisor of both TB and |TA-TB|/2 also
          * divides TA.
          */
         if( mbedtls_mpi_cmp_mpi( &TA, &TB ) >= 0 )
diff --git a/library/ccm.c b/library/ccm.c
index e062678..3edfba3 100644
--- a/library/ccm.c
+++ b/library/ccm.c
@@ -99,7 +99,7 @@
 
 #define CCM_STATE__CLEAR                0
 #define CCM_STATE__STARTED              (1 << 0)
-#define CCM_STATE__LENGHTS_SET          (1 << 1)
+#define CCM_STATE__LENGTHS_SET          (1 << 1)
 #define CCM_STATE__AUTH_DATA_STARTED    (1 << 2)
 #define CCM_STATE__AUTH_DATA_FINISHED   (1 << 3)
 #define CCM_STATE__ERROR                (1 << 4)
@@ -147,7 +147,7 @@
     /* length calulcation can be done only after both
      * mbedtls_ccm_starts() and mbedtls_ccm_set_lengths() have been executed
      */
-    if( !(ctx->state & CCM_STATE__STARTED) || !(ctx->state & CCM_STATE__LENGHTS_SET) )
+    if( !(ctx->state & CCM_STATE__STARTED) || !(ctx->state & CCM_STATE__LENGTHS_SET) )
         return 0;
 
     /* CCM expects non-empty tag.
@@ -260,7 +260,7 @@
     ctx->tag_len = tag_len;
     ctx->processed = 0;
 
-    ctx->state |= CCM_STATE__LENGHTS_SET;
+    ctx->state |= CCM_STATE__LENGTHS_SET;
     return ccm_calculate_first_block_if_ready(ctx);
 }
 
diff --git a/library/constant_time.c b/library/constant_time.c
index a6451bb..8475b0c 100644
--- a/library/constant_time.c
+++ b/library/constant_time.c
@@ -690,7 +690,7 @@
 /*
  * Conditionally swap X and Y, without leaking information
  * about whether the swap was made or not.
- * Here it is not ok to simply swap the pointers, which whould lead to
+ * Here it is not ok to simply swap the pointers, which would lead to
  * different memory access patterns when X and Y are used afterwards.
  */
 int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X,
diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c
index 93a7cdc..23ea07b 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -815,7 +815,7 @@
                         return( 1 );                        \
                     }
 
-#define SELF_TEST_OUPUT_DISCARD_LENGTH 64
+#define SELF_TEST_OUTPUT_DISCARD_LENGTH 64
 
 /*
  * Checkup routine
@@ -841,7 +841,7 @@
                                 (void *) entropy_source_pr,
                                 pers_pr, MBEDTLS_CTR_DRBG_KEYSIZE ) );
     mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
-    CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUPUT_DISCARD_LENGTH ) );
+    CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH ) );
     CHK( mbedtls_ctr_drbg_random( &ctx, buf, sizeof( result_pr ) ) );
     CHK( memcmp( buf, result_pr, sizeof( result_pr ) ) );
 
@@ -866,7 +866,7 @@
                                 (void *) entropy_source_nopr,
                                 pers_nopr, MBEDTLS_CTR_DRBG_KEYSIZE ) );
     CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
-    CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUPUT_DISCARD_LENGTH ) );
+    CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH ) );
     CHK( mbedtls_ctr_drbg_random( &ctx, buf, sizeof( result_nopr ) ) );
     CHK( memcmp( buf, result_nopr, sizeof( result_nopr ) ) );
 
diff --git a/library/ecdh.c b/library/ecdh.c
index 8be7f19..cc1340c 100644
--- a/library/ecdh.c
+++ b/library/ecdh.c
@@ -399,7 +399,7 @@
 }
 
 /*
- * Read the ServerKeyExhange parameters (RFC 4492)
+ * Read the ServerKeyExchange parameters (RFC 4492)
  *      struct {
  *          ECParameters    curve_params;
  *          ECPoint         public;
diff --git a/library/ecjpake.c b/library/ecjpake.c
index 738a977..d467a65 100644
--- a/library/ecjpake.c
+++ b/library/ecjpake.c
@@ -449,7 +449,7 @@
 
 /*
  * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs
- * Ouputs: verified peer public keys Xa, Xb
+ * Outputs: verified peer public keys Xa, Xb
  */
 static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info,
                               const mbedtls_ecp_group *grp,
diff --git a/library/ecp.c b/library/ecp.c
index f39cb02..67c46f2 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -1267,7 +1267,7 @@
  * For curves in short Weierstrass form, we do all the internal operations in
  * Jacobian coordinates.
  *
- * For multiplication, we'll use a comb method with coutermeasueres against
+ * For multiplication, we'll use a comb method with countermeasures against
  * SPA, hence timing attacks.
  */
 
@@ -1817,7 +1817,7 @@
     unsigned char i;
     size_t j = 0;
     const unsigned char T_size = 1U << ( w - 1 );
-    mbedtls_ecp_point *cur, *TT[COMB_MAX_PRE - 1];
+    mbedtls_ecp_point *cur, *TT[COMB_MAX_PRE - 1] = {NULL};
 
     mbedtls_mpi tmp[4];
 
@@ -2231,7 +2231,7 @@
  * This function is mainly responsible for administrative work:
  * - managing the restart context if enabled
  * - managing the table of precomputed points (passed between the below two
- *   functions): allocation, computation, ownership tranfer, freeing.
+ *   functions): allocation, computation, ownership transfer, freeing.
  *
  * It delegates the actual arithmetic work to:
  *      ecp_precompute_comb() and ecp_mul_comb_with_precomp()
@@ -2365,7 +2365,7 @@
 /*
  * For Montgomery curves, we do all the internal arithmetic in projective
  * coordinates. Import/export of points uses only the x coordinates, which is
- * internaly represented as X / Z.
+ * internally represented as X / Z.
  *
  * For scalar multiplication, we'll use a Montgomery ladder.
  */
@@ -2519,7 +2519,7 @@
     MPI_ECP_LSET( &R->Z, 0 );
     mbedtls_mpi_free( &R->Y );
 
-    /* RP.X might be sligtly larger than P, so reduce it */
+    /* RP.X might be slightly larger than P, so reduce it */
     MOD_ADD( &RP.X );
 
     /* Randomize coordinates of the starting point */
diff --git a/library/gcm.c b/library/gcm.c
index 8505cf4..6d07f87 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -430,7 +430,7 @@
     const unsigned char *p = input;
     unsigned char *out_p = output;
     size_t offset;
-    unsigned char ectr[16];
+    unsigned char ectr[16] = {0};
 
     if( output_size < input_length )
         return( MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL );
diff --git a/library/memory_buffer_alloc.c b/library/memory_buffer_alloc.c
index 8c6b442..61432d8 100644
--- a/library/memory_buffer_alloc.c
+++ b/library/memory_buffer_alloc.c
@@ -561,8 +561,8 @@
 
 static void buffer_alloc_free_mutexed( void *ptr )
 {
-    /* We have to good option here, but corrupting the heap seems
-     * worse than loosing memory. */
+    /* We have no good option here, but corrupting the heap seems
+     * worse than losing memory. */
     if( mbedtls_mutex_lock( &heap.mutex ) )
         return;
     buffer_alloc_free( ptr );
diff --git a/library/mps_common.h b/library/mps_common.h
index d20776f..668876c 100644
--- a/library/mps_common.h
+++ b/library/mps_common.h
@@ -51,7 +51,7 @@
  *  the function's behavior is entirely undefined.
  *  In addition to state integrity, all MPS structures have a more refined
  *  notion of abstract state that the API operates on. For example, all layers
- *  have a notion of 'abtract read state' which indicates if incoming data has
+ *  have a notion of 'abstract read state' which indicates if incoming data has
  *  been passed to the user, e.g. through mps_l2_read_start() for Layer 2
  *  or mps_l3_read() in Layer 3. After such a call, it doesn't make sense to
  *  call these reading functions again until the incoming data has been
diff --git a/library/pk.c b/library/pk.c
index 42ff432..1eab65a 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -232,6 +232,127 @@
     return( ctx->pk_info->can_do( type ) );
 }
 
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/*
+ * Tell if a PK can do the operations of the given PSA algorithm
+ */
+int mbedtls_pk_can_do_ext( const mbedtls_pk_context *ctx, psa_algorithm_t alg,
+                           psa_key_usage_t usage )
+{
+    psa_key_usage_t key_usage;
+
+    /* A context with null pk_info is not set up yet and can't do anything.
+     * For backward compatibility, also accept NULL instead of a context
+     * pointer. */
+    if( ctx == NULL || ctx->pk_info == NULL )
+        return( 0 );
+
+    /* Filter out non allowed algorithms */
+    if( PSA_ALG_IS_ECDSA( alg ) == 0 &&
+        PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) == 0 &&
+        PSA_ALG_IS_RSA_PSS( alg ) == 0 &&
+        alg != PSA_ALG_RSA_PKCS1V15_CRYPT &&
+        PSA_ALG_IS_ECDH( alg ) == 0 )
+        return( 0 );
+
+    /* Filter out non allowed usage flags */
+    if( usage == 0 ||
+        ( usage & ~( PSA_KEY_USAGE_SIGN_HASH |
+                     PSA_KEY_USAGE_DECRYPT |
+                     PSA_KEY_USAGE_DERIVE ) ) != 0 )
+        return( 0 );
+
+    /* Wildcard hash is not allowed */
+    if( PSA_ALG_IS_SIGN_HASH( alg ) &&
+        PSA_ALG_SIGN_GET_HASH( alg ) == PSA_ALG_ANY_HASH )
+        return( 0 );
+
+    if( mbedtls_pk_get_type( ctx ) != MBEDTLS_PK_OPAQUE )
+    {
+        mbedtls_pk_type_t type;
+
+        if( PSA_ALG_IS_ECDSA( alg ) || PSA_ALG_IS_ECDH( alg ) )
+            type = MBEDTLS_PK_ECKEY;
+        else if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) ||
+                 alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
+            type = MBEDTLS_PK_RSA;
+        else if( PSA_ALG_IS_RSA_PSS( alg ) )
+            type = MBEDTLS_PK_RSASSA_PSS;
+        else
+            return( 0 );
+
+        if( ctx->pk_info->can_do( type ) == 0 )
+            return( 0 );
+
+        switch( type )
+        {
+            case MBEDTLS_PK_ECKEY:
+                key_usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_DERIVE;
+                break;
+            case MBEDTLS_PK_RSA:
+            case MBEDTLS_PK_RSASSA_PSS:
+                key_usage = PSA_KEY_USAGE_SIGN_HASH |
+                            PSA_KEY_USAGE_SIGN_MESSAGE |
+                            PSA_KEY_USAGE_DECRYPT;
+                break;
+            default:
+                /* Should never happen */
+                return( 0 );
+        }
+
+        return( ( key_usage & usage ) == usage );
+    }
+
+    const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx->pk_ctx;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_algorithm_t key_alg, key_alg2;
+    psa_status_t status;
+
+    status = psa_get_key_attributes( *key, &attributes );
+    if( status != PSA_SUCCESS )
+        return( 0 );
+
+    key_alg = psa_get_key_algorithm( &attributes );
+    key_alg2 = psa_get_key_enrollment_algorithm( &attributes );
+    key_usage = psa_get_key_usage_flags( &attributes );
+    psa_reset_key_attributes( &attributes );
+
+    if( ( key_usage & usage ) != usage )
+        return( 0 );
+
+    /*
+     * Common case: the key alg or alg2 only allows alg.
+     * This will match PSA_ALG_RSA_PKCS1V15_CRYPT & PSA_ALG_IS_ECDH
+     * directly.
+     * This would also match ECDSA/RSA_PKCS1V15_SIGN/RSA_PSS with
+     * a fixed hash on key_alg/key_alg2.
+     */
+    if( alg == key_alg || alg == key_alg2 )
+            return( 1 );
+
+    /*
+     * If key_alg or key_alg2 is a hash-and-sign with a wildcard for the hash,
+     * and alg is the same hash-and-sign family with any hash,
+     * then alg is compliant with this key alg
+     */
+    if( PSA_ALG_IS_SIGN_HASH( alg ) )
+    {
+
+        if( PSA_ALG_IS_SIGN_HASH( key_alg ) &&
+            PSA_ALG_SIGN_GET_HASH( key_alg ) == PSA_ALG_ANY_HASH &&
+            ( alg & ~PSA_ALG_HASH_MASK ) == ( key_alg & ~PSA_ALG_HASH_MASK ) )
+            return( 1 );
+
+        if( PSA_ALG_IS_SIGN_HASH( key_alg2 ) &&
+            PSA_ALG_SIGN_GET_HASH( key_alg2 ) == PSA_ALG_ANY_HASH &&
+            ( alg & ~PSA_ALG_HASH_MASK ) == ( key_alg2 & ~PSA_ALG_HASH_MASK ) )
+            return( 1 );
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
 /*
  * Helper for mbedtls_pk_sign and mbedtls_pk_verify
  */
diff --git a/library/pk_wrap.c b/library/pk_wrap.c
index 852c46e..e234a8d 100644
--- a/library/pk_wrap.c
+++ b/library/pk_wrap.c
@@ -100,7 +100,8 @@
     }
 }
 
-#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY)
+#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) ||    \
+    defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)
 int mbedtls_pk_error_from_psa_rsa( psa_status_t status )
 {
     switch( status )
@@ -121,7 +122,7 @@
             return( mbedtls_pk_error_from_psa( status ) );
     }
 }
-#endif
+#endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY || PSA_WANT_KEY_TYPE_RSA_KEY_PAIR */
 
 #endif /* MBEDTLS_PSA_CRYPTO_C */
 
@@ -1602,6 +1603,32 @@
     NULL, /* debug - could be done later, or even left NULL */
 };
 
+#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)
+static int pk_opaque_rsa_decrypt( void *ctx,
+                    const unsigned char *input, size_t ilen,
+                    unsigned char *output, size_t *olen, size_t osize,
+                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx;
+    psa_status_t status;
+
+    /* PSA has its own RNG */
+    (void) f_rng;
+    (void) p_rng;
+
+    status = psa_asymmetric_decrypt( *key, PSA_ALG_RSA_PKCS1V15_CRYPT,
+                                     input, ilen,
+                                     NULL, 0,
+                                     output, osize, olen );
+    if( status != PSA_SUCCESS )
+    {
+        return( mbedtls_pk_error_from_psa_rsa( status ) );
+    }
+
+    return 0;
+}
+#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR */
+
 const mbedtls_pk_info_t mbedtls_pk_rsa_opaque_info = {
     MBEDTLS_PK_OPAQUE,
     "Opaque",
@@ -1613,7 +1640,11 @@
     NULL, /* restartable verify - not relevant */
     NULL, /* restartable sign - not relevant */
 #endif
-    NULL, /* decrypt - will be done later */
+#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)
+    pk_opaque_rsa_decrypt,
+#else
+    NULL, /* decrypt - not available */
+#endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY */
     NULL, /* encrypt - will be done later */
     NULL, /* check_pair - could be done later or left NULL */
     pk_opaque_alloc_wrap,
diff --git a/library/pk_wrap.h b/library/pk_wrap.h
index 5e81a65..fc756db 100644
--- a/library/pk_wrap.h
+++ b/library/pk_wrap.h
@@ -148,9 +148,10 @@
 #if defined(MBEDTLS_PSA_CRYPTO_C)
 int mbedtls_pk_error_from_psa( psa_status_t status );
 
-#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY)
+#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) ||    \
+    defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)
 int mbedtls_pk_error_from_psa_rsa( psa_status_t status );
-#endif
+#endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY || PSA_WANT_KEY_TYPE_RSA_KEY_PAIR */
 
 #if defined(MBEDTLS_RSA_C)
 int  mbedtls_pk_psa_rsa_sign_ext( psa_algorithm_t psa_alg_md,
diff --git a/library/pkcs12.c b/library/pkcs12.c
index a90d1f9..e725a97 100644
--- a/library/pkcs12.c
+++ b/library/pkcs12.c
@@ -218,7 +218,7 @@
     unsigned int j;
 
     unsigned char diversifier[128];
-    unsigned char salt_block[128], pwd_block[128], hash_block[128];
+    unsigned char salt_block[128], pwd_block[128], hash_block[128] = {0};
     unsigned char hash_output[MBEDTLS_MD_MAX_SIZE];
     unsigned char *p;
     unsigned char c;
diff --git a/library/pkparse.c b/library/pkparse.c
index 22dab3a..68727ec 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -475,7 +475,7 @@
     }
 
     /*
-     * grp may already be initilialized; if so, make sure IDs match
+     * grp may already be initialized; if so, make sure IDs match
      */
     if( grp->id != MBEDTLS_ECP_DP_NONE && grp->id != grp_id )
         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
@@ -808,7 +808,7 @@
        goto cleanup;
 
 #else
-    /* Verify existance of the CRT params */
+    /* Verify existence of the CRT params */
     if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
         ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
         ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 )
@@ -866,7 +866,7 @@
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     int version, pubkey_done;
     size_t len;
-    mbedtls_asn1_buf params;
+    mbedtls_asn1_buf params = { 0, 0, NULL };
     unsigned char *p = (unsigned char *) key;
     unsigned char *end = p + keylen;
     unsigned char *end2;
diff --git a/library/platform_util.c b/library/platform_util.c
index 3d5cb5b..916a7f4 100644
--- a/library/platform_util.c
+++ b/library/platform_util.c
@@ -74,6 +74,7 @@
 #endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */
 
 #if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
+#define __STDC_WANT_LIB_EXT1__ 1  /* Ask for the C11 gmtime_s() if it's available */
 #include <time.h>
 #if !defined(_WIN32) && (defined(unix) || \
     defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \
@@ -92,9 +93,10 @@
  * threading.h. However, this macro is not part of the Mbed TLS public API, so
  * we keep it private by only defining it in this file
  */
-#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) )
+#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) || \
+      ( defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) )
 #define PLATFORM_UTIL_USE_GMTIME
-#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */
+#endif
 
 #endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) ||     \
              ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) &&                     \
@@ -103,8 +105,13 @@
 struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
                                       struct tm *tm_buf )
 {
-#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
+#if defined(_WIN32) && !defined(PLATFORM_UTIL_USE_GMTIME)
+#if defined(__STDC_LIB_EXT1__)
+    return( ( gmtime_s( tt, tm_buf ) == 0 ) ? NULL : tm_buf );
+#else
+    /* MSVC and mingw64 argument order and return value are inconsistent with the C11 standard */
     return( ( gmtime_s( tm_buf, tt ) == 0 ) ? tm_buf : NULL );
+#endif
 #elif !defined(PLATFORM_UTIL_USE_GMTIME)
     return( gmtime_r( tt, tm_buf ) );
 #else
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index d58923d..c3af7aa 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -913,7 +913,7 @@
         goto error;
     }
 
-    /* Enforce that the usage policy permits the requested algortihm. */
+    /* Enforce that the usage policy permits the requested algorithm. */
     if( alg != 0 )
     {
         status = psa_key_policy_permits( &slot->attr.policy,
@@ -4810,7 +4810,7 @@
 
         /* 4. If k > N - 2, discard the result and return to step 1.
         *    Result of comparison is returned. When it indicates error
-        *    then this fuction is called again.
+        *    then this function is called again.
         */
         MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( &diff_N_2, &k, &key_out_of_range ) );
     }
@@ -5371,7 +5371,6 @@
     *cur++ = MBEDTLS_BYTE_1( data_length );
     *cur++ = MBEDTLS_BYTE_0( data_length );
     memcpy( cur, data, data_length );
-    mbedtls_platform_zeroize( (void*) data, data_length );
     cur += data_length;
 
     status = psa_tls12_prf_set_key( prf, pms, cur - pms );
@@ -5767,6 +5766,22 @@
     if( status != PSA_SUCCESS )
         goto exit;
 
+    /* PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE() is in general an upper bound
+     * for the output size. The PSA specification only guarantees that this
+     * function works if output_size >= PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(...),
+     * but it might be nice to allow smaller buffers if the output fits.
+     * At the time of writing this comment, with only ECDH implemented,
+     * PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE() is exact so the point is moot.
+     * If FFDH is implemented, PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE() can easily
+     * be exact for it as well. */
+    size_t expected_length =
+        PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE( slot->attr.type, slot->attr.bits );
+    if( output_size < expected_length )
+    {
+        status = PSA_ERROR_BUFFER_TOO_SMALL;
+        goto exit;
+    }
+
     status = psa_key_agreement_raw_internal( alg, slot,
                                              peer_key, peer_key_length,
                                              output, output_size,
diff --git a/library/psa_crypto_aead.h b/library/psa_crypto_aead.h
index e82e1cc..17b3953 100644
--- a/library/psa_crypto_aead.h
+++ b/library/psa_crypto_aead.h
@@ -428,7 +428,7 @@
  *   preceding calls to mbedtls_psa_aead_update().
  * - \p tag contains the authentication tag.
  *
- * Whether or not this function returns successfuly, the PSA core subsequently
+ * Whether or not this function returns successfully, the PSA core subsequently
  * calls mbedtls_psa_aead_abort() to deactivate the operation.
  *
  * \param[in,out] operation     Active AEAD operation.
diff --git a/library/psa_crypto_hash.h b/library/psa_crypto_hash.h
index 7091dc5..3bcea59 100644
--- a/library/psa_crypto_hash.h
+++ b/library/psa_crypto_hash.h
@@ -175,7 +175,7 @@
  * This function calculates the hash of the message formed by concatenating
  * the inputs passed to preceding calls to mbedtls_psa_hash_update().
  *
- * When this function returns successfuly, the operation becomes inactive.
+ * When this function returns successfully, the operation becomes inactive.
  * If this function returns an error status, the operation enters an error
  * state and must be aborted by calling mbedtls_psa_hash_abort().
  *
diff --git a/library/rsa.c b/library/rsa.c
index 36f487f..e95768f 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -49,10 +49,6 @@
 
 #include <string.h>
 
-#if defined(MBEDTLS_PKCS1_V21)
-#include "mbedtls/md.h"
-#endif
-
 #if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__) && !defined(__NetBSD__)
 #include <stdlib.h>
 #endif
@@ -852,10 +848,10 @@
  * the more bits of the key can be recovered. See [3].
  *
  * Collecting n collisions with m bit long blinding value requires 2^(m-m/n)
- * observations on avarage.
+ * observations on average.
  *
  * For example with 28 byte blinding to achieve 2 collisions the adversary has
- * to make 2^112 observations on avarage.
+ * to make 2^112 observations on average.
  *
  * (With the currently (as of 2017 April) known best algorithms breaking 2048
  * bit RSA requires approximately as much time as trying out 2^112 random keys.
@@ -1965,7 +1961,7 @@
     size_t observed_salt_len, msb;
     const mbedtls_md_info_t *md_info;
     mbedtls_md_context_t md_ctx;
-    unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
+    unsigned char buf[MBEDTLS_MPI_MAX_SIZE] = {0};
 
     RSA_VALIDATE_RET( ctx != NULL );
     RSA_VALIDATE_RET( sig != NULL );
diff --git a/library/ssl_ciphersuites.c b/library/ssl_ciphersuites.c
index ee8a60e..7deb57a 100644
--- a/library/ssl_ciphersuites.c
+++ b/library/ssl_ciphersuites.c
@@ -1876,15 +1876,26 @@
 
 size_t mbedtls_ssl_ciphersuite_get_cipher_key_bitlen( const mbedtls_ssl_ciphersuite_t *info )
 {
-#if defined(MBEDTLS_CIPHER_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_type_t key_type;
+    psa_algorithm_t alg;
+    size_t key_bits;
+
+    status = mbedtls_ssl_cipher_to_psa( info->cipher,
+                        info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16,
+                        &alg, &key_type, &key_bits );
+
+    if( status != PSA_SUCCESS )
+        return 0;
+
+    return key_bits;
+#else
     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
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
 }
 
 #if defined(MBEDTLS_PK_C)
diff --git a/library/ssl_client.c b/library/ssl_client.c
index 0c32f07..22ca57c 100644
--- a/library/ssl_client.c
+++ b/library/ssl_client.c
@@ -308,110 +308,6 @@
 #endif /* 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
- *
- */
-static int 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 */
-
 static int ssl_write_client_hello_cipher_suites(
             mbedtls_ssl_context *ssl,
             unsigned char *buf,
@@ -721,7 +617,7 @@
 #endif
        0 )
     {
-        ret = ssl_write_sig_alg_ext( ssl, p, end, &output_len );
+        ret = mbedtls_ssl_write_sig_alg_ext( ssl, p, end, &output_len );
         if( ret != 0 )
             return( ret );
         p += output_len;
diff --git a/library/ssl_cookie.c b/library/ssl_cookie.c
index 3be4b45..0f2bc60 100644
--- a/library/ssl_cookie.c
+++ b/library/ssl_cookie.c
@@ -62,7 +62,7 @@
 
 /*
  * Cookies are formed of a 4-bytes timestamp (or serial number) and
- * an HMAC of timestemp and client ID.
+ * an HMAC of timestamp and client ID.
  */
 #define COOKIE_LEN      ( 4 + COOKIE_HMAC_LEN )
 
diff --git a/library/ssl_debug_helpers.h b/library/ssl_debug_helpers.h
index 29b64dc..9f1df73 100644
--- a/library/ssl_debug_helpers.h
+++ b/library/ssl_debug_helpers.h
@@ -41,6 +41,8 @@
 
 const char *mbedtls_ssl_sig_alg_to_str( uint16_t in );
 
+const char *mbedtls_ssl_named_group_to_str( uint16_t in );
+
 #endif /* MBEDTLS_DEBUG_C */
 
 #endif /* SSL_DEBUG_HELPERS_H */
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index e8acc23..9912d6c 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -243,6 +243,18 @@
 
 #define MBEDTLS_RECEIVED_SIG_ALGS_SIZE         20
 
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+
+#define MBEDTLS_TLS_SIG_NONE MBEDTLS_TLS1_3_SIG_NONE
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#define MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG( sig, hash ) (( hash << 8 ) | sig)
+#define MBEDTLS_SSL_TLS12_SIG_ALG_FROM_SIG_AND_HASH_ALG(alg) (alg & 0xFF)
+#define MBEDTLS_SSL_TLS12_HASH_ALG_FROM_SIG_AND_HASH_ALG(alg) (alg >> 8)
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+
 /*
  * Check that we obey the standard's message size bounds
  */
@@ -423,24 +435,6 @@
 extern "C" {
 #endif
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
-    defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
-/*
- * Abstraction for a grid of allowed signature-hash-algorithm pairs.
- */
-struct mbedtls_ssl_sig_hash_set_t
-{
-    /* At the moment, we only need to remember a single suitable
-     * hash algorithm per signature algorithm. As long as that's
-     * the case - and we don't need a general lookup function -
-     * we can implement the sig-hash-set as a map from signatures
-     * to hash algorithms. */
-    mbedtls_md_type_t rsa;
-    mbedtls_md_type_t ecdsa;
-};
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
-          MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
-
 typedef int  mbedtls_ssl_tls_prf_cb( const unsigned char *secret, size_t slen,
                                      const char *label,
                                      const unsigned char *random, size_t rlen,
@@ -515,6 +509,12 @@
     uint8_t sni_authmode;               /*!< authmode from SNI callback     */
 #endif
 
+#if defined(MBEDTLS_SSL_SRV_C)
+    /* Flag indicating if a CertificateRequest message has been sent
+     * to the client or not. */
+    uint8_t certificate_request_sent;
+#endif /* MBEDTLS_SSL_SRV_C */
+
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
     uint8_t new_session_ticket;         /*!< use NewSessionTicket?    */
 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
@@ -585,25 +585,16 @@
      */
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
     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.  */
+    /** Number of HelloRetryRequest messages received/sent from/to the server. */
     int hello_retry_request_count;
-#endif /* MBEDTLS_SSL_CLI_C */
-
 #if defined(MBEDTLS_SSL_SRV_C)
     /** selected_group of key_share extension in HelloRetryRequest message. */
     uint16_t hrr_selected_group;
 #endif /* MBEDTLS_SSL_SRV_C */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
 
-#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 */
-#endif
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
-    defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
     uint16_t received_sig_algs[MBEDTLS_RECEIVED_SIG_ALGS_SIZE];
 #endif
 
@@ -652,9 +643,11 @@
 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     mbedtls_svc_key_id_t psk_opaque;            /*!< Opaque PSK from the callback   */
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
+    uint8_t psk_opaque_is_internal;
+#else
     unsigned char *psk;                 /*!<  PSK from the callback         */
     size_t psk_len;                     /*!<  Length of PSK from callback   */
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
 
 #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
@@ -1116,24 +1109,21 @@
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
     defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
 
-/* Find an entry in a signature-hash set matching a given hash algorithm. */
-mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set,
-                                                 mbedtls_pk_type_t sig_alg );
-/* Add a signature-hash-pair to a signature-hash set */
-void mbedtls_ssl_sig_hash_set_add( mbedtls_ssl_sig_hash_set_t *set,
-                                   mbedtls_pk_type_t sig_alg,
-                                   mbedtls_md_type_t md_alg );
-/* Allow exactly one hash algorithm for each signature. */
-void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set,
-                                          mbedtls_md_type_t md_alg );
+/**
+ * \brief Find the preferred hash for a given signature algorithm.
+ *
+ * \param[in]   ssl     SSL context
+ * \param[in]   sig_alg A signature algorithm identifier as defined in the
+ *                      TLS 1.2 SignatureAlgorithm enumeration.
+ *
+ * \return  The preferred hash algorithm for \p sig_alg. It is a hash algorithm
+ *          identifier as defined in the TLS 1.2 HashAlgorithm enumeration.
+ */
+unsigned int mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg(
+                mbedtls_ssl_context *ssl,
+                unsigned int sig_alg );
 
-/* Setup an empty signature-hash set */
-static inline void mbedtls_ssl_sig_hash_set_init( mbedtls_ssl_sig_hash_set_t *set )
-{
-    mbedtls_ssl_sig_hash_set_const_hash( set, MBEDTLS_MD_NONE );
-}
-
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2) &&
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
           MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
 /**
@@ -1305,12 +1295,34 @@
                                          size_t msg_len );
 
 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+#if !defined(MBEDTLS_USE_PSA_CRYPTO)
 int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl,
                                       mbedtls_key_exchange_type_t key_ex );
+#endif /* !MBEDTLS_USE_PSA_CRYPTO */
 #if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_PROTO_TLS1_2)
 int mbedtls_ssl_conf_has_static_psk( mbedtls_ssl_config const *conf );
 #endif
 
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/**
+ * Get the first defined opaque PSK by order of precedence:
+ * 1. handshake PSK set by \c mbedtls_ssl_set_hs_psk_opaque() in the PSK
+ *    callback
+ * 2. static PSK configured by \c mbedtls_ssl_conf_psk_opaque()
+ * Return an 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 ) )
+        return( ssl->handshake->psk_opaque );
+
+    if( ! mbedtls_svc_key_id_is_null( ssl->conf->psk_opaque ) )
+        return( ssl->conf->psk_opaque );
+
+    return( MBEDTLS_SVC_KEY_ID_INIT );
+}
+#else
 /**
  * Get the first defined PSK by order of precedence:
  * 1. handshake PSK set by \c mbedtls_ssl_set_hs_psk() in the PSK callback
@@ -1341,27 +1353,6 @@
 
     return( 0 );
 }
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-/**
- * Get the first defined opaque PSK by order of precedence:
- * 1. handshake PSK set by \c mbedtls_ssl_set_hs_psk_opaque() in the PSK
- *    callback
- * 2. static PSK configured by \c mbedtls_ssl_conf_psk_opaque()
- * Return an 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 ) )
-        return( ssl->handshake->psk_opaque );
-
-    if( ! mbedtls_svc_key_id_is_null( ssl->conf->psk_opaque ) )
-        return( ssl->conf->psk_opaque );
-
-    return( MBEDTLS_SVC_KEY_ID_INIT );
-}
-
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
@@ -1631,7 +1622,8 @@
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_SSL_PROTO_TLS1_3 */
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
-
+extern const uint8_t mbedtls_ssl_tls13_hello_retry_request_magic[
+                        MBEDTLS_SERVER_HELLO_RANDOM_LEN ];
 int mbedtls_ssl_tls13_process_finished_message( mbedtls_ssl_context *ssl );
 int mbedtls_ssl_tls13_write_finished_message( mbedtls_ssl_context *ssl );
 void mbedtls_ssl_tls13_handshake_wrapup( mbedtls_ssl_context *ssl );
@@ -1803,11 +1795,11 @@
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
 /*
- * Parse TLS 1.3 Signature Algorithm extension
+ * Parse TLS Signature Algorithm extension
  */
-int mbedtls_ssl_tls13_parse_sig_alg_ext( mbedtls_ssl_context *ssl,
-                                         const unsigned char *buf,
-                                         const unsigned char *end );
+int mbedtls_ssl_parse_sig_alg_ext( mbedtls_ssl_context *ssl,
+                                   const unsigned char *buf,
+                                   const unsigned char *end );
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
 /* Get handshake transcript */
@@ -1853,7 +1845,7 @@
             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 */
+            /* Below deprecated 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 ||
@@ -1953,7 +1945,7 @@
     if( sig_alg == NULL )
         return( 0 );
 
-    for( ; *sig_alg != MBEDTLS_TLS1_3_SIG_NONE; sig_alg++ )
+    for( ; *sig_alg != MBEDTLS_TLS_SIG_NONE; sig_alg++ )
     {
         if( *sig_alg == own_sig_alg )
             return( 1 );
@@ -1969,7 +1961,7 @@
     if( sig_alg == NULL )
         return( 0 );
 
-    for( ; *sig_alg != MBEDTLS_TLS1_3_SIG_NONE; sig_alg++ )
+    for( ; *sig_alg != MBEDTLS_TLS_SIG_NONE; sig_alg++ )
     {
         if( *sig_alg == proposed_sig_alg )
             return( 1 );
@@ -2151,22 +2143,9 @@
 }
 #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 */
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
 /* Corresponding PSA algorithm for MBEDTLS_CIPHER_NULL.
- * Same value is used fo PSA_ALG_CATEGORY_CIPHER, hence it is
+ * Same value is used for PSA_ALG_CATEGORY_CIPHER, hence it is
  * guaranteed to not be a valid PSA algorithm identifier.
  */
 #define MBEDTLS_SSL_NULL_CIPHER 0x04000000
@@ -2194,9 +2173,7 @@
                                     psa_algorithm_t *alg,
                                     psa_key_type_t *key_type,
                                     size_t *key_size );
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
-#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
 /**
  * \brief       Convert given PSA status to mbedtls error code.
  *
@@ -2290,4 +2267,7 @@
     mbedtls_ssl_protocol_version min_tls_version,
     mbedtls_ssl_protocol_version max_tls_version );
 
+int mbedtls_ssl_write_sig_alg_ext( mbedtls_ssl_context *ssl, unsigned char *buf,
+                                   const unsigned char *end, size_t *out_len );
+
 #endif /* ssl_misc.h */
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index 083c8d2..e1ea440 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -1234,7 +1234,7 @@
                                add_data, add_data_len );
 
         /* Because of the check above, we know that there are
-         * explicit_iv_len Bytes preceeding data, and taglen
+         * explicit_iv_len Bytes preceding data, and taglen
          * bytes following data + data_len. This justifies
          * the debug message and the invocation of
          * mbedtls_cipher_auth_decrypt_ext() below. */
@@ -2404,7 +2404,7 @@
                                      unsigned char **buf, size_t *buf_len )
 {
     /*
-     * Reserve 4 bytes for hanshake header. ( Section 4,RFC 8446 )
+     * Reserve 4 bytes for handshake header. ( Section 4,RFC 8446 )
      *    ...
      *    HandshakeType msg_type;
      *    uint24 length;
diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c
index 1c05001..a924a2a 100644
--- a/library/ssl_ticket.c
+++ b/library/ssl_ticket.c
@@ -37,7 +37,7 @@
 #include <string.h>
 
 /*
- * Initialze context
+ * Initialize context
  */
 void mbedtls_ssl_ticket_init( mbedtls_ssl_ticket_context *ctx )
 {
@@ -70,7 +70,7 @@
                                unsigned char index )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    unsigned char buf[MAX_KEY_BYTES];
+    unsigned char buf[MAX_KEY_BYTES] = {0};
     mbedtls_ssl_ticket_key *key = ctx->keys + index;
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 250bae9..5331865 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -616,11 +616,6 @@
 
     handshake->update_checksum = ssl_update_checksum_start;
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
-    defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
-    mbedtls_ssl_sig_hash_set_init( &handshake->hash_algs );
-#endif
-
 #if defined(MBEDTLS_DHM_C)
     mbedtls_dhm_init( &handshake->dhm_ctx );
 #endif
@@ -852,7 +847,7 @@
             p++;
 #endif
         }
-        *p = MBEDTLS_TLS1_3_SIG_NONE;
+        *p = MBEDTLS_TLS_SIG_NONE;
         ssl->handshake->sig_algs_heap_allocated = 1;
     }
     else
@@ -1528,7 +1523,6 @@
     if( !mbedtls_svc_key_id_is_null( conf->psk_opaque ) )
         return( 1 );
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
-
     if( conf->psk != NULL )
         return( 1 );
 
@@ -1545,11 +1539,6 @@
          * user's responsibility. */
         conf->psk_opaque = MBEDTLS_SVC_KEY_ID_INIT;
     }
-    /* This and the following branch should never
-     * be taken simultaenously as we maintain the
-     * invariant that raw and opaque PSKs are never
-     * configured simultaneously. As a safeguard,
-     * though, `else` is omitted here. */
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
     if( conf->psk != NULL )
     {
@@ -1631,10 +1620,16 @@
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     if( ! mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) )
     {
+        /* The maintenance of the external PSK key slot is the
+         * user's responsibility. */
+        if( ssl->handshake->psk_opaque_is_internal )
+        {
+            psa_destroy_key( ssl->handshake->psk_opaque );
+            ssl->handshake->psk_opaque_is_internal = 0;
+        }
         ssl->handshake->psk_opaque = MBEDTLS_SVC_KEY_ID_INIT;
     }
-    else
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
+#else
     if( ssl->handshake->psk != NULL )
     {
         mbedtls_platform_zeroize( ssl->handshake->psk,
@@ -1642,11 +1637,19 @@
         mbedtls_free( ssl->handshake->psk );
         ssl->handshake->psk_len = 0;
     }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
 }
 
 int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
                             const unsigned char *psk, size_t psk_len )
 {
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    psa_key_attributes_t key_attributes = psa_key_attributes_init();
+    psa_status_t status;
+    psa_algorithm_t alg;
+    mbedtls_svc_key_id_t key;
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
     if( psk == NULL || ssl->handshake == NULL )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
@@ -1655,6 +1658,24 @@
 
     ssl_remove_psk( ssl );
 
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    if( ssl->handshake->ciphersuite_info->mac == MBEDTLS_MD_SHA384)
+        alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384);
+    else
+        alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256);
+
+    psa_set_key_usage_flags( &key_attributes, PSA_KEY_USAGE_DERIVE );
+    psa_set_key_algorithm( &key_attributes, alg );
+    psa_set_key_type( &key_attributes, PSA_KEY_TYPE_DERIVE );
+
+    status = psa_import_key( &key_attributes, psk, psk_len, &key );
+    if( status != PSA_SUCCESS )
+        return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+
+    /* Allow calling psa_destroy_key() on psk remove */
+    ssl->handshake->psk_opaque_is_internal = 1;
+    return mbedtls_ssl_set_hs_psk_opaque( ssl, key );
+#else
     if( ( ssl->handshake->psk = mbedtls_calloc( 1, psk_len ) ) == NULL )
         return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
 
@@ -1662,6 +1683,7 @@
     memcpy( ssl->handshake->psk, psk, ssl->handshake->psk_len );
 
     return( 0 );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
 }
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
@@ -1816,7 +1838,7 @@
     return( mbedtls_ssl_get_actual_mode( base_mode, encrypt_then_mac ) );
 }
 
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
 psa_status_t mbedtls_ssl_cipher_to_psa( mbedtls_cipher_type_t mbedtls_cipher_type,
                                     size_t taglen,
                                     psa_algorithm_t *alg,
@@ -1961,7 +1983,7 @@
 
     return PSA_SUCCESS;
 }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
+#endif /* MBEDTLS_USE_PSA_CRYPTO || MBEDTLS_SSL_PROTO_TLS1_3 */
 
 #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
 int mbedtls_ssl_conf_dh_param_bin( mbedtls_ssl_config *conf,
@@ -2891,7 +2913,7 @@
      * In the case of TLS 1.3, handshake step handlers do not send data to the
      * peer. Data are only sent here and through
      * `mbedtls_ssl_handle_pending_alert` in case an error that triggered an
-     * alert occured.
+     * alert occurred.
      */
     if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
         return( ret );
@@ -3231,11 +3253,25 @@
 #endif
 
 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    if( ! mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) )
+    {
+        /* The maintenance of the external PSK key slot is the
+         * user's responsibility. */
+        if( ssl->handshake->psk_opaque_is_internal )
+        {
+            psa_destroy_key( ssl->handshake->psk_opaque );
+            ssl->handshake->psk_opaque_is_internal = 0;
+        }
+        ssl->handshake->psk_opaque = MBEDTLS_SVC_KEY_ID_INIT;
+    }
+#else
     if( handshake->psk != NULL )
     {
         mbedtls_platform_zeroize( handshake->psk, handshake->psk_len );
         mbedtls_free( handshake->psk );
     }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
 #endif
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C) && \
@@ -3976,7 +4012,7 @@
 }
 
 /*
- * Initialze mbedtls_ssl_config
+ * Initialize mbedtls_ssl_config
  */
 void mbedtls_ssl_config_init( mbedtls_ssl_config *conf )
 {
@@ -4102,22 +4138,37 @@
     MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256,
 #endif /* MBEDTLS_RSA_C && MBEDTLS_SHA256_C */
 
-    MBEDTLS_TLS1_3_SIG_NONE
+    MBEDTLS_TLS_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 )
+#if defined(MBEDTLS_ECDSA_C)
+    MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG( MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA512 ),
 #endif
+#if defined(MBEDTLS_RSA_C)
+    MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG( MBEDTLS_SSL_SIG_RSA, MBEDTLS_SSL_HASH_SHA512 ),
+#endif
+#endif /* MBEDTLS_SHA512_C */
 #if defined(MBEDTLS_SHA384_C)
-    MBEDTLS_SSL_SIG_ALG( MBEDTLS_SSL_HASH_SHA384 )
+#if defined(MBEDTLS_ECDSA_C)
+    MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG( MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA384 ),
 #endif
+#if defined(MBEDTLS_RSA_C)
+    MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG( MBEDTLS_SSL_SIG_RSA, MBEDTLS_SSL_HASH_SHA384 ),
+#endif
+#endif /* MBEDTLS_SHA384_C */
 #if defined(MBEDTLS_SHA256_C)
-    MBEDTLS_SSL_SIG_ALG( MBEDTLS_SSL_HASH_SHA256 )
+#if defined(MBEDTLS_ECDSA_C)
+    MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG( MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA256 ),
 #endif
-    MBEDTLS_TLS1_3_SIG_NONE
+#if defined(MBEDTLS_RSA_C)
+    MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG( MBEDTLS_SSL_SIG_RSA, MBEDTLS_SSL_HASH_SHA256 ),
+#endif
+#endif /* MBEDTLS_SHA256_C */
+    MBEDTLS_TLS_SIG_NONE
 };
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 /* NOTICE: see above */
@@ -4143,19 +4194,29 @@
     MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256,
 #endif /* MBEDTLS_RSA_C && MBEDTLS_SHA256_C */
 
-    MBEDTLS_TLS1_3_SIG_NONE
+    MBEDTLS_TLS_SIG_NONE
 };
 
 /* 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 )
+#if defined(MBEDTLS_ECDSA_C)
+    MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG( MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA256 ),
 #endif
+#if defined(MBEDTLS_RSA_C)
+    MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG( MBEDTLS_SSL_SIG_RSA, MBEDTLS_SSL_HASH_SHA256 ),
+#endif
+#endif /* MBEDTLS_SHA256_C */
 #if defined(MBEDTLS_SHA384_C)
-    MBEDTLS_SSL_SIG_ALG( MBEDTLS_SSL_HASH_SHA384 )
+#if defined(MBEDTLS_ECDSA_C)
+    MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG( MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA384 ),
 #endif
-    MBEDTLS_TLS1_3_SIG_NONE
+#if defined(MBEDTLS_RSA_C)
+    MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG( MBEDTLS_SSL_SIG_RSA, MBEDTLS_SSL_HASH_SHA384 ),
+#endif
+#endif /* MBEDTLS_SHA256_C */
+    MBEDTLS_TLS_SIG_NONE
 };
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
@@ -4179,7 +4240,7 @@
     size_t i, j;
     int ret = 0;
 
-    for( i = 0; sig_algs[i] != MBEDTLS_TLS1_3_SIG_NONE; i++ )
+    for( i = 0; sig_algs[i] != MBEDTLS_TLS_SIG_NONE; i++ )
     {
         for( j = 0; j < i; j++ )
         {
@@ -4424,6 +4485,12 @@
 #endif
 
 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    if( ! mbedtls_svc_key_id_is_null( conf->psk_opaque ) )
+    {
+        conf->psk_opaque = MBEDTLS_SVC_KEY_ID_INIT;
+    }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
     if( conf->psk != NULL )
     {
         mbedtls_platform_zeroize( conf->psk, conf->psk_len );
@@ -4805,6 +4872,109 @@
 
 #endif /* !MBEDTLS_USE_PSA_CRYPTO */
 
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+/* mbedtls_ssl_parse_sig_alg_ext()
+ *
+ * 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_parse_sig_alg_ext( mbedtls_ssl_context *ssl,
+                                   const unsigned char *buf,
+                                   const unsigned char *end )
+{
+    const unsigned char *p = buf;
+    size_t supported_sig_algs_len = 0;
+    const unsigned char *supported_sig_algs_end;
+    uint16_t sig_alg;
+    uint32_t common_idx = 0;
+
+    MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, 2 );
+    supported_sig_algs_len = MBEDTLS_GET_UINT16_BE( p, 0 );
+    p += 2;
+
+    memset( ssl->handshake->received_sig_algs, 0,
+            sizeof(ssl->handshake->received_sig_algs) );
+
+    MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, supported_sig_algs_len );
+    supported_sig_algs_end = p + supported_sig_algs_len;
+    while( p < supported_sig_algs_end )
+    {
+        MBEDTLS_SSL_CHK_BUF_READ_PTR( p, supported_sig_algs_end, 2 );
+        sig_alg = MBEDTLS_GET_UINT16_BE( p, 0 );
+        p += 2;
+
+        MBEDTLS_SSL_DEBUG_MSG( 4, ( "received signature algorithm: 0x%x",
+                                    sig_alg ) );
+
+        if( ! mbedtls_ssl_sig_alg_is_supported( ssl, sig_alg ) ||
+            ! mbedtls_ssl_sig_alg_is_offered( ssl, sig_alg ) )
+            continue;
+
+        if( common_idx + 1 < MBEDTLS_RECEIVED_SIG_ALGS_SIZE )
+        {
+            ssl->handshake->received_sig_algs[common_idx] = sig_alg;
+            common_idx += 1;
+        }
+    }
+    /* Check that we consumed all the message. */
+    if( p != end )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1,
+            ( "Signature algorithms extension length misaligned" ) );
+        MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
+                                      MBEDTLS_ERR_SSL_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
+    }
+
+    if( common_idx == 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "no signature algorithm in common" ) );
+        MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
+                                      MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
+    }
+
+    ssl->handshake->received_sig_algs[common_idx] = MBEDTLS_TLS_SIG_NONE;
+    return( 0 );
+}
+
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
@@ -4812,6 +4982,7 @@
 static psa_status_t setup_psa_key_derivation( psa_key_derivation_operation_t* derivation,
                                               mbedtls_svc_key_id_t key,
                                               psa_algorithm_t alg,
+                                              const unsigned char* raw_psk, size_t raw_psk_length,
                                               const unsigned char* seed, size_t seed_length,
                                               const unsigned char* label, size_t label_length,
                                               const unsigned char* other_secret,
@@ -4845,7 +5016,7 @@
         {
             status = psa_key_derivation_input_bytes(
                 derivation, PSA_KEY_DERIVATION_INPUT_SECRET,
-                NULL, 0 );
+                raw_psk, raw_psk_length );
         }
         else
         {
@@ -4911,6 +5082,7 @@
 
     status = setup_psa_key_derivation( &derivation,
                                        master_key, alg,
+                                       NULL, 0,
                                        random, rlen,
                                        (unsigned char const *) label,
                                        (size_t) strlen( label ),
@@ -5100,30 +5272,6 @@
     return( 0 );
 }
 
-
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO) &&                   \
-    defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED )
-static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl )
-{
-    if( ssl->conf->f_psk != NULL )
-    {
-        /* If we've used a callback to select the PSK,
-         * the static configuration is irrelevant. */
-        if( ! mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) )
-            return( 1 );
-
-        return( 0 );
-    }
-
-    if( ! mbedtls_svc_key_id_is_null( ssl->conf->psk_opaque ) )
-        return( 1 );
-
-    return( 0 );
-}
-#endif /* MBEDTLS_USE_PSA_CRYPTO &&
-          MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
-
 /*
  * Compute master secret if needed
  *
@@ -5196,8 +5344,7 @@
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO) &&                   \
     defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
-    if( mbedtls_ssl_ciphersuite_uses_psk( handshake->ciphersuite_info ) == 1 &&
-        ssl_use_opaque_psk( ssl ) == 1 )
+    if( mbedtls_ssl_ciphersuite_uses_psk( handshake->ciphersuite_info ) == 1 )
     {
         /* Perform PSK-to-MS expansion in a single step. */
         psa_status_t status;
@@ -5240,6 +5387,7 @@
         }
 
         status = setup_psa_key_derivation( &derivation, psk, alg,
+                                           ssl->conf->psk, ssl->conf->psk_len,
                                            seed, seed_len,
                                            (unsigned char const *) lbl,
                                            (size_t) strlen( lbl ),
@@ -5472,7 +5620,8 @@
 }
 #endif /* MBEDTLS_SHA384_C */
 
-#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+#if !defined(MBEDTLS_USE_PSA_CRYPTO) &&                      \
+    defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
 int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex )
 {
     unsigned char *p = ssl->handshake->premaster;
@@ -5481,11 +5630,6 @@
     size_t psk_len = 0;
     int psk_ret = mbedtls_ssl_get_psk( ssl, &psk, &psk_len );
 
-#if defined(MBEDTLS_USE_PSA_CRYPTO) &&                 \
-    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
-    (void) key_ex;
-#endif /* MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
-
     if( psk_ret == MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED )
     {
         /*
@@ -5560,19 +5704,10 @@
         p += 2 + len;
 
         MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K  );
-
-        /* For opaque PSK fill premaster with the the shared secret without PSK. */
-        if( psk_ret == MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 1,
-                ( "skip PMS generation for opaque DHE-PSK" ) );
-            return( 0 );
-        }
     }
     else
 #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
-#if !defined(MBEDTLS_USE_PSA_CRYPTO) &&                 \
-    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
     if( key_ex == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
     {
         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -5593,7 +5728,7 @@
                                 MBEDTLS_DEBUG_ECDH_Z );
     }
     else
-#endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
@@ -5616,7 +5751,7 @@
 
     return( 0 );
 }
-#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
+#endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
 
 #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
 static int ssl_write_hello_request( mbedtls_ssl_context *ssl );
@@ -6602,7 +6737,7 @@
     ssl->handshake = NULL;
 
     /*
-     * Free the previous transform and swith in the current one
+     * Free the previous transform and switch in the current one
      */
     if( ssl->transform )
     {
@@ -7543,49 +7678,26 @@
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
 
-/* Find an entry in a signature-hash set matching a given hash algorithm. */
-mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set,
-                                                 mbedtls_pk_type_t sig_alg )
+/* Find the preferred hash for a given signature algorithm. */
+unsigned int mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg(
+                mbedtls_ssl_context *ssl,
+                unsigned int sig_alg )
 {
-    switch( sig_alg )
+    unsigned int i;
+    uint16_t *received_sig_algs = ssl->handshake->received_sig_algs;
+
+    if( sig_alg == MBEDTLS_SSL_SIG_ANON )
+        return( MBEDTLS_SSL_HASH_NONE );
+
+    for( i = 0; received_sig_algs[i] != MBEDTLS_TLS_SIG_NONE; i++ )
     {
-        case MBEDTLS_PK_RSA:
-            return( set->rsa );
-        case MBEDTLS_PK_ECDSA:
-            return( set->ecdsa );
-        default:
-            return( MBEDTLS_MD_NONE );
+        if( sig_alg == MBEDTLS_SSL_TLS12_SIG_ALG_FROM_SIG_AND_HASH_ALG(
+                            received_sig_algs[i] ) )
+            return( MBEDTLS_SSL_TLS12_HASH_ALG_FROM_SIG_AND_HASH_ALG(
+                        received_sig_algs[i] ) );
     }
-}
 
-/* Add a signature-hash-pair to a signature-hash set */
-void mbedtls_ssl_sig_hash_set_add( mbedtls_ssl_sig_hash_set_t *set,
-                                   mbedtls_pk_type_t sig_alg,
-                                   mbedtls_md_type_t md_alg )
-{
-    switch( sig_alg )
-    {
-        case MBEDTLS_PK_RSA:
-            if( set->rsa == MBEDTLS_MD_NONE )
-                set->rsa = md_alg;
-            break;
-
-        case MBEDTLS_PK_ECDSA:
-            if( set->ecdsa == MBEDTLS_MD_NONE )
-                set->ecdsa = md_alg;
-            break;
-
-        default:
-            break;
-    }
-}
-
-/* Allow exactly one hash algorithm for each signature. */
-void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set,
-                                          mbedtls_md_type_t md_alg )
-{
-    set->rsa   = md_alg;
-    set->ecdsa = md_alg;
+    return( MBEDTLS_SSL_HASH_NONE );
 }
 
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
@@ -7998,4 +8110,104 @@
     return( 0 );
 }
 
+#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 );
+    }
+
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SIG_ALG, buf, 0 );
+    MBEDTLS_PUT_UINT16_BE( supported_sig_alg_len + 2, buf, 2 );
+    MBEDTLS_PUT_UINT16_BE( supported_sig_alg_len, buf, 4 );
+
+    *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_tls12_client.c b/library/ssl_tls12_client.c
index d286764..f516efa 100644
--- a/library/ssl_tls12_client.c
+++ b/library/ssl_tls12_client.c
@@ -62,37 +62,16 @@
         return( 0 );
     }
 
-    if( conf->psk != NULL && conf->psk_len != 0 )
-        return( 1 );
-
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     if( ! mbedtls_svc_key_id_is_null( conf->psk_opaque ) )
         return( 1 );
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 
-    return( 0 );
-}
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
-    ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ) || \
-      defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) )
-static int ssl_conf_has_static_raw_psk( mbedtls_ssl_config const *conf )
-{
-    if( conf->psk_identity     == NULL ||
-        conf->psk_identity_len == 0     )
-    {
-        return( 0 );
-    }
-
     if( conf->psk != NULL && conf->psk_len != 0 )
         return( 1 );
 
     return( 0 );
 }
-#endif /* MBEDTLS_USE_PSA_CRYPTO &&
-          ( MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
-            MBEDTLS_KEY_EXCHANGE_PSK_ENABLED ) */
-
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
 
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
@@ -2297,7 +2276,7 @@
                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
             return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
-    } /* FALLTROUGH */
+    } /* FALLTHROUGH */
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) ||                       \
@@ -3067,41 +3046,6 @@
         /* Write the ECDH computation length before the ECDH computation */
         MBEDTLS_PUT_UINT16_BE( zlen, pms, 0 );
         pms += zlen_size + zlen;
-
-        /* In case of opaque psk skip writting psk to pms.
-         * Opaque key will be handled later. */
-        if( ssl_conf_has_static_raw_psk( ssl->conf ) == 1 )
-        {
-            const unsigned char *psk = NULL;
-            size_t psk_len = 0;
-
-            if( mbedtls_ssl_get_psk( ssl, &psk, &psk_len )
-                    == MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED )
-                /*
-                * This should never happen because the existence of a PSK is always
-                * checked before calling this function
-                */
-                return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-
-            /* opaque psk<0..2^16-1>; */
-            if( (size_t)( pms_end - pms ) < ( 2 + psk_len ) )
-                return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-            /* Write the PSK length as uint16 */
-            MBEDTLS_PUT_UINT16_BE( psk_len, pms, 0 );
-            pms += 2;
-
-            /* Write the PSK itself */
-            memcpy( pms, psk, psk_len );
-            pms += psk_len;
-
-            ssl->handshake->pmslen = pms - ssl->handshake->premaster;
-        }
-        else
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 1,
-                ( "skip PMS generation for opaque ECDHE-PSK" ) );
-        }
     }
     else
 #endif /* MBEDTLS_USE_PSA_CRYPTO &&
@@ -3182,6 +3126,25 @@
                 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
                 return( ret );
             }
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+            unsigned char *pms = ssl->handshake->premaster;
+            unsigned char *pms_end = pms + sizeof( ssl->handshake->premaster );
+            size_t pms_len;
+
+            /* Write length only when we know the actual value */
+            if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
+                                          pms + 2, pms_end - ( pms + 2 ), &pms_len,
+                                          ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+            {
+                MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
+                return( ret );
+            }
+            MBEDTLS_PUT_UINT16_BE( pms_len, pms, 0 );
+            pms += 2 + pms_len;
+
+            MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K  );
+#endif
         }
         else
 #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
@@ -3213,31 +3176,15 @@
             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
         }
 
-#if defined(MBEDTLS_USE_PSA_CRYPTO) &&          \
-    defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
-        if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK &&
-            ssl_conf_has_static_raw_psk( ssl->conf ) == 0 )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 1,
-                ( "skip PMS generation for opaque PSK" ) );
-        }
-        else
-        if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK &&
-            ssl_conf_has_static_raw_psk( ssl->conf ) == 0 )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 1,
-                ( "skip PMS generation for opaque RSA-PSK" ) );
-        }
-        else
-#endif /* MBEDTLS_USE_PSA_CRYPTO &&
-          MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
+#if !defined(MBEDTLS_USE_PSA_CRYPTO)
         if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
                         ciphersuite_info->key_exchange ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1,
-                "mbedtls_ssl_psk_derive_premaster", ret );
+                    "mbedtls_ssl_psk_derive_premaster", ret );
             return( ret );
         }
+#endif /* !MBEDTLS_USE_PSA_CRYPTO */
     }
     else
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c
index a60b5ad..1c9e5cd 100644
--- a/library/ssl_tls12_server.c
+++ b/library/ssl_tls12_server.c
@@ -160,43 +160,17 @@
     if( conf->psk_identity_len == 0 || conf->psk_identity == NULL )
         return( 0 );
 
-    if( conf->psk != NULL && conf->psk_len != 0 )
-        return( 1 );
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     if( ! mbedtls_svc_key_id_is_null( conf->psk_opaque ) )
         return( 1 );
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 
-    return( 0 );
-}
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
-    ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ) || \
-      defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) ||        \
-      defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) )
-static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl )
-{
-    if( ssl->conf->f_psk != NULL )
-    {
-        /* If we've used a callback to select the PSK,
-         * the static configuration is irrelevant. */
-
-        if( ! mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) )
-            return( 1 );
-
-        return( 0 );
-    }
-
-    if( ! mbedtls_svc_key_id_is_null( ssl->conf->psk_opaque ) )
+    if( conf->psk != NULL && conf->psk_len != 0 )
         return( 1 );
 
     return( 0 );
 }
-#endif /* MBEDTLS_USE_PSA_CRYPTO &&
-          ( MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
-            MBEDTLS_KEY_EXCHANGE_PSK_ENABLED ||
-            MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) */
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
 
 static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
@@ -235,96 +209,6 @@
     return( 0 );
 }
 
-#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
-
-/*
- * Status of the implementation of signature-algorithms extension:
- *
- * Currently, we are only considering the signature-algorithm extension
- * to pick a ciphersuite which allows us to send the ServerKeyExchange
- * message with a signature-hash combination that the user allows.
- *
- * We do *not* check whether all certificates in our certificate
- * chain are signed with an allowed signature-hash pair.
- * This needs to be done at a later stage.
- *
- */
-static int ssl_parse_sig_alg_ext( mbedtls_ssl_context *ssl,
-                                  const unsigned char *buf,
-                                  size_t len )
-{
-    size_t sig_alg_list_size;
-
-    const unsigned char *p;
-    const unsigned char *end = buf + len;
-
-    mbedtls_md_type_t md_cur;
-    mbedtls_pk_type_t sig_cur;
-
-    if ( len < 2 ) {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                       MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
-    }
-    sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
-    if( sig_alg_list_size + 2 != len ||
-        sig_alg_list_size % 2 != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
-    }
-
-    /* Currently we only guarantee signing the ServerKeyExchange message according
-     * to the constraints specified in this extension (see above), so it suffices
-     * to remember only one suitable hash for each possible signature algorithm.
-     *
-     * This will change when we also consider certificate signatures,
-     * in which case we will need to remember the whole signature-hash
-     * pair list from the extension.
-     */
-
-    for( p = buf + 2; p < end; p += 2 )
-    {
-        /* Silently ignore unknown signature or hash algorithms. */
-
-        if( ( sig_cur = mbedtls_ssl_pk_alg_from_sig( p[1] ) ) == MBEDTLS_PK_NONE )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext"
-                                        " unknown sig alg encoding %d", p[1] ) );
-            continue;
-        }
-
-        /* Check if we support the hash the user proposes */
-        md_cur = mbedtls_ssl_md_alg_from_hash( p[0] );
-        if( md_cur == MBEDTLS_MD_NONE )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext:"
-                                        " unknown hash alg encoding %d", p[0] ) );
-            continue;
-        }
-
-        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:"
-                                        " match sig %u and hash %u",
-                                        (unsigned) sig_cur, (unsigned) md_cur ) );
-        }
-        else
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: "
-                                        "hash alg %u not supported", (unsigned) md_cur ) );
-        }
-    }
-
-    return( 0 );
-}
-#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
-
 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
 /*
@@ -1104,7 +988,8 @@
      * a suitable hash algorithm is present. */
     sig_type = mbedtls_ssl_get_ciphersuite_sig_alg( suite_info );
     if( sig_type != MBEDTLS_PK_NONE &&
-        mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs, sig_type ) == MBEDTLS_MD_NONE )
+        mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg(
+            ssl, mbedtls_ssl_sig_from_pk_alg( sig_type ) ) == MBEDTLS_SSL_HASH_NONE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no suitable hash algorithm "
                                     "for signature algorithm %u", (unsigned) sig_type ) );
@@ -1287,7 +1172,7 @@
      * Handshake layer:
      *     0  .   0   handshake type
      *     1  .   3   handshake length
-     *     4  .   5   DTLS only: message seqence number
+     *     4  .   5   DTLS only: message sequence number
      *     6  .   8   DTLS only: fragment offset
      *     9  .  11   DTLS only: fragment length
      */
@@ -1619,7 +1504,7 @@
             case MBEDTLS_TLS_EXT_SIG_ALG:
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
 
-                ret = ssl_parse_sig_alg_ext( ssl, ext + 4, ext_size );
+                ret = mbedtls_ssl_parse_sig_alg_ext( ssl, ext + 4, ext + 4 + ext_size );
                 if( ret != 0 )
                     return( ret );
 
@@ -1743,18 +1628,27 @@
      * Try to fall back to default hash SHA1 if the client
      * hasn't provided any preferred signature-hash combinations.
      */
-    if( sig_hash_alg_ext_present == 0 )
+    if( ! sig_hash_alg_ext_present )
     {
-        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;
-        }
+        uint16_t *received_sig_algs = ssl->handshake->received_sig_algs;
+        const uint16_t default_sig_algs[] = {
+#if defined(MBEDTLS_ECDSA_C)
+            MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG( MBEDTLS_SSL_SIG_ECDSA,
+                                                MBEDTLS_SSL_HASH_SHA1 ),
+#endif
+#if defined(MBEDTLS_RSA_C)
+            MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG( MBEDTLS_SSL_SIG_RSA,
+                                                MBEDTLS_SSL_HASH_SHA1 ),
+#endif
+            MBEDTLS_TLS_SIG_NONE
+        };
 
-        mbedtls_ssl_sig_hash_set_const_hash( &ssl->handshake->hash_algs,
-                                             md_default );
+#if defined(static_assert)
+        static_assert( sizeof( default_sig_algs ) / sizeof( default_sig_algs[0] ) <=
+                       MBEDTLS_RECEIVED_SIG_ALGS_SIZE, "default_sig_algs is too big" );
+#endif
+
+        memcpy( received_sig_algs, default_sig_algs, sizeof( default_sig_algs ) );
     }
 
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
@@ -1915,10 +1809,10 @@
     mbedtls_pk_type_t sig_alg = mbedtls_ssl_get_ciphersuite_sig_alg( ciphersuite_info );
     if( sig_alg != MBEDTLS_PK_NONE )
     {
-        mbedtls_md_type_t md_alg = mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs,
-                                                              sig_alg );
-        MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: %d",
-                                    mbedtls_ssl_hash_from_md_alg( md_alg ) ) );
+        unsigned int sig_hash = mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg(
+                                    ssl, mbedtls_ssl_sig_from_pk_alg( sig_alg ) );
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: %u",
+                                    sig_hash ) );
     }
     else
     {
@@ -2610,8 +2504,9 @@
 
 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
-    if ( mbedtls_ssl_ciphersuite_uses_ec(
-         mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite ) ) )
+    const mbedtls_ssl_ciphersuite_t *suite =
+        mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite );
+    if ( suite != NULL && mbedtls_ssl_ciphersuite_uses_ec( suite) )
     {
         ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
         ext_len += olen;
@@ -2754,7 +2649,7 @@
     if( sig_alg == NULL )
         return( MBEDTLS_ERR_SSL_BAD_CONFIG );
 
-    for( ; *sig_alg != MBEDTLS_TLS1_3_SIG_NONE; sig_alg++ )
+    for( ; *sig_alg != MBEDTLS_TLS_SIG_NONE; sig_alg++ )
     {
         unsigned char hash = MBEDTLS_BYTE_1( *sig_alg );
 
@@ -2931,7 +2826,14 @@
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
-    if( ! mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECKEY ) )
+    const mbedtls_pk_context *private_key = mbedtls_ssl_own_key( ssl );
+    if( private_key == NULL)
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no server private key" ) );
+        return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
+    }
+
+    if( ! mbedtls_pk_can_do( private_key, MBEDTLS_PK_ECKEY ) )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
         return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
@@ -3266,6 +3168,12 @@
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
     if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) )
     {
+        if( dig_signed == NULL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+
         size_t dig_signed_len = ssl->out_msg + ssl->out_msglen - dig_signed;
         size_t hashlen = 0;
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
@@ -3281,15 +3189,18 @@
          *      to choose appropriate hash.
          */
 
-        mbedtls_md_type_t md_alg;
         mbedtls_pk_type_t sig_alg =
             mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
 
+        unsigned int sig_hash =
+            mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg(
+                ssl, mbedtls_ssl_sig_from_pk_alg( sig_alg ) );
+
+        mbedtls_md_type_t md_alg = mbedtls_ssl_md_alg_from_hash( sig_hash );
+
         /*    For TLS 1.2, obey signature-hash-algorithm extension
          *    (RFC 5246, Sec. 7.4.1.4.1). */
-        if( sig_alg == MBEDTLS_PK_NONE ||
-            ( md_alg = mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs,
-                                                      sig_alg ) ) == MBEDTLS_MD_NONE )
+        if( sig_alg == MBEDTLS_PK_NONE || md_alg == MBEDTLS_MD_NONE )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
             /* (... because we choose a cipher suite
@@ -4009,19 +3920,14 @@
             return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-        /* For opaque PSKs, we perform the PSK-to-MS derivation atomatically
-         * and skip the intermediate PMS. */
-        if( ssl_use_opaque_psk( ssl ) == 1 )
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "skip PMS generation for opaque PSK" ) );
-        else
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
+#if !defined(MBEDTLS_USE_PSA_CRYPTO)
         if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
                         ciphersuite_info->key_exchange ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret );
             return( ret );
         }
+#endif /* !MBEDTLS_USE_PSA_CRYPTO */
     }
     else
 #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
@@ -4053,19 +3959,14 @@
             return( ret );
         }
 
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-        /* For opaque PSKs, we perform the PSK-to-MS derivation automatically
-         * and skip the intermediate PMS. */
-        if( ssl_use_opaque_psk( ssl ) == 1 )
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "skip PMS generation for opaque RSA-PSK" ) );
-        else
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
+#if !defined(MBEDTLS_USE_PSA_CRYPTO)
         if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
                         ciphersuite_info->key_exchange ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret );
             return( ret );
         }
+#endif /* !MBEDTLS_USE_PSA_CRYPTO */
     }
     else
 #endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
@@ -4089,12 +3990,31 @@
             return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+        unsigned char *pms = ssl->handshake->premaster;
+        unsigned char *pms_end = pms + sizeof( ssl->handshake->premaster );
+        size_t pms_len;
+
+        /* Write length only when we know the actual value */
+        if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
+                                      pms + 2, pms_end - ( pms + 2 ), &pms_len,
+                                      ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
+            return( ret );
+        }
+        MBEDTLS_PUT_UINT16_BE( pms_len, pms, 0 );
+        pms += 2 + pms_len;
+
+        MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K  );
+#else
         if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
                         ciphersuite_info->key_exchange ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret );
             return( ret );
         }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
     }
     else
 #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
@@ -4175,40 +4095,6 @@
         MBEDTLS_PUT_UINT16_BE( zlen, psm, 0 );
         psm += zlen_size + zlen;
 
-        const unsigned char *psk = NULL;
-        size_t psk_len = 0;
-
-        /* In case of opaque psk skip writting psk to pms.
-         * Opaque key will be handled later. */
-        if( ssl_use_opaque_psk( ssl ) == 0 )
-        {
-            if( mbedtls_ssl_get_psk( ssl, &psk, &psk_len )
-                    == MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED )
-                /*
-                * This should never happen because the existence of a PSK is always
-                * checked before calling this function
-                */
-                return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-
-            /* opaque psk<0..2^16-1>; */
-            if( (size_t)( psm_end - psm ) < ( 2 + psk_len ) )
-                return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-            /* Write the PSK length as uint16 */
-            MBEDTLS_PUT_UINT16_BE( psk_len, psm, 0 );
-            psm += 2;
-
-            /* Write the PSK itself */
-            memcpy( psm, psk, psk_len );
-            psm += psk_len;
-
-            ssl->handshake->pmslen = psm - ssl->handshake->premaster;
-        }
-        else
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 1,
-                ( "skip PMS generation for opaque ECDHE-PSK" ) );
-        }
 #else /* MBEDTLS_USE_PSA_CRYPTO */
         if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 )
         {
diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c
index d024abf..e9250fc 100644
--- a/library/ssl_tls13_client.c
+++ b/library/ssl_tls13_client.c
@@ -750,11 +750,6 @@
                                     const unsigned char *buf,
                                     const unsigned char *end )
 {
-    static const unsigned char magic_hrr_string[MBEDTLS_SERVER_HELLO_RANDOM_LEN] =
-        { 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11,
-          0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
-          0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E,
-          0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33 ,0x9C };
 
     /* Check whether this message is a HelloRetryRequest ( HRR ) message.
      *
@@ -771,9 +766,11 @@
      * } ServerHello;
      *
      */
-    MBEDTLS_SSL_CHK_BUF_READ_PTR( buf, end, 2 + sizeof( magic_hrr_string ) );
+    MBEDTLS_SSL_CHK_BUF_READ_PTR( buf, end,
+                    2 + sizeof( mbedtls_ssl_tls13_hello_retry_request_magic ) );
 
-    if( memcmp( buf + 2, magic_hrr_string, sizeof( magic_hrr_string ) ) == 0 )
+    if( memcmp( buf + 2, mbedtls_ssl_tls13_hello_retry_request_magic,
+                sizeof( mbedtls_ssl_tls13_hello_retry_request_magic ) ) == 0 )
     {
         return( SSL_SERVER_HELLO_COORDINATE_HRR );
     }
@@ -1189,8 +1186,6 @@
 static int ssl_tls13_postprocess_server_hello( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    mbedtls_ssl_key_set traffic_keys;
-    mbedtls_ssl_transform *transform_handshake = NULL;
     mbedtls_ssl_handshake_params *handshake = ssl->handshake;
 
     /* Determine the key exchange mode:
@@ -1234,50 +1229,21 @@
     ret = mbedtls_ssl_tls13_key_schedule_stage_early( ssl );
     if( ret != 0 )
     {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_key_schedule_stage_early_data",
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_key_schedule_stage_early",
                                ret );
         goto cleanup;
     }
 
-    /* Compute handshake secret */
-    ret = mbedtls_ssl_tls13_key_schedule_stage_handshake( ssl );
+    ret = mbedtls_ssl_tls13_compute_handshake_transform( ssl );
     if( ret != 0 )
     {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_derive_master_secret", ret );
-        goto cleanup;
-    }
-
-    /* Next evolution in key schedule: Establish handshake secret and
-     * key material. */
-    ret = mbedtls_ssl_tls13_generate_handshake_keys( ssl, &traffic_keys );
-    if( ret != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_generate_handshake_keys",
+        MBEDTLS_SSL_DEBUG_RET( 1,
+                               "mbedtls_ssl_tls13_compute_handshake_transform",
                                ret );
         goto cleanup;
     }
 
-    transform_handshake = mbedtls_calloc( 1, sizeof( mbedtls_ssl_transform ) );
-    if( transform_handshake == NULL )
-    {
-        ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
-        goto cleanup;
-    }
-
-    ret = mbedtls_ssl_tls13_populate_transform( transform_handshake,
-                              ssl->conf->endpoint,
-                              ssl->session_negotiate->ciphersuite,
-                              &traffic_keys,
-                              ssl );
-    if( ret != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_populate_transform", ret );
-        goto cleanup;
-    }
-
-    handshake->transform_handshake = transform_handshake;
-    mbedtls_ssl_set_inbound_transform( ssl, transform_handshake );
-
+    mbedtls_ssl_set_inbound_transform( ssl, handshake->transform_handshake );
     MBEDTLS_SSL_DEBUG_MSG( 1, ( "Switch to handshake keys for inbound traffic" ) );
     ssl->session_in = ssl->session_negotiate;
 
@@ -1287,16 +1253,13 @@
     mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS );
 
 cleanup:
-
-    mbedtls_platform_zeroize( &traffic_keys, sizeof( traffic_keys ) );
     if( ret != 0 )
     {
-        mbedtls_free( transform_handshake );
-
         MBEDTLS_SSL_PEND_FATAL_ALERT(
             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
             MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
+
     return( ret );
 }
 
@@ -1649,8 +1612,8 @@
             case MBEDTLS_TLS_EXT_SIG_ALG:
                 MBEDTLS_SSL_DEBUG_MSG( 3,
                         ( "found signature algorithms extension" ) );
-                ret = mbedtls_ssl_tls13_parse_sig_alg_ext( ssl, p,
-                              p + extension_data_len );
+                ret = mbedtls_ssl_parse_sig_alg_ext( ssl, p,
+                                                     p + extension_data_len );
                 if( ret != 0 )
                     return( ret );
                 if( ! sig_alg_ext_found )
@@ -1787,6 +1750,15 @@
     if( ret != 0 )
         return( ret );
 
+    ret = mbedtls_ssl_tls13_compute_application_transform( ssl );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_PEND_FATAL_ALERT(
+                MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
+                MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
+        return( ret );
+    }
+
 #if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
     mbedtls_ssl_handshake_set_state(
         ssl,
@@ -1862,6 +1834,14 @@
     if( ret != 0 )
         return( ret );
 
+    ret = mbedtls_ssl_tls13_generate_resumption_master_secret( ssl );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1,
+                "mbedtls_ssl_tls13_generate_resumption_master_secret ", ret );
+        return ( ret );
+    }
+
     mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_FLUSH_BUFFERS );
     return( 0 );
 }
@@ -1881,11 +1861,6 @@
  */
 static int ssl_tls13_handshake_wrapup( mbedtls_ssl_context *ssl )
 {
-    MBEDTLS_SSL_DEBUG_MSG( 1, ( "Switch to application keys for inbound traffic" ) );
-    mbedtls_ssl_set_inbound_transform ( ssl, ssl->transform_application );
-
-    MBEDTLS_SSL_DEBUG_MSG( 1, ( "Switch to application keys for outbound traffic" ) );
-    mbedtls_ssl_set_outbound_transform( ssl, ssl->transform_application );
 
     mbedtls_ssl_tls13_handshake_wrapup( ssl );
 
diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c
index f5d791f..239be53 100644
--- a/library/ssl_tls13_generic.c
+++ b/library/ssl_tls13_generic.c
@@ -34,6 +34,13 @@
 #include "ssl_tls13_keys.h"
 #include "ssl_debug_helpers.h"
 
+const uint8_t mbedtls_ssl_tls13_hello_retry_request_magic[
+                MBEDTLS_SERVER_HELLO_RANDOM_LEN ] =
+                    { 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11,
+                      0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
+                      0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E,
+                      0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C };
+
 int mbedtls_ssl_tls13_fetch_handshake_msg( mbedtls_ssl_context *ssl,
                                            unsigned hs_type,
                                            unsigned char **buf,
@@ -73,80 +80,6 @@
 }
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
-/* mbedtls_ssl_tls13_parse_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;
- */
-int mbedtls_ssl_tls13_parse_sig_alg_ext( mbedtls_ssl_context *ssl,
-                                         const unsigned char *buf,
-                                         const unsigned char *end )
-{
-    const unsigned char *p = buf;
-    size_t supported_sig_algs_len = 0;
-    const unsigned char *supported_sig_algs_end;
-    uint16_t sig_alg;
-    uint32_t common_idx = 0;
-
-    MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, 2 );
-    supported_sig_algs_len = MBEDTLS_GET_UINT16_BE( p, 0 );
-    p += 2;
-
-    memset( ssl->handshake->received_sig_algs, 0,
-            sizeof(ssl->handshake->received_sig_algs) );
-
-    MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, supported_sig_algs_len );
-    supported_sig_algs_end = p + supported_sig_algs_len;
-    while( p < supported_sig_algs_end )
-    {
-        MBEDTLS_SSL_CHK_BUF_READ_PTR( p, supported_sig_algs_end, 2 );
-        sig_alg = MBEDTLS_GET_UINT16_BE( p, 0 );
-        p += 2;
-
-        MBEDTLS_SSL_DEBUG_MSG( 4, ( "received signature algorithm: 0x%x",
-                                    sig_alg ) );
-
-        if( ! mbedtls_ssl_sig_alg_is_supported( ssl, sig_alg ) ||
-            ! mbedtls_ssl_sig_alg_is_offered( ssl, sig_alg ) )
-            continue;
-
-        if( common_idx + 1 < MBEDTLS_RECEIVED_SIG_ALGS_SIZE )
-        {
-            ssl->handshake->received_sig_algs[common_idx] = sig_alg;
-            common_idx += 1;
-        }
-    }
-    /* Check that we consumed all the message. */
-    if( p != end )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1,
-            ( "Signature algorithms extension length misaligned" ) );
-        MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
-                                      MBEDTLS_ERR_SSL_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
-    }
-
-    if( common_idx == 0 )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 3, ( "no signature algorithm in common" ) );
-        MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
-                                      MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
-    }
-
-    ssl->handshake->received_sig_algs[common_idx] = MBEDTLS_TLS1_3_SIG_NONE;
-    return( 0 );
-}
-
 /*
  * STATE HANDLING: Read CertificateVerify
  */
@@ -434,14 +367,10 @@
 
 /*
  *
- * STATE HANDLING: Incoming Certificate, client-side only currently.
+ * STATE HANDLING: Incoming Certificate.
  *
  */
 
-/*
- * Implementation
- */
-
 #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
 #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
 /*
@@ -506,6 +435,13 @@
         mbedtls_free( ssl->session_negotiate->peer_cert );
     }
 
+    if( certificate_list_len == 0 )
+    {
+        ssl->session_negotiate->peer_cert = NULL;
+        ret = 0;
+        goto exit;
+    }
+
     if( ( ssl->session_negotiate->peer_cert =
           mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ) ) == NULL )
     {
@@ -582,6 +518,7 @@
         p += extensions_len;
     }
 
+exit:
     /* Check that all the message is consumed. */
     if( p != end )
     {
@@ -614,10 +551,58 @@
 static int ssl_tls13_validate_certificate( mbedtls_ssl_context *ssl )
 {
     int ret = 0;
+    int authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
     mbedtls_x509_crt *ca_chain;
     mbedtls_x509_crl *ca_crl;
     uint32_t verify_result = 0;
 
+    /* If SNI was used, overwrite authentication mode
+     * from the configuration. */
+#if defined(MBEDTLS_SSL_SRV_C)
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
+        authmode = ssl->conf->authmode;
+#endif
+
+    /*
+     * If the peer hasn't sent a certificate ( i.e. it sent
+     * an empty certificate chain ), this is reflected in the peer CRT
+     * structure being unset.
+     * Check for that and handle it depending on the
+     * authentication mode.
+     */
+    if( ssl->session_negotiate->peer_cert == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer has not sent a certificate" ) );
+
+#if defined(MBEDTLS_SSL_SRV_C)
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
+        {
+            /* The client was asked for a certificate but didn't send
+             * one. The client should know what's going on, so we
+             * don't send an alert.
+             */
+            ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
+            if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL )
+                return( 0 );
+            else
+            {
+                MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_NO_CERT,
+                                              MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE  );
+                return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE );
+            }
+        }
+#endif /* MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_SSL_CLI_C)
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+        {
+            MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_NO_CERT,
+                                          MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE );
+            return( MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE );
+        }
+#endif /* MBEDTLS_SSL_CLI_C */
+    }
+
 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
     if( ssl->handshake->sni_ca_chain != NULL )
     {
@@ -660,8 +645,20 @@
             ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
     }
 
+    /* mbedtls_x509_crt_verify_with_profile is supposed to report a
+     * verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED,
+     * with details encoded in the verification flags. All other kinds
+     * of error codes, including those from the user provided f_vrfy
+     * functions, are treated as fatal and lead to a failure of
+     * ssl_tls13_parse_certificate even if verification was optional. */
+    if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
+        ( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
+          ret == MBEDTLS_ERR_SSL_BAD_CERTIFICATE ) )
+    {
+        ret = 0;
+    }
 
-    if( ca_chain == NULL )
+    if( ca_chain == NULL && authmode == MBEDTLS_SSL_VERIFY_REQUIRED )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) );
         ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
@@ -730,7 +727,8 @@
                           &buf, &buf_len ) );
 
     /* Parse the certificate chain sent by the peer. */
-    MBEDTLS_SSL_PROC_CHK( ssl_tls13_parse_certificate( ssl, buf, buf + buf_len ) );
+    MBEDTLS_SSL_PROC_CHK( ssl_tls13_parse_certificate( ssl, buf,
+                                                       buf + buf_len ) );
     /* Validate the certificate chain and set the verification results. */
     MBEDTLS_SSL_PROC_CHK( ssl_tls13_validate_certificate( ssl ) );
 
@@ -738,12 +736,9 @@
                                         buf, buf_len );
 
 cleanup:
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) );
-#else
-    MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
-    ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
-#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
     return( ret );
 }
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
@@ -975,7 +970,7 @@
 #endif /* MBEDTLS_RSA_C */
         default:
             MBEDTLS_SSL_DEBUG_MSG( 1,
-                                   ( "unkown signature type : %u", sig ) );
+                                   ( "unknown signature type : %u", sig ) );
             break;
     }
     return( -1 );
@@ -1187,80 +1182,6 @@
     return( 0 );
 }
 
-#if defined(MBEDTLS_SSL_CLI_C)
-static int ssl_tls13_postprocess_server_finished_message( mbedtls_ssl_context *ssl )
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    mbedtls_ssl_key_set traffic_keys;
-    mbedtls_ssl_transform *transform_application = NULL;
-
-    ret = mbedtls_ssl_tls13_key_schedule_stage_application( ssl );
-    if( ret != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1,
-           "mbedtls_ssl_tls13_key_schedule_stage_application", ret );
-        goto cleanup;
-    }
-
-    ret = mbedtls_ssl_tls13_generate_application_keys( ssl, &traffic_keys );
-    if( ret != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1,
-            "mbedtls_ssl_tls13_generate_application_keys", ret );
-        goto cleanup;
-    }
-
-    transform_application =
-        mbedtls_calloc( 1, sizeof( mbedtls_ssl_transform ) );
-    if( transform_application == NULL )
-    {
-        ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
-        goto cleanup;
-    }
-
-    ret = mbedtls_ssl_tls13_populate_transform(
-                                    transform_application,
-                                    ssl->conf->endpoint,
-                                    ssl->session_negotiate->ciphersuite,
-                                    &traffic_keys,
-                                    ssl );
-    if( ret != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_populate_transform", ret );
-        goto cleanup;
-    }
-
-    ssl->transform_application = transform_application;
-
-cleanup:
-
-    mbedtls_platform_zeroize( &traffic_keys, sizeof( traffic_keys ) );
-    if( ret != 0 )
-    {
-        mbedtls_free( transform_application );
-        MBEDTLS_SSL_PEND_FATAL_ALERT(
-                MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
-                MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
-    }
-    return( ret );
-}
-#endif /* MBEDTLS_SSL_CLI_C */
-
-static int ssl_tls13_postprocess_finished_message( mbedtls_ssl_context *ssl )
-{
-
-#if defined(MBEDTLS_SSL_CLI_C)
-    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
-    {
-        return( ssl_tls13_postprocess_server_finished_message( ssl ) );
-    }
-#else
-    ((void) ssl);
-#endif /* MBEDTLS_SSL_CLI_C */
-
-    return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-}
-
 int mbedtls_ssl_tls13_process_finished_message( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -1278,7 +1199,6 @@
     MBEDTLS_SSL_PROC_CHK( ssl_tls13_parse_finished_message( ssl, buf, buf + buf_len ) );
     mbedtls_ssl_add_hs_msg_to_checksum( ssl, MBEDTLS_SSL_HS_FINISHED,
                                         buf, buf_len );
-    MBEDTLS_SSL_PROC_CHK( ssl_tls13_postprocess_finished_message( ssl ) );
 
 cleanup:
 
@@ -1315,14 +1235,6 @@
     return( 0 );
 }
 
-static int ssl_tls13_finalize_finished_message( mbedtls_ssl_context *ssl )
-{
-    // TODO: Add back resumption keys calculation after MVP.
-    ((void) ssl);
-
-    return( 0 );
-}
-
 static int ssl_tls13_write_finished_message_body( mbedtls_ssl_context *ssl,
                                                   unsigned char *buf,
                                                   unsigned char *end,
@@ -1363,7 +1275,6 @@
     mbedtls_ssl_add_hs_msg_to_checksum( ssl, MBEDTLS_SSL_HS_FINISHED,
                                         buf, msg_len );
 
-    MBEDTLS_SSL_PROC_CHK( ssl_tls13_finalize_finished_message( ssl ) );
     MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_finish_handshake_msg(
                               ssl, buf_len, msg_len ) );
 cleanup:
@@ -1377,6 +1288,12 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup" ) );
 
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "Switch to application keys for inbound traffic" ) );
+    mbedtls_ssl_set_inbound_transform ( ssl, ssl->transform_application );
+
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "Switch to application keys for outbound traffic" ) );
+    mbedtls_ssl_set_outbound_transform( ssl, ssl->transform_application );
+
     /*
      * Free the previous session and switch to the current one.
      */
diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c
index 6559bc9..91cc4d9 100644
--- a/library/ssl_tls13_keys.c
+++ b/library/ssl_tls13_keys.c
@@ -27,6 +27,7 @@
 #include "mbedtls/hkdf.h"
 #include "mbedtls/debug.h"
 #include "mbedtls/error.h"
+#include "mbedtls/platform.h"
 
 #include "ssl_misc.h"
 #include "ssl_tls13_keys.h"
@@ -992,8 +993,8 @@
 {
 #if !defined(MBEDTLS_USE_PSA_CRYPTO)
     int ret;
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
     mbedtls_cipher_info_t const *cipher_info;
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
     const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
     unsigned char const *key_enc;
     unsigned char const *iv_enc;
@@ -1021,6 +1022,7 @@
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
+#if !defined(MBEDTLS_USE_PSA_CRYPTO)
     cipher_info = mbedtls_cipher_info_from_type( ciphersuite_info->cipher );
     if( cipher_info == NULL )
     {
@@ -1029,7 +1031,6 @@
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
-#if !defined(MBEDTLS_USE_PSA_CRYPTO)
     /*
      * Setup cipher contexts in target transform
      */
@@ -1109,7 +1110,7 @@
     transform->tls_version = MBEDTLS_SSL_VERSION_TLS1_3;
 
     /* We add the true record content type (1 Byte) to the plaintext and
-     * then pad to the configured granularity. The mimimum length of the
+     * then pad to the configured granularity. The minimum length of the
      * type-extended and padded plaintext is therefore the padding
      * granularity. */
     transform->minlen =
@@ -1119,7 +1120,7 @@
     /*
      * Setup psa keys and alg
      */
-    if( ( status = mbedtls_ssl_cipher_to_psa( cipher_info->type,
+    if( ( status = mbedtls_ssl_cipher_to_psa( ciphersuite_info->cipher,
                                  transform->taglen,
                                  &alg,
                                  &key_type,
@@ -1187,6 +1188,34 @@
     return( 0 );
 }
 
+static int mbedtls_ssl_tls13_get_cipher_key_info(
+                    const mbedtls_ssl_ciphersuite_t *ciphersuite_info,
+                    size_t *key_len, size_t *iv_len )
+{
+    psa_key_type_t key_type;
+    psa_algorithm_t alg;
+    size_t taglen;
+    size_t key_bits;
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+    if( ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG )
+        taglen = 8;
+    else
+        taglen = 16;
+
+    status = mbedtls_ssl_cipher_to_psa( ciphersuite_info->cipher, taglen,
+                                        &alg, &key_type, &key_bits );
+    if( status != PSA_SUCCESS )
+        return psa_ssl_status_to_mbedtls( status );
+
+    *key_len = PSA_BITS_TO_BYTES( key_bits );
+
+    /* TLS 1.3 only have AEAD ciphers, IV length is unconditionally 12 bytes */
+    *iv_len = 12;
+
+    return 0;
+}
+
 /* mbedtls_ssl_tls13_generate_handshake_keys() generates keys necessary for
  * protecting the handshake messages, as described in Section 7 of TLS 1.3. */
 int mbedtls_ssl_tls13_generate_handshake_keys( mbedtls_ssl_context *ssl,
@@ -1202,7 +1231,6 @@
     unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE];
     size_t transcript_len;
 
-    mbedtls_cipher_info_t const *cipher_info;
     size_t key_len, iv_len;
 
     mbedtls_ssl_handshake_params *handshake = ssl->handshake;
@@ -1211,9 +1239,13 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_tls13_generate_handshake_keys" ) );
 
-    cipher_info = mbedtls_cipher_info_from_type( ciphersuite_info->cipher );
-    key_len = cipher_info->key_bitlen >> 3;
-    iv_len = cipher_info->iv_size;
+    ret = mbedtls_ssl_tls13_get_cipher_key_info( ciphersuite_info,
+                                                 &key_len, &iv_len );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_get_cipher_key_info", ret );
+        return ret;
+    }
 
     md_type = ciphersuite_info->mac;
 
@@ -1407,24 +1439,26 @@
     size_t hash_len;
 
     /* Variables relating to the cipher for the chosen ciphersuite. */
-    mbedtls_cipher_info_t const *cipher_info;
     size_t key_len, iv_len;
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive application traffic keys" ) );
 
     /* Extract basic information about hash and ciphersuite */
 
-    cipher_info = mbedtls_cipher_info_from_type(
-                                  handshake->ciphersuite_info->cipher );
-    key_len = cipher_info->key_bitlen / 8;
-    iv_len = cipher_info->iv_size;
+    ret = mbedtls_ssl_tls13_get_cipher_key_info( handshake->ciphersuite_info,
+                                                 &key_len, &iv_len );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_get_cipher_key_info", ret );
+        goto cleanup;
+    }
 
     md_type = handshake->ciphersuite_info->mac;
 
     hash_alg = mbedtls_psa_translate_md( handshake->ciphersuite_info->mac );
     hash_len = PSA_HASH_LENGTH( hash_alg );
 
-    /* Compute current handshake transcript. It's the caller's responsiblity
+    /* Compute current handshake transcript. It's the caller's responsibility
      * to call this at the right time, that is, after the ServerFinished. */
 
     ret = mbedtls_ssl_get_handshake_transcript( ssl, md_type,
@@ -1439,9 +1473,6 @@
                                    handshake->tls13_master_secrets.app,
                                    transcript, transcript_len,
                                    app_secrets );
-    /* Erase master secrets */
-    mbedtls_platform_zeroize( &ssl->handshake->tls13_master_secrets,
-                              sizeof( ssl->handshake->tls13_master_secrets ) );
     if( ret != 0 )
     {
         MBEDTLS_SSL_DEBUG_RET( 1,
@@ -1506,8 +1537,125 @@
     /* randbytes is not used again */
     mbedtls_platform_zeroize( ssl->handshake->randbytes,
                               sizeof( ssl->handshake->randbytes ) );
+
     mbedtls_platform_zeroize( transcript, sizeof( transcript ) );
     return( ret );
 }
 
+int mbedtls_ssl_tls13_compute_handshake_transform( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    mbedtls_ssl_key_set traffic_keys;
+    mbedtls_ssl_transform *transform_handshake = NULL;
+    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
+
+    /* Compute handshake secret */
+    ret = mbedtls_ssl_tls13_key_schedule_stage_handshake( ssl );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_derive_master_secret", ret );
+        goto cleanup;
+    }
+
+    /* Next evolution in key schedule: Establish handshake secret and
+     * key material. */
+    ret = mbedtls_ssl_tls13_generate_handshake_keys( ssl, &traffic_keys );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_generate_handshake_keys",
+                               ret );
+        goto cleanup;
+    }
+
+    transform_handshake = mbedtls_calloc( 1, sizeof( mbedtls_ssl_transform ) );
+    if( transform_handshake == NULL )
+    {
+        ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
+        goto cleanup;
+    }
+
+    ret = mbedtls_ssl_tls13_populate_transform(
+                                        transform_handshake,
+                                        ssl->conf->endpoint,
+                                        ssl->session_negotiate->ciphersuite,
+                                        &traffic_keys,
+                                        ssl );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_populate_transform", ret );
+        goto cleanup;
+    }
+    handshake->transform_handshake = transform_handshake;
+
+cleanup:
+    mbedtls_platform_zeroize( &traffic_keys, sizeof( traffic_keys ) );
+    if( ret != 0 )
+        mbedtls_free( transform_handshake );
+
+    return( ret );
+}
+
+int mbedtls_ssl_tls13_generate_resumption_master_secret(
+    mbedtls_ssl_context *ssl )
+{
+    /* Erase master secrets */
+    mbedtls_platform_zeroize( &ssl->handshake->tls13_master_secrets,
+                              sizeof( ssl->handshake->tls13_master_secrets ) );
+    return( 0 );
+}
+
+int mbedtls_ssl_tls13_compute_application_transform( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    mbedtls_ssl_key_set traffic_keys;
+    mbedtls_ssl_transform *transform_application = NULL;
+
+    ret = mbedtls_ssl_tls13_key_schedule_stage_application( ssl );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1,
+           "mbedtls_ssl_tls13_key_schedule_stage_application", ret );
+        goto cleanup;
+    }
+
+    ret = mbedtls_ssl_tls13_generate_application_keys( ssl, &traffic_keys );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1,
+            "mbedtls_ssl_tls13_generate_application_keys", ret );
+        goto cleanup;
+    }
+
+    transform_application =
+        mbedtls_calloc( 1, sizeof( mbedtls_ssl_transform ) );
+    if( transform_application == NULL )
+    {
+        ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
+        goto cleanup;
+    }
+
+    ret = mbedtls_ssl_tls13_populate_transform(
+                                    transform_application,
+                                    ssl->conf->endpoint,
+                                    ssl->session_negotiate->ciphersuite,
+                                    &traffic_keys,
+                                    ssl );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_populate_transform", ret );
+        goto cleanup;
+    }
+
+    ssl->transform_application = transform_application;
+
+cleanup:
+
+    mbedtls_platform_zeroize( &traffic_keys, sizeof( traffic_keys ) );
+    if( ret != 0 )
+    {
+        mbedtls_free( transform_application );
+    }
+    return( ret );
+}
+
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
diff --git a/library/ssl_tls13_keys.h b/library/ssl_tls13_keys.h
index d56067c..693b6c4 100644
--- a/library/ssl_tls13_keys.h
+++ b/library/ssl_tls13_keys.h
@@ -611,6 +611,19 @@
     mbedtls_ssl_context* ssl, mbedtls_ssl_key_set *traffic_keys );
 
 /**
+ * \brief Compute TLS 1.3 resumption master secret.
+ *
+ * \param ssl  The SSL context to operate on. This must be in
+ *             key schedule stage \c Application, see
+ *             mbedtls_ssl_tls13_key_schedule_stage_application().
+ *
+ * \returns    \c 0 on success.
+ * \returns    A negative error code on failure.
+ */
+int mbedtls_ssl_tls13_generate_resumption_master_secret(
+    mbedtls_ssl_context *ssl );
+
+/**
  * \brief Calculate the verify_data value for the client or server TLS 1.3
  * Finished message.
  *
@@ -638,6 +651,28 @@
                                              size_t *actual_len,
                                              int which );
 
+/**
+ * \brief Compute TLS 1.3 handshake transform
+ *
+ * \param ssl  The SSL context to operate on. The early secret must have been
+ *             computed.
+ *
+ * \returns    \c 0 on success.
+ * \returns    A negative error code on failure.
+ */
+int mbedtls_ssl_tls13_compute_handshake_transform( mbedtls_ssl_context *ssl );
+
+/**
+ * \brief Compute TLS 1.3 application transform
+ *
+ * \param ssl  The SSL context to operate on. The early secret must have been
+ *             computed.
+ *
+ * \returns    \c 0 on success.
+ * \returns    A negative error code on failure.
+ */
+int mbedtls_ssl_tls13_compute_application_transform( mbedtls_ssl_context *ssl );
+
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
 
 #endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index d06b9a8..f3843b1 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -22,6 +22,8 @@
 #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3)
 
 #include "mbedtls/debug.h"
+#include "mbedtls/error.h"
+#include "mbedtls/platform.h"
 
 #include "ssl_misc.h"
 #include "ssl_tls13_keys.h"
@@ -39,6 +41,10 @@
 #define mbedtls_free       free
 #endif /* MBEDTLS_PLATFORM_C */
 
+#include "ssl_misc.h"
+#include "ssl_tls13_keys.h"
+#include "ssl_debug_helpers.h"
+
 /* From RFC 8446:
  *   struct {
  *          ProtocolVersion versions<2..254>;
@@ -100,9 +106,9 @@
  *       NamedGroup named_group_list<2..2^16-1>;
  *   } NamedGroupList;
  */
-static int ssl_tls13_parse_supported_groups_ext(
-                mbedtls_ssl_context *ssl,
-                const unsigned char *buf, const unsigned char *end )
+static int ssl_tls13_parse_supported_groups_ext( mbedtls_ssl_context *ssl,
+                                                 const unsigned char *buf,
+                                                 const unsigned char *end )
 {
     const unsigned char *p = buf;
     size_t named_group_list_len;
@@ -123,7 +129,10 @@
         named_group = MBEDTLS_GET_UINT16_BE( p, 0 );
         p += 2;
 
-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "got named group: %d", named_group ) );
+        MBEDTLS_SSL_DEBUG_MSG( 2,
+                               ( "got named group: %s(%04x)",
+                                 mbedtls_ssl_named_group_to_str( named_group ),
+                                 named_group ) );
 
         if( ! mbedtls_ssl_named_group_is_offered( ssl, named_group ) ||
             ! mbedtls_ssl_named_group_is_supported( named_group ) ||
@@ -132,9 +141,11 @@
             continue;
         }
 
-        MBEDTLS_SSL_DEBUG_MSG(
-                2, ( "add named group (%04x) into received list.",
-                     named_group ) );
+        MBEDTLS_SSL_DEBUG_MSG( 2,
+                               ( "add named group %s(%04x) into received list.",
+                                 mbedtls_ssl_named_group_to_str( named_group ),
+                                 named_group ) );
+
         ssl->handshake->hrr_selected_group = named_group;
     }
 
@@ -156,8 +167,7 @@
  *    does not match a group supported by the server. A HelloRetryRequest will
  *    be needed.
  *  - A negative value for fatal errors.
-*/
-
+ */
 static int ssl_tls13_parse_key_shares_ext( mbedtls_ssl_context *ssl,
                                            const unsigned char *buf,
                                            const unsigned char *end )
@@ -165,8 +175,7 @@
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char const *p = buf;
     unsigned char const *client_shares_end;
-    size_t client_shares_len, key_exchange_len;
-    int match_found = 0;
+    size_t client_shares_len;
 
     /* From RFC 8446:
      *
@@ -190,9 +199,11 @@
      * dismiss it and send a HelloRetryRequest message.
      */
 
-    for( ; p < client_shares_end; p += key_exchange_len )
+    while( p < client_shares_end )
     {
         uint16_t group;
+        size_t key_exchange_len;
+        const unsigned char *key_exchange;
 
         /*
          * struct {
@@ -202,19 +213,18 @@
          */
         MBEDTLS_SSL_CHK_BUF_READ_PTR( p, client_shares_end, 4 );
         group = MBEDTLS_GET_UINT16_BE( p, 0 );
-        p += 2;
-        key_exchange_len = MBEDTLS_GET_UINT16_BE( p, 0 );
-        p += 2;
+        key_exchange_len = MBEDTLS_GET_UINT16_BE( p, 2 );
+        p += 4;
+        key_exchange = p;
         MBEDTLS_SSL_CHK_BUF_READ_PTR( p, client_shares_end, key_exchange_len );
+        p += key_exchange_len;
 
         /* Continue parsing even if we have already found a match,
          * for input validation purposes.
          */
-        if( match_found == 1 )
-            continue;
-
         if( ! mbedtls_ssl_named_group_is_offered( ssl, group ) ||
-            ! mbedtls_ssl_named_group_is_supported( group ) )
+            ! mbedtls_ssl_named_group_is_supported( group ) ||
+            ssl->handshake->offered_group_id != 0 )
         {
             continue;
         }
@@ -224,16 +234,14 @@
          */
         if( mbedtls_ssl_tls13_named_group_is_ecdhe( group ) )
         {
-            const mbedtls_ecp_curve_info *curve_info =
-                    mbedtls_ecp_curve_info_from_tls_id( group );
-            ((void) curve_info);
-            MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) );
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH group: %s (%04x)",
+                                        mbedtls_ssl_named_group_to_str( group ),
+                                        group ) );
             ret = mbedtls_ssl_tls13_read_public_ecdhe_share(
-                    ssl, p - 2, key_exchange_len + 2 );
+                      ssl, key_exchange - 2, key_exchange_len + 2 );
             if( ret != 0 )
                 return( ret );
 
-            match_found = 1;
         }
         else
         {
@@ -245,7 +253,8 @@
         ssl->handshake->offered_group_id = group;
     }
 
-    if( match_found == 0 )
+
+    if( ssl->handshake->offered_group_id == 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "no matching key share" ) );
         return( SSL_TLS1_3_PARSE_KEY_SHARES_EXT_NO_MATCH );
@@ -382,6 +391,7 @@
     const unsigned char *cipher_suites_end;
     size_t extensions_len;
     const unsigned char *extensions_end;
+    int hrr_required = 0;
 
     const mbedtls_ssl_ciphersuite_t* ciphersuite_info;
 
@@ -402,7 +412,7 @@
      */
 
     /*
-     * Minimal length ( with everything empty and extensions ommitted ) is
+     * Minimal length ( with everything empty and extensions omitted ) is
      * 2 + 32 + 1 + 2 + 1 = 38 bytes. Check that first, so that we can
      * read at least up to session id length without worrying.
      */
@@ -429,9 +439,9 @@
      */
     ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_3;
 
-    /* ---
-     *  Random random;
-     * ---
+    /* ...
+     * Random random;
+     * ...
      * with Random defined as:
      * opaque Random[32];
      */
@@ -441,9 +451,9 @@
     memcpy( &ssl->handshake->randbytes[0], p, MBEDTLS_CLIENT_HELLO_RANDOM_LEN );
     p += MBEDTLS_CLIENT_HELLO_RANDOM_LEN;
 
-    /* ---
+    /* ...
      * opaque legacy_session_id<0..32>;
-     * ---
+     * ...
      */
     legacy_session_id_len = p[0];
     p++;
@@ -474,9 +484,9 @@
      */
     MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, cipher_suites_len + 2 + 2 );
 
-   /* ---
+   /* ...
     * CipherSuite cipher_suites<2..2^16-2>;
-    * ---
+    * ...
     * with CipherSuite defined as:
     * uint8 CipherSuite[2];
     */
@@ -498,10 +508,12 @@
          * Check whether this ciphersuite is valid and offered.
          */
         if( ( mbedtls_ssl_validate_ciphersuite(
-            ssl, ciphersuite_info, ssl->tls_version,
-            ssl->tls_version ) != 0 ) ||
-            !mbedtls_ssl_tls13_cipher_suite_is_offered( ssl, cipher_suite ) )
+                ssl, ciphersuite_info, ssl->tls_version,
+                ssl->tls_version ) != 0 ) ||
+            ! mbedtls_ssl_tls13_cipher_suite_is_offered( ssl, cipher_suite ) )
+        {
             continue;
+        }
 
         ssl->session_negotiate->ciphersuite = cipher_suite;
         ssl->handshake->ciphersuite_info = ciphersuite_info;
@@ -511,7 +523,7 @@
 
     }
 
-    if( !ciphersuite_match )
+    if( ! ciphersuite_match )
     {
         MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
                                       MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
@@ -522,6 +534,7 @@
                                 ciphersuite_info->name ) );
 
     p = cipher_suites + cipher_suites_len;
+
     /* ...
      * opaque legacy_compression_methods<1..2^8-1>;
      * ...
@@ -535,9 +548,9 @@
     }
     p += 2;
 
-    /* ---
+    /* ...
      * Extension extensions<8..2^16-1>;
-     * ---
+     * ...
      * with Extension defined as:
      * struct {
      *    ExtensionType extension_type;
@@ -577,8 +590,8 @@
                  * indicates the named groups which the client supports,
                  * ordered from most preferred to least preferred.
                  */
-                ret = ssl_tls13_parse_supported_groups_ext( ssl, p,
-                            extension_data_end );
+                ret = ssl_tls13_parse_supported_groups_ext(
+                          ssl, p, extension_data_end );
                 if( ret != 0 )
                 {
                     MBEDTLS_SSL_DEBUG_RET( 1,
@@ -601,15 +614,20 @@
                  * contains the endpoint's cryptographic parameters for
                  * ECDHE/DHE key establishment methods.
                  */
-                ret = ssl_tls13_parse_key_shares_ext( ssl, p, extension_data_end );
+                ret = ssl_tls13_parse_key_shares_ext(
+                          ssl, p, extension_data_end );
                 if( ret == SSL_TLS1_3_PARSE_KEY_SHARES_EXT_NO_MATCH )
                 {
                     MBEDTLS_SSL_DEBUG_MSG( 2, ( "HRR needed " ) );
-                    ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+                    hrr_required = 1;
                 }
 
-                if( ret != 0 )
+                if( ret < 0 )
+                {
+                    MBEDTLS_SSL_DEBUG_RET(
+                        1, "ssl_tls13_parse_key_shares_ext", ret );
                     return( ret );
+                }
 
                 ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_KEY_SHARE;
                 break;
@@ -619,7 +637,7 @@
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported versions extension" ) );
 
                 ret = ssl_tls13_parse_supported_versions_ext(
-                        ssl, p, extension_data_end );
+                          ssl, p, extension_data_end );
                 if( ret != 0 )
                 {
                     MBEDTLS_SSL_DEBUG_RET( 1,
@@ -633,8 +651,8 @@
             case MBEDTLS_TLS_EXT_SIG_ALG:
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
 
-                ret = mbedtls_ssl_tls13_parse_sig_alg_ext( ssl, p,
-                                                           extension_data_end );
+                ret = mbedtls_ssl_parse_sig_alg_ext(
+                          ssl, p, extension_data_end );
                 if( ret != 0 )
                 {
                     MBEDTLS_SSL_DEBUG_MSG( 1,
@@ -681,9 +699,11 @@
         return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     }
 
-    return( 0 );
+    return( hrr_required ? SSL_CLIENT_HELLO_HRR_REQUIRED : SSL_CLIENT_HELLO_OK );
 }
 
+/* Update the handshake state machine */
+
 static int ssl_tls13_postprocess_client_hello( mbedtls_ssl_context* ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -710,6 +730,8 @@
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char* buf = NULL;
     size_t buflen = 0;
+    int parse_client_hello_ret;
+
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) );
 
     MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_tls13_fetch_handshake_msg(
@@ -718,8 +740,18 @@
 
     MBEDTLS_SSL_PROC_CHK_NEG( ssl_tls13_parse_client_hello( ssl, buf,
                                                             buf + buflen ) );
+    parse_client_hello_ret = ret; /* Store return value of parse_client_hello,
+                                   * only SSL_CLIENT_HELLO_OK or
+                                   * SSL_CLIENT_HELLO_HRR_REQUIRED at this
+                                   * stage as negative error codes are handled
+                                   * by MBEDTLS_SSL_PROC_CHK_NEG. */
+
     MBEDTLS_SSL_PROC_CHK( ssl_tls13_postprocess_client_hello( ssl ) );
-    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_HELLO );
+
+    if( parse_client_hello_ret == SSL_CLIENT_HELLO_OK )
+        mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_HELLO );
+    else
+        mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_HELLO_RETRY_REQUEST );
 
 cleanup:
 
@@ -888,6 +920,7 @@
     if( ret != 0 )
         return( ret );
     p += key_exchange_length;
+
     MBEDTLS_PUT_UINT16_BE( key_exchange_length, server_share + 2, 0 );
 
     MBEDTLS_PUT_UINT16_BE( p - server_share, buf, 2 );
@@ -897,6 +930,68 @@
     return( 0 );
 }
 
+static int ssl_tls13_write_hrr_key_share_ext( mbedtls_ssl_context *ssl,
+                                              unsigned char *buf,
+                                              unsigned char *end,
+                                              size_t *out_len )
+{
+    uint16_t selected_group = ssl->handshake->hrr_selected_group;
+    /* key_share Extension
+     *
+     *  struct {
+     *    select (Handshake.msg_type) {
+     *      ...
+     *      case hello_retry_request:
+     *          NamedGroup selected_group;
+     *      ...
+     *    };
+     * } KeyShare;
+     */
+
+    *out_len = 0;
+
+    /*
+     * For a pure PSK key exchange, there is no group to agree upon. The purpose
+     * of the HRR is then to transmit a cookie to force the client to demonstrate
+     * reachability at their apparent network address (primarily useful for DTLS).
+     */
+    if( ! mbedtls_ssl_tls13_some_ephemeral_enabled( ssl ) )
+        return( 0 );
+
+    /* We should only send the key_share extension if the client's initial
+     * key share was not acceptable. */
+    if( ssl->handshake->offered_group_id != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 4, ( "Skip key_share extension in HRR" ) );
+        return( 0 );
+    }
+
+    if( selected_group == 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "no matching named group found" ) );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
+    }
+
+    /* Check if we have enough space:
+     * - extension_type         (2 bytes)
+     * - extension_data_length  (2 bytes)
+     * - selected_group         (2 bytes)
+     */
+    MBEDTLS_SSL_CHK_BUF_READ_PTR( buf, end, 6 );
+
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_KEY_SHARE, buf, 0 );
+    MBEDTLS_PUT_UINT16_BE( 2, buf, 2 );
+    MBEDTLS_PUT_UINT16_BE( selected_group, buf, 4 );
+
+    MBEDTLS_SSL_DEBUG_MSG( 3,
+        ( "HRR selected_group: %s (%x)",
+            mbedtls_ssl_named_group_to_str( selected_group ),
+            selected_group ) );
+
+    *out_len = 6;
+
+    return( 0 );
+}
 
 /*
  * Structure of ServerHello message:
@@ -913,12 +1008,13 @@
 static int ssl_tls13_write_server_hello_body( mbedtls_ssl_context *ssl,
                                               unsigned char *buf,
                                               unsigned char *end,
-                                              size_t *out_len )
+                                              size_t *out_len,
+                                              int is_hrr )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char *p = buf;
     unsigned char *p_extensions_len;
-    size_t output_len;               /* Length of buffer used by function */
+    size_t output_len;
 
     *out_len = 0;
 
@@ -939,8 +1035,16 @@
      * opaque Random[MBEDTLS_SERVER_HELLO_RANDOM_LEN];
      */
     MBEDTLS_SSL_CHK_BUF_PTR( p, end, MBEDTLS_SERVER_HELLO_RANDOM_LEN );
-    memcpy( p, &ssl->handshake->randbytes[MBEDTLS_CLIENT_HELLO_RANDOM_LEN],
-               MBEDTLS_SERVER_HELLO_RANDOM_LEN );
+    if( is_hrr )
+    {
+        memcpy( p, mbedtls_ssl_tls13_hello_retry_request_magic,
+                MBEDTLS_SERVER_HELLO_RANDOM_LEN );
+    }
+    else
+    {
+        memcpy( p, &ssl->handshake->randbytes[MBEDTLS_CLIENT_HELLO_RANDOM_LEN],
+                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;
@@ -1006,7 +1110,10 @@
 
     if( mbedtls_ssl_conf_tls13_some_ephemeral_enabled( ssl ) )
     {
-        ret = ssl_tls13_write_key_share_ext( ssl, p, end, &output_len );
+        if( is_hrr )
+            ret = ssl_tls13_write_hrr_key_share_ext( ssl, p, end, &output_len );
+        else
+            ret = ssl_tls13_write_key_share_ext( ssl, p, end, &output_len );
         if( ret != 0 )
             return( ret );
         p += output_len;
@@ -1024,6 +1131,26 @@
     return( ret );
 }
 
+static int ssl_tls13_finalize_write_server_hello( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    ret = mbedtls_ssl_tls13_compute_handshake_transform( ssl );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1,
+                               "mbedtls_ssl_tls13_compute_handshake_transform",
+                               ret );
+        return( ret );
+    }
+
+    mbedtls_ssl_set_outbound_transform( ssl,
+                                        ssl->handshake->transform_handshake );
+    MBEDTLS_SSL_DEBUG_MSG(
+        3, ( "switching to handshake transform for outbound data" ) );
+
+    return( ret );
+}
+
 static int ssl_tls13_write_server_hello( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -1039,7 +1166,8 @@
 
     MBEDTLS_SSL_PROC_CHK( ssl_tls13_write_server_hello_body( ssl, buf,
                                                              buf + buf_len,
-                                                             &msg_len ) );
+                                                             &msg_len,
+                                                             0 ) );
 
     mbedtls_ssl_add_hs_msg_to_checksum(
         ssl, MBEDTLS_SSL_HS_SERVER_HELLO, buf, msg_len );
@@ -1047,13 +1175,381 @@
     MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_finish_handshake_msg(
                               ssl, buf_len, msg_len ) );
 
+    MBEDTLS_SSL_PROC_CHK( ssl_tls13_finalize_write_server_hello( ssl ) );
+
     mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS );
+
 cleanup:
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello" ) );
     return( ret );
 }
 
+
+/*
+ * Handler for MBEDTLS_SSL_HELLO_RETRY_REQUEST
+ */
+static int ssl_tls13_write_hello_retry_request_coordinate(
+                                                    mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    if( ssl->handshake->hello_retry_request_count > 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Too many HRRs" ) );
+        MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
+                                      MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
+    }
+
+    /*
+     * Create stateless transcript hash for HRR
+     */
+    MBEDTLS_SSL_DEBUG_MSG( 4, ( "Reset transcript for HRR" ) );
+    ret = mbedtls_ssl_reset_transcript_for_hrr( ssl );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_reset_transcript_for_hrr", ret );
+        return( ret );
+    }
+    mbedtls_ssl_session_reset_msg_layer( ssl, 0 );
+
+    return( 0 );
+}
+
+static int ssl_tls13_write_hello_retry_request( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    unsigned char *buf;
+    size_t buf_len, msg_len;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write hello retry request" ) );
+
+    MBEDTLS_SSL_PROC_CHK( ssl_tls13_write_hello_retry_request_coordinate( ssl ) );
+
+    MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_start_handshake_msg(
+                              ssl, MBEDTLS_SSL_HS_SERVER_HELLO,
+                              &buf, &buf_len ) );
+
+    MBEDTLS_SSL_PROC_CHK( ssl_tls13_write_server_hello_body( ssl, buf,
+                                                             buf + buf_len,
+                                                             &msg_len,
+                                                             1 ) );
+    mbedtls_ssl_add_hs_msg_to_checksum(
+        ssl, MBEDTLS_SSL_HS_SERVER_HELLO, buf, msg_len );
+
+
+    MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_finish_handshake_msg( ssl, buf_len,
+                                                            msg_len ) );
+
+    ssl->handshake->hello_retry_request_count++;
+
+    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_HELLO );
+
+cleanup:
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello retry request" ) );
+    return( ret );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_ENCRYPTED_EXTENSIONS
+ */
+
+/*
+ * struct {
+ *    Extension extensions<0..2 ^ 16 - 1>;
+ * } EncryptedExtensions;
+ *
+ */
+static int ssl_tls13_write_encrypted_extensions_body( mbedtls_ssl_context *ssl,
+                                                      unsigned char *buf,
+                                                      unsigned char *end,
+                                                      size_t *out_len )
+{
+    unsigned char *p = buf;
+    size_t extensions_len = 0;
+    unsigned char *p_extensions_len;
+
+    *out_len = 0;
+
+    MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
+    p_extensions_len = p;
+    p += 2;
+
+    ((void) ssl);
+
+    extensions_len = ( p - p_extensions_len ) - 2;
+    MBEDTLS_PUT_UINT16_BE( extensions_len, p_extensions_len, 0 );
+
+    *out_len = p - buf;
+
+    MBEDTLS_SSL_DEBUG_BUF( 4, "encrypted extensions", buf, *out_len );
+
+    return( 0 );
+}
+
+static int ssl_tls13_write_encrypted_extensions( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    unsigned char *buf;
+    size_t buf_len, msg_len;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write encrypted extensions" ) );
+
+    MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_start_handshake_msg( ssl,
+                       MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, &buf, &buf_len ) );
+
+    MBEDTLS_SSL_PROC_CHK( ssl_tls13_write_encrypted_extensions_body(
+                              ssl, buf, buf + buf_len, &msg_len ) );
+
+    mbedtls_ssl_add_hs_msg_to_checksum(
+        ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, buf, msg_len );
+
+    MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_finish_handshake_msg(
+                              ssl, buf_len, msg_len ) );
+
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+    if( mbedtls_ssl_tls13_some_psk_enabled( ssl ) )
+        mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_FINISHED );
+    else
+        mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CERTIFICATE_REQUEST );
+#else
+    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_FINISHED );
+#endif
+
+cleanup:
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write encrypted extensions" ) );
+    return( ret );
+}
+
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+#define SSL_CERTIFICATE_REQUEST_SEND_REQUEST 0
+#define SSL_CERTIFICATE_REQUEST_SKIP         1
+/* Coordination:
+ * Check whether a CertificateRequest message should be written.
+ * Returns a negative code on failure, or
+ * - SSL_CERTIFICATE_REQUEST_SEND_REQUEST
+ * - SSL_CERTIFICATE_REQUEST_SKIP
+ * indicating if the writing of the CertificateRequest
+ * should be skipped or not.
+ */
+static int ssl_tls13_certificate_request_coordinate( mbedtls_ssl_context *ssl )
+{
+    int authmode;
+
+    authmode = ssl->conf->authmode;
+
+    if( authmode == MBEDTLS_SSL_VERIFY_NONE )
+        return( SSL_CERTIFICATE_REQUEST_SKIP );
+
+    ssl->handshake->certificate_request_sent = 1;
+
+    return( SSL_CERTIFICATE_REQUEST_SEND_REQUEST );
+}
+
+/*
+ * struct {
+ *   opaque certificate_request_context<0..2^8-1>;
+ *   Extension extensions<2..2^16-1>;
+ * } CertificateRequest;
+ *
+ */
+static int ssl_tls13_write_certificate_request_body( mbedtls_ssl_context *ssl,
+                                                     unsigned char *buf,
+                                                     const unsigned char *end,
+                                                     size_t *out_len )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    unsigned char *p = buf;
+    size_t output_len = 0;
+    unsigned char *p_extensions_len;
+
+    *out_len = 0;
+
+    /* Check if we have enough space:
+     * - certificate_request_context (1 byte)
+     * - extensions length           (2 bytes)
+     */
+    MBEDTLS_SSL_CHK_BUF_PTR( p, end, 3 );
+
+    /*
+     * Write certificate_request_context
+     */
+    /*
+     * We use a zero length context for the normal handshake
+     * messages. For post-authentication handshake messages
+     * this request context would be set to a non-zero value.
+     */
+    *p++ = 0x0;
+
+    /*
+     * Write extensions
+     */
+    /* The extensions must contain the signature_algorithms. */
+    p_extensions_len = p;
+    p += 2;
+    ret = mbedtls_ssl_write_sig_alg_ext( ssl, p, end, &output_len );
+    if( ret != 0 )
+        return( ret );
+
+    p += output_len;
+    MBEDTLS_PUT_UINT16_BE( p - p_extensions_len - 2, p_extensions_len, 0 );
+
+    *out_len = p - buf;
+
+    return( 0 );
+}
+
+static int ssl_tls13_write_certificate_request( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) );
+
+    MBEDTLS_SSL_PROC_CHK_NEG( ssl_tls13_certificate_request_coordinate( ssl ) );
+
+    if( ret == SSL_CERTIFICATE_REQUEST_SEND_REQUEST )
+    {
+        unsigned char *buf;
+        size_t buf_len, msg_len;
+
+        MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_start_handshake_msg( ssl,
+                MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, &buf, &buf_len ) );
+
+        MBEDTLS_SSL_PROC_CHK( ssl_tls13_write_certificate_request_body(
+                                  ssl, buf, buf + buf_len, &msg_len ) );
+
+        mbedtls_ssl_add_hs_msg_to_checksum(
+            ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, buf, msg_len );
+
+        MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_finish_handshake_msg(
+                                  ssl, buf_len, msg_len ) );
+    }
+    else if( ret == SSL_CERTIFICATE_REQUEST_SKIP )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
+        ret = 0;
+    }
+    else
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+        goto cleanup;
+    }
+
+    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_CERTIFICATE );
+cleanup:
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate request" ) );
+    return( ret );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_SERVER_CERTIFICATE
+ */
+static int ssl_tls13_write_server_certificate( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    if( mbedtls_ssl_own_cert( ssl ) == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "No certificate available." ) );
+        MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
+                                      MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
+    }
+
+    ret = mbedtls_ssl_tls13_write_certificate( ssl );
+    if( ret != 0 )
+        return( ret );
+    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CERTIFICATE_VERIFY );
+    return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_CERTIFICATE_VERIFY
+ */
+static int ssl_tls13_write_certificate_verify( mbedtls_ssl_context *ssl )
+{
+    int ret = mbedtls_ssl_tls13_write_certificate_verify( ssl );
+    if( ret != 0 )
+        return( ret );
+    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_FINISHED );
+    return( 0 );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+
+/*
+ * Handler for MBEDTLS_SSL_SERVER_FINISHED
+ */
+static int ssl_tls13_write_server_finished( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+    ret = mbedtls_ssl_tls13_write_finished_message( ssl );
+    if( ret != 0 )
+        return( ret );
+
+    ret = mbedtls_ssl_tls13_compute_application_transform( ssl );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_PEND_FATAL_ALERT(
+                MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
+                MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
+        return( ret );
+    }
+
+    if( ssl->handshake->certificate_request_sent )
+    {
+        mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE );
+
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Switch to handshake keys for inbound traffic" ) );
+        mbedtls_ssl_set_inbound_transform( ssl, ssl->handshake->transform_handshake );
+    }
+    else
+        mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_FINISHED );
+    return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_CLIENT_FINISHED
+ */
+static int ssl_tls13_process_client_finished( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+    if( ! ssl->handshake->certificate_request_sent )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1,
+            ( "Switch to handshake traffic keys for inbound traffic" ) );
+        mbedtls_ssl_set_inbound_transform( ssl, ssl->handshake->transform_handshake );
+    }
+    ret = mbedtls_ssl_tls13_process_finished_message( ssl );
+    if( ret != 0 )
+        return( ret );
+
+    ret = mbedtls_ssl_tls13_generate_resumption_master_secret( ssl );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1,
+            "mbedtls_ssl_tls13_generate_resumption_master_secret ", ret );
+    }
+
+    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP );
+    return( 0 );
+}
+
+/*
+ * Handler for MBEDTLS_SSL_HANDSHAKE_WRAPUP
+ */
+static int ssl_tls13_handshake_wrapup( mbedtls_ssl_context *ssl )
+{
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
+
+    mbedtls_ssl_tls13_handshake_wrapup( ssl );
+    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_HANDSHAKE_OVER );
+    return( 0 );
+}
+
 /*
  * TLS 1.3 State Machine -- server side
  */
@@ -1073,22 +1569,84 @@
         /* start state */
         case MBEDTLS_SSL_HELLO_REQUEST:
             mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_HELLO );
-
             ret = 0;
             break;
 
         case MBEDTLS_SSL_CLIENT_HELLO:
-
             ret = ssl_tls13_process_client_hello( ssl );
             if( ret != 0 )
                 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls13_process_client_hello", ret );
+            break;
 
+        case MBEDTLS_SSL_HELLO_RETRY_REQUEST:
+            ret = ssl_tls13_write_hello_retry_request( ssl );
+            if( ret != 0 )
+            {
+                MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls13_write_hello_retry_request", ret );
+                return( ret );
+            }
             break;
 
         case MBEDTLS_SSL_SERVER_HELLO:
             ret = ssl_tls13_write_server_hello( ssl );
             break;
 
+        case MBEDTLS_SSL_ENCRYPTED_EXTENSIONS:
+            ret = ssl_tls13_write_encrypted_extensions( ssl );
+            if( ret != 0 )
+            {
+                MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls13_write_encrypted_extensions", ret );
+                return( ret );
+            }
+            break;
+
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+        case MBEDTLS_SSL_CERTIFICATE_REQUEST:
+            ret = ssl_tls13_write_certificate_request( ssl );
+            break;
+
+        case MBEDTLS_SSL_SERVER_CERTIFICATE:
+            ret = ssl_tls13_write_server_certificate( ssl );
+            break;
+
+        case MBEDTLS_SSL_CERTIFICATE_VERIFY:
+            ret = ssl_tls13_write_certificate_verify( ssl );
+            break;
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+
+        case MBEDTLS_SSL_SERVER_FINISHED:
+            ret = ssl_tls13_write_server_finished( ssl );
+            break;
+
+        case MBEDTLS_SSL_CLIENT_FINISHED:
+            ret = ssl_tls13_process_client_finished( ssl );
+            break;
+
+        case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
+            ret = ssl_tls13_handshake_wrapup( ssl );
+            break;
+
+        case MBEDTLS_SSL_CLIENT_CERTIFICATE:
+            ret = mbedtls_ssl_tls13_process_certificate( ssl );
+            if( ret == 0 && ssl->session_negotiate->peer_cert != NULL )
+            {
+                mbedtls_ssl_handshake_set_state(
+                    ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY );
+            }
+            else
+                mbedtls_ssl_handshake_set_state(
+                    ssl, MBEDTLS_SSL_CLIENT_FINISHED );
+            break;
+
+        case MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY:
+            ret = mbedtls_ssl_tls13_process_certificate_verify( ssl );
+            if( ret == 0 )
+            {
+                mbedtls_ssl_handshake_set_state(
+                    ssl, MBEDTLS_SSL_CLIENT_FINISHED );
+            }
+            break;
+
         default:
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
             return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
diff --git a/programs/aes/crypt_and_hash.c b/programs/aes/crypt_and_hash.c
index 74ea88c..7288548 100644
--- a/programs/aes/crypt_and_hash.c
+++ b/programs/aes/crypt_and_hash.c
@@ -137,11 +137,6 @@
             list++;
         }
 
-#if defined(_WIN32)
-        mbedtls_printf( "\n  Press Enter to exit this program.\n" );
-        fflush( stdout ); getchar();
-#endif
-
         goto exit;
     }
 
diff --git a/programs/fuzz/README.md b/programs/fuzz/README.md
index b6a4333..aaef030 100644
--- a/programs/fuzz/README.md
+++ b/programs/fuzz/README.md
@@ -35,10 +35,10 @@
 Finally, you can run the targets like `./test/fuzz/fuzz_client`.
 
 
-Corpus generation for network trafic targets
+Corpus generation for network traffic targets
 ------
 
-These targets use network trafic as inputs :
+These targets use network traffic as inputs :
 * client : simulates a client against (fuzzed) server traffic
 * server : simulates a server against (fuzzed) client traffic
 * dtls_client
@@ -48,7 +48,7 @@
 
 To generate corpus for these targets, you can do the following, not fully automated steps :
 * Build mbedtls programs ssl_server2 and ssl_client2
-* Run them one against the other with `reproducible` option turned on while capturing trafic into test.pcap
+* Run them one against the other with `reproducible` option turned on while capturing traffic into test.pcap
 * Extract tcp payloads, for instance with tshark : `tshark -Tfields -e tcp.dstport -e tcp.payload -r test.pcap > test.txt`
 * Run a dummy python script to output either client or server corpus file like `python dummy.py test.txt > test.cor`
 * Finally, you can add the options by appending the last bytes to the file test.cor
diff --git a/programs/fuzz/onefile.c b/programs/fuzz/onefile.c
index efd8dbb..730be36 100644
--- a/programs/fuzz/onefile.c
+++ b/programs/fuzz/onefile.c
@@ -47,7 +47,7 @@
         return 2;
     }
 
-    //lauch fuzzer
+    //launch fuzzer
     LLVMFuzzerTestOneInput(Data, Size);
     free(Data);
     fclose(fp);
diff --git a/programs/hash/generic_sum.c b/programs/hash/generic_sum.c
index 9243f0a..f38a976 100644
--- a/programs/hash/generic_sum.c
+++ b/programs/hash/generic_sum.c
@@ -192,11 +192,6 @@
             list++;
         }
 
-#if defined(_WIN32)
-        mbedtls_printf( "\n  Press Enter to exit this program.\n" );
-        fflush( stdout ); getchar();
-#endif
-
         mbedtls_exit( exit_code );
     }
 
diff --git a/programs/hash/hello.c b/programs/hash/hello.c
index d2b6910..cb8de8b 100644
--- a/programs/hash/hello.c
+++ b/programs/hash/hello.c
@@ -59,11 +59,6 @@
 
     mbedtls_printf( "\n\n" );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( MBEDTLS_EXIT_SUCCESS );
 }
 #endif /* MBEDTLS_MD5_C */
diff --git a/programs/pkey/dh_client.c b/programs/pkey/dh_client.c
index d633e4d..45de57b 100644
--- a/programs/pkey/dh_client.c
+++ b/programs/pkey/dh_client.c
@@ -300,11 +300,6 @@
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_AES_C && MBEDTLS_DHM_C && MBEDTLS_ENTROPY_C &&
diff --git a/programs/pkey/dh_genprime.c b/programs/pkey/dh_genprime.c
index 174a363..9ada4ea 100644
--- a/programs/pkey/dh_genprime.c
+++ b/programs/pkey/dh_genprime.c
@@ -186,11 +186,6 @@
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_FS_IO &&
diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c
index 75713ff..2956308 100644
--- a/programs/pkey/dh_server.c
+++ b/programs/pkey/dh_server.c
@@ -322,11 +322,6 @@
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_AES_C && MBEDTLS_DHM_C && MBEDTLS_ENTROPY_C &&
diff --git a/programs/pkey/ecdh_curve25519.c b/programs/pkey/ecdh_curve25519.c
index ca046fd..dff5480 100644
--- a/programs/pkey/ecdh_curve25519.c
+++ b/programs/pkey/ecdh_curve25519.c
@@ -222,11 +222,6 @@
 
 exit:
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_ecdh_free( &ctx_srv );
     mbedtls_ecdh_free( &ctx_cli );
     mbedtls_ctr_drbg_free( &ctr_drbg );
diff --git a/programs/pkey/ecdsa.c b/programs/pkey/ecdsa.c
index 550a230..c1c5070 100644
--- a/programs/pkey/ecdsa.c
+++ b/programs/pkey/ecdsa.c
@@ -232,11 +232,6 @@
 
 exit:
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_ecdsa_free( &ctx_verify );
     mbedtls_ecdsa_free( &ctx_sign );
     mbedtls_ctr_drbg_free( &ctr_drbg );
diff --git a/programs/pkey/gen_key.c b/programs/pkey/gen_key.c
index 7535eee..8779519 100644
--- a/programs/pkey/gen_key.c
+++ b/programs/pkey/gen_key.c
@@ -435,11 +435,6 @@
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_PK_WRITE_C && MBEDTLS_PEM_WRITE_C && MBEDTLS_FS_IO &&
diff --git a/programs/pkey/key_app.c b/programs/pkey/key_app.c
index 4203902..bd16b24 100644
--- a/programs/pkey/key_app.c
+++ b/programs/pkey/key_app.c
@@ -324,11 +324,6 @@
     mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &DP );
     mbedtls_mpi_free( &DQ ); mbedtls_mpi_free( &QP );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_PK_PARSE_C && MBEDTLS_FS_IO &&
diff --git a/programs/pkey/key_app_writer.c b/programs/pkey/key_app_writer.c
index ed6addf..df1e502 100644
--- a/programs/pkey/key_app_writer.c
+++ b/programs/pkey/key_app_writer.c
@@ -454,11 +454,6 @@
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_PK_PARSE_C && MBEDTLS_PK_WRITE_C && MBEDTLS_FS_IO &&
diff --git a/programs/pkey/mpi_demo.c b/programs/pkey/mpi_demo.c
index 6341752..eed8dfc 100644
--- a/programs/pkey/mpi_demo.c
+++ b/programs/pkey/mpi_demo.c
@@ -101,11 +101,6 @@
         mbedtls_printf( "\nAn error occurred.\n" );
     }
 
-#if defined(_WIN32)
-    mbedtls_printf( "  Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_FS_IO */
diff --git a/programs/pkey/pk_decrypt.c b/programs/pkey/pk_decrypt.c
index f1bfd8a..b09b6b8 100644
--- a/programs/pkey/pk_decrypt.c
+++ b/programs/pkey/pk_decrypt.c
@@ -162,11 +162,6 @@
     }
 #endif
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_PK_PARSE_C && MBEDTLS_FS_IO &&
diff --git a/programs/pkey/pk_encrypt.c b/programs/pkey/pk_encrypt.c
index 293c0a0..3df11f7 100644
--- a/programs/pkey/pk_encrypt.c
+++ b/programs/pkey/pk_encrypt.c
@@ -165,11 +165,6 @@
     }
 #endif
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_PK_PARSE_C && MBEDTLS_ENTROPY_C &&
diff --git a/programs/pkey/pk_sign.c b/programs/pkey/pk_sign.c
index 2ab428d..7b5d8e1 100644
--- a/programs/pkey/pk_sign.c
+++ b/programs/pkey/pk_sign.c
@@ -164,11 +164,6 @@
     }
 #endif
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C &&
diff --git a/programs/pkey/pk_verify.c b/programs/pkey/pk_verify.c
index 5173507..e82653b 100644
--- a/programs/pkey/pk_verify.c
+++ b/programs/pkey/pk_verify.c
@@ -136,11 +136,6 @@
     }
 #endif
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_SHA256_C &&
diff --git a/programs/pkey/rsa_decrypt.c b/programs/pkey/rsa_decrypt.c
index 42ec6a7..c01a5cf 100644
--- a/programs/pkey/rsa_decrypt.c
+++ b/programs/pkey/rsa_decrypt.c
@@ -196,11 +196,6 @@
     mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &DP );
     mbedtls_mpi_free( &DQ ); mbedtls_mpi_free( &QP );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_RSA_C && MBEDTLS_FS_IO */
diff --git a/programs/pkey/rsa_encrypt.c b/programs/pkey/rsa_encrypt.c
index f7ff68f..25a42d3 100644
--- a/programs/pkey/rsa_encrypt.c
+++ b/programs/pkey/rsa_encrypt.c
@@ -172,11 +172,6 @@
     mbedtls_entropy_free( &entropy );
     mbedtls_rsa_free( &rsa );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_RSA_C && MBEDTLS_ENTROPY_C &&
diff --git a/programs/pkey/rsa_genkey.c b/programs/pkey/rsa_genkey.c
index e48050a..67711bd 100644
--- a/programs/pkey/rsa_genkey.c
+++ b/programs/pkey/rsa_genkey.c
@@ -161,11 +161,6 @@
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_RSA_C &&
diff --git a/programs/pkey/rsa_sign.c b/programs/pkey/rsa_sign.c
index 5aa592d..1df9b13 100644
--- a/programs/pkey/rsa_sign.c
+++ b/programs/pkey/rsa_sign.c
@@ -177,11 +177,6 @@
     mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &DP );
     mbedtls_mpi_free( &DQ ); mbedtls_mpi_free( &QP );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_RSA_C && MBEDTLS_SHA256_C &&
diff --git a/programs/pkey/rsa_sign_pss.c b/programs/pkey/rsa_sign_pss.c
index 7ec7335..8078ab6 100644
--- a/programs/pkey/rsa_sign_pss.c
+++ b/programs/pkey/rsa_sign_pss.c
@@ -172,11 +172,6 @@
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_RSA_C &&
diff --git a/programs/pkey/rsa_verify.c b/programs/pkey/rsa_verify.c
index 1b3e193..a8b1abb 100644
--- a/programs/pkey/rsa_verify.c
+++ b/programs/pkey/rsa_verify.c
@@ -151,11 +151,6 @@
 
     mbedtls_rsa_free( &rsa );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_RSA_C && MBEDTLS_SHA256_C &&
diff --git a/programs/pkey/rsa_verify_pss.c b/programs/pkey/rsa_verify_pss.c
index d6634ba..3a20778 100644
--- a/programs/pkey/rsa_verify_pss.c
+++ b/programs/pkey/rsa_verify_pss.c
@@ -146,11 +146,6 @@
 exit:
     mbedtls_pk_free( &pk );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_RSA_C && MBEDTLS_SHA256_C &&
diff --git a/programs/psa/aead_demo.c b/programs/psa/aead_demo.c
index 5bc0af0..c4ed0dd 100644
--- a/programs/psa/aead_demo.c
+++ b/programs/psa/aead_demo.c
@@ -156,7 +156,7 @@
         return( PSA_ERROR_INVALID_ARGUMENT );
     }
 
-    /* Prepare key attibutes */
+    /* Prepare key attributes */
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
     psa_set_key_algorithm( &attributes, *alg );
diff --git a/programs/ssl/dtls_client.c b/programs/ssl/dtls_client.c
index 2bebb0d..e06d535 100644
--- a/programs/ssl/dtls_client.c
+++ b/programs/ssl/dtls_client.c
@@ -346,11 +346,6 @@
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     /* Shell can not handle large exit numbers -> 1 for errors */
     if( ret < 0 )
         ret = 1;
diff --git a/programs/ssl/dtls_server.c b/programs/ssl/dtls_server.c
index 5d1cccb..9317449 100644
--- a/programs/ssl/dtls_server.c
+++ b/programs/ssl/dtls_server.c
@@ -416,11 +416,6 @@
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
-#if defined(_WIN32)
-    printf( "  Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     /* Shell can not handle large exit numbers -> 1 for errors */
     if( ret < 0 )
         ret = 1;
diff --git a/programs/ssl/mini_client.c b/programs/ssl/mini_client.c
index 97bfe68..8f2fed8 100644
--- a/programs/ssl/mini_client.c
+++ b/programs/ssl/mini_client.c
@@ -37,7 +37,7 @@
  * dominate memory usage in small configurations. For the sake of simplicity,
  * only a Unix version is implemented.
  *
- * Warning: we are breaking some of the abtractions from the NET layer here.
+ * Warning: we are breaking some of the abstractions from the NET layer here.
  * This is not a good example for general use. This programs has the specific
  * goal of minimizing use of the libc functions on full-blown OSes.
  */
diff --git a/programs/ssl/ssl_client1.c b/programs/ssl/ssl_client1.c
index 3f7256f..a80ff71 100644
--- a/programs/ssl/ssl_client1.c
+++ b/programs/ssl/ssl_client1.c
@@ -305,11 +305,6 @@
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C &&
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index f741d99..97b786a 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -115,6 +115,7 @@
 #define DFL_USE_SRTP            0
 #define DFL_SRTP_FORCE_PROFILE  0
 #define DFL_SRTP_MKI            ""
+#define DFL_KEY_OPAQUE_ALG      "none"
 
 #define GET_REQUEST "GET %s HTTP/1.0\r\nExtra-header: "
 #define GET_REQUEST_END "\r\n\r\n"
@@ -343,6 +344,13 @@
 #define USAGE_SERIALIZATION ""
 #endif
 
+#define USAGE_KEY_OPAQUE_ALGS \
+    "    key_opaque_algs=%%s  Allowed opaque key algorithms.\n"                      \
+    "                        comma-separated pair of values among the following:\n"   \
+    "                        rsa-sign-pkcs1, rsa-sign-pss, rsa-decrypt,\n"           \
+    "                        ecdsa-sign, ecdh, none (only acceptable for\n"          \
+    "                        the second value).\n"                                   \
+
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
 #define USAGE_TLS1_3_KEY_EXCHANGE_MODES \
     "    tls13_kex_modes=%%s   default: all\n"     \
@@ -411,6 +419,7 @@
     USAGE_CURVES                                            \
     USAGE_SIG_ALGS                                          \
     USAGE_DHMLEN                                            \
+    USAGE_KEY_OPAQUE_ALGS                                   \
     "\n"
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
@@ -498,7 +507,7 @@
     int transport;              /* TLS or DTLS?                             */
     uint32_t hs_to_min;         /* Initial value of DTLS handshake timer    */
     uint32_t hs_to_max;         /* Max value of DTLS handshake timer        */
-    int dtls_mtu;               /* UDP Maximum tranport unit for DTLS       */
+    int dtls_mtu;               /* UDP Maximum transport unit for DTLS       */
     int fallback;               /* is this a fallback connection?           */
     int dgram_packing;          /* allow/forbid datagram packing            */
     int extended_ms;            /* negotiate extended master secret?        */
@@ -523,6 +532,8 @@
     int use_srtp;               /* Support SRTP                             */
     int force_srtp_profile;     /* SRTP protection profile to use or all    */
     const char *mki;            /* The dtls mki value to use                */
+    const char *key_opaque_alg1; /* Allowed opaque key alg 1                */
+    const char *key_opaque_alg2; /* Allowed Opaque key alg 2                */
 } opt;
 
 #include "ssl_test_common_source.c"
@@ -885,6 +896,8 @@
     opt.use_srtp            = DFL_USE_SRTP;
     opt.force_srtp_profile  = DFL_SRTP_FORCE_PROFILE;
     opt.mki                 = DFL_SRTP_MKI;
+    opt.key_opaque_alg1     = DFL_KEY_OPAQUE_ALG;
+    opt.key_opaque_alg2     = DFL_KEY_OPAQUE_ALG;
 
     for( i = 1; i < argc; i++ )
     {
@@ -1308,6 +1321,12 @@
         {
             opt.mki = q;
         }
+        else if( strcmp( p, "key_opaque_algs" ) == 0 )
+        {
+            if( key_opaque_alg_parse( q, &opt.key_opaque_alg1,
+                                         &opt.key_opaque_alg2 ) != 0 )
+                goto usage;
+        }
         else
             goto usage;
     }
@@ -1698,26 +1717,24 @@
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     if( opt.key_opaque != 0 )
     {
-        psa_algorithm_t psa_alg, psa_alg2;
+        psa_algorithm_t psa_alg, psa_alg2 = PSA_ALG_NONE;
+        psa_key_usage_t usage = 0;
 
-        if( mbedtls_pk_get_type( &pkey ) == MBEDTLS_PK_ECKEY )
+        if( key_opaque_set_alg_usage( opt.key_opaque_alg1,
+                                      opt.key_opaque_alg2,
+                                      &psa_alg, &psa_alg2,
+                                      &usage,
+                                      mbedtls_pk_get_type( &pkey ) ) == 0 )
         {
-            psa_alg = PSA_ALG_ECDSA( PSA_ALG_ANY_HASH );
-            psa_alg2 = PSA_ALG_NONE;
-        }
-        else
-        {
-            psa_alg = PSA_ALG_RSA_PKCS1V15_SIGN( PSA_ALG_ANY_HASH );
-            psa_alg2 = PSA_ALG_RSA_PSS( PSA_ALG_ANY_HASH );
-        }
-
-        if( ( ret = mbedtls_pk_wrap_as_opaque( &pkey, &key_slot, psa_alg,
-                                               PSA_KEY_USAGE_SIGN_HASH,
-                                               psa_alg2 ) ) != 0 )
-        {
-            mbedtls_printf( " failed\n  !  "
-                            "mbedtls_pk_wrap_as_opaque returned -0x%x\n\n", (unsigned int)  -ret );
-            goto exit;
+            ret = mbedtls_pk_wrap_as_opaque( &pkey, &key_slot, psa_alg,
+                                             usage, psa_alg2 );
+            if( ret != 0 )
+            {
+                mbedtls_printf( " failed\n  !  "
+                                "mbedtls_pk_wrap_as_opaque returned -0x%x\n\n",
+                                (unsigned int)  -ret );
+                goto exit;
+            }
         }
     }
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
@@ -3134,14 +3151,6 @@
     mbedtls_memory_buffer_alloc_free();
 #endif  /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */
 
-#if defined(_WIN32)
-    if( opt.query_config_mode == DFL_QUERY_CONFIG_MODE )
-    {
-        mbedtls_printf( "  + Press Enter to exit this program.\n" );
-        fflush( stdout ); getchar();
-    }
-#endif
-
     // Shell can not handle large exit numbers -> 1 for errors
     if( ret < 0 )
         ret = 1;
diff --git a/programs/ssl/ssl_fork_server.c b/programs/ssl/ssl_fork_server.c
index 694fc3b..07b3e6f 100644
--- a/programs/ssl/ssl_fork_server.c
+++ b/programs/ssl/ssl_fork_server.c
@@ -407,11 +407,6 @@
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C &&
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index 32960ad..664a384 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -848,11 +848,6 @@
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C &&
diff --git a/programs/ssl/ssl_pthread_server.c b/programs/ssl/ssl_pthread_server.c
index a8db4d8..ac14789 100644
--- a/programs/ssl/ssl_pthread_server.c
+++ b/programs/ssl/ssl_pthread_server.c
@@ -515,11 +515,6 @@
     mbedtls_memory_buffer_alloc_free();
 #endif
 
-#if defined(_WIN32)
-    mbedtls_printf( "  Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( ret );
 }
 
diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c
index 95557fb..3b66372 100644
--- a/programs/ssl/ssl_server.c
+++ b/programs/ssl/ssl_server.c
@@ -386,11 +386,6 @@
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( ret );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C &&
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index d728b95..c144b05 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -151,6 +151,7 @@
 #define DFL_USE_SRTP            0
 #define DFL_SRTP_FORCE_PROFILE  0
 #define DFL_SRTP_SUPPORT_MKI    0
+#define DFL_KEY_OPAQUE_ALG      "none"
 
 #define LONG_RESPONSE "<p>01-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
     "02-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n"  \
@@ -455,6 +456,17 @@
 #define USAGE_SERIALIZATION ""
 #endif
 
+#define USAGE_KEY_OPAQUE_ALGS \
+    "    key_opaque_algs=%%s  Allowed opaque key 1 algorithms.\n"                    \
+    "                        comma-separated pair of values among the following:\n"  \
+    "                        rsa-sign-pkcs1, rsa-sign-pss, rsa-decrypt,\n"           \
+    "                        ecdsa-sign, ecdh, none (only acceptable for\n"          \
+    "                        the second value).\n"                                   \
+    "    key_opaque_algs2=%%s Allowed opaque key 2 algorithms.\n"                    \
+    "                        comma-separated pair of values among the following:\n"  \
+    "                        rsa-sign-pkcs1, rsa-sign-pss, rsa-decrypt,\n"           \
+    "                        ecdsa-sign, ecdh, none (only acceptable for\n"          \
+    "                        the second value).\n"
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
 #define USAGE_TLS1_3_KEY_EXCHANGE_MODES \
     "    tls13_kex_modes=%%s   default: all\n"     \
@@ -519,6 +531,7 @@
     USAGE_ETM                                               \
     USAGE_CURVES                                            \
     USAGE_SIG_ALGS                                          \
+    USAGE_KEY_OPAQUE_ALGS                                   \
     "\n"
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
@@ -638,7 +651,7 @@
     int anti_replay;            /* Use anti-replay for DTLS? -1 for default */
     uint32_t hs_to_min;         /* Initial value of DTLS handshake timer    */
     uint32_t hs_to_max;         /* Max value of DTLS handshake timer        */
-    int dtls_mtu;               /* UDP Maximum tranport unit for DTLS       */
+    int dtls_mtu;               /* UDP Maximum transport unit for DTLS       */
     int dgram_packing;          /* allow/forbid datagram packing            */
     int badmac_limit;           /* Limit of records with bad MAC            */
     int eap_tls;                /* derive EAP-TLS keying material?          */
@@ -659,6 +672,10 @@
     int use_srtp;               /* Support SRTP                             */
     int force_srtp_profile;     /* SRTP protection profile to use or all    */
     int support_mki;            /* The dtls mki mki support                 */
+    const char *key1_opaque_alg1; /* Allowed opaque key 1 alg 1            */
+    const char *key1_opaque_alg2; /* Allowed Opaque key 1 alg 2            */
+    const char *key2_opaque_alg1; /* Allowed opaque key 2 alg 1            */
+    const char *key2_opaque_alg2; /* Allowed Opaque key 2 alg 2            */
 } opt;
 
 #include "ssl_test_common_source.c"
@@ -679,7 +696,7 @@
 }
 
 /*
- * Used by sni_parse and psk_parse to handle coma-separated lists
+ * Used by sni_parse and psk_parse to handle comma-separated lists
  */
 #define GET_ITEM( dst )         \
     do                          \
@@ -1615,6 +1632,10 @@
     opt.use_srtp            = DFL_USE_SRTP;
     opt.force_srtp_profile  = DFL_SRTP_FORCE_PROFILE;
     opt.support_mki         = DFL_SRTP_SUPPORT_MKI;
+    opt.key1_opaque_alg1   = DFL_KEY_OPAQUE_ALG;
+    opt.key1_opaque_alg2   = DFL_KEY_OPAQUE_ALG;
+    opt.key2_opaque_alg1   = DFL_KEY_OPAQUE_ALG;
+    opt.key2_opaque_alg2   = DFL_KEY_OPAQUE_ALG;
 
     for( i = 1; i < argc; i++ )
     {
@@ -2088,6 +2109,18 @@
         {
             opt.support_mki = atoi( q );
         }
+        else if( strcmp( p, "key_opaque_algs" ) == 0 )
+        {
+            if( key_opaque_alg_parse( q, &opt.key1_opaque_alg1,
+                                         &opt.key1_opaque_alg2 ) != 0 )
+                goto usage;
+        }
+        else if( strcmp( p, "key_opaque_algs2" ) == 0 )
+        {
+            if( key_opaque_alg_parse( q, &opt.key2_opaque_alg1,
+                                         &opt.key2_opaque_alg2 ) != 0 )
+                goto usage;
+        }
         else
             goto usage;
     }
@@ -2564,59 +2597,44 @@
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     if( opt.key_opaque != 0 )
     {
-        psa_algorithm_t psa_alg, psa_alg2;
-        psa_key_usage_t psa_usage;
+        psa_algorithm_t psa_alg, psa_alg2 = PSA_ALG_NONE;
+        psa_key_usage_t psa_usage = 0;
 
-        if ( mbedtls_pk_get_type( &pkey ) == MBEDTLS_PK_ECKEY ||
-             mbedtls_pk_get_type( &pkey ) == MBEDTLS_PK_RSA )
+        if( key_opaque_set_alg_usage( opt.key1_opaque_alg1,
+                                      opt.key1_opaque_alg2,
+                                      &psa_alg, &psa_alg2,
+                                      &psa_usage,
+                                      mbedtls_pk_get_type( &pkey ) ) == 0 )
         {
-            if( mbedtls_pk_get_type( &pkey ) == MBEDTLS_PK_ECKEY )
-            {
-                psa_alg = PSA_ALG_ECDSA( PSA_ALG_ANY_HASH );
-                psa_alg2 = PSA_ALG_ECDH;
-                psa_usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_DERIVE;
-            }
-            else
-            {
-                psa_alg = PSA_ALG_RSA_PKCS1V15_SIGN( PSA_ALG_ANY_HASH );
-                psa_alg2 = PSA_ALG_NONE;
-                psa_usage = PSA_KEY_USAGE_SIGN_HASH;
-            }
+            ret = mbedtls_pk_wrap_as_opaque( &pkey, &key_slot,
+                                             psa_alg, psa_usage, psa_alg2 );
 
-            if( ( ret = mbedtls_pk_wrap_as_opaque( &pkey, &key_slot,
-                                                   psa_alg,
-                                                   psa_usage,
-                                                   psa_alg2 ) ) != 0 )
+            if( ret != 0 )
             {
                 mbedtls_printf( " failed\n  !  "
-                                "mbedtls_pk_wrap_as_opaque returned -0x%x\n\n", (unsigned int)  -ret );
+                                "mbedtls_pk_wrap_as_opaque returned -0x%x\n\n",
+                                (unsigned int)  -ret );
                 goto exit;
             }
         }
 
-        if ( mbedtls_pk_get_type( &pkey2 ) == MBEDTLS_PK_ECKEY ||
-             mbedtls_pk_get_type( &pkey2 ) == MBEDTLS_PK_RSA )
-        {
-            if( mbedtls_pk_get_type( &pkey2 ) == MBEDTLS_PK_ECKEY )
-            {
-                psa_alg = PSA_ALG_ECDSA( PSA_ALG_ANY_HASH );
-                psa_alg2 = PSA_ALG_ECDH;
-                psa_usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_DERIVE;
-            }
-            else
-            {
-                psa_alg = PSA_ALG_RSA_PKCS1V15_SIGN( PSA_ALG_ANY_HASH );
-                psa_alg2 = PSA_ALG_NONE;
-                psa_usage = PSA_KEY_USAGE_SIGN_HASH;
-            }
+        psa_alg = PSA_ALG_NONE; psa_alg2 = PSA_ALG_NONE;
+        psa_usage = 0;
 
-            if( ( ret = mbedtls_pk_wrap_as_opaque( &pkey2, &key_slot2,
-                                                   psa_alg,
-                                                   psa_usage,
-                                                   psa_alg2 ) ) != 0 )
+        if( key_opaque_set_alg_usage( opt.key2_opaque_alg1,
+                                      opt.key2_opaque_alg2,
+                                      &psa_alg, &psa_alg2,
+                                      &psa_usage,
+                                      mbedtls_pk_get_type( &pkey2 ) ) == 0 )
+        {
+            ret = mbedtls_pk_wrap_as_opaque( &pkey2, &key_slot2,
+                                             psa_alg, psa_usage, psa_alg2 );
+
+            if( ret != 0 )
             {
                 mbedtls_printf( " failed\n  !  "
-                                "mbedtls_pk_wrap_as_opaque returned -0x%x\n\n", (unsigned int)  -ret );
+                                "mbedtls_pk_wrap_as_opaque returned -0x%x\n\n",
+                                (unsigned int)  -ret );
                 goto exit;
             }
         }
@@ -4213,11 +4231,6 @@
     if( opt.query_config_mode == DFL_QUERY_CONFIG_MODE )
     {
         mbedtls_printf( " done.\n" );
-
-#if defined(_WIN32)
-        mbedtls_printf( "  + Press Enter to exit this program.\n" );
-        fflush( stdout ); getchar();
-#endif
     }
 
     // Shell can not handle large exit numbers -> 1 for errors
diff --git a/programs/ssl/ssl_test_lib.c b/programs/ssl/ssl_test_lib.c
index a28a477..a7f3d0e 100644
--- a/programs/ssl/ssl_test_lib.c
+++ b/programs/ssl/ssl_test_lib.c
@@ -193,6 +193,103 @@
 #endif /* !MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
 }
 
+int key_opaque_alg_parse( const char *arg, const char **alg1, const char **alg2 )
+{
+    char* separator;
+    if( ( separator = strchr( arg, ',' ) ) == NULL )
+        return 1;
+    *separator = '\0';
+
+    *alg1 = arg;
+    *alg2 = separator + 1;
+
+    if( strcmp( *alg1, "rsa-sign-pkcs1" ) != 0 &&
+        strcmp( *alg1, "rsa-sign-pss" ) != 0 &&
+        strcmp( *alg1, "rsa-decrypt" ) != 0 &&
+        strcmp( *alg1, "ecdsa-sign" ) != 0 &&
+        strcmp( *alg1, "ecdh" ) != 0 )
+        return 1;
+
+    if( strcmp( *alg2, "rsa-sign-pkcs1" ) != 0 &&
+        strcmp( *alg2, "rsa-sign-pss" ) != 0 &&
+        strcmp( *alg2, "rsa-decrypt" ) != 0 &&
+        strcmp( *alg2, "ecdsa-sign" ) != 0 &&
+        strcmp( *alg2, "ecdh" ) != 0 &&
+        strcmp( *alg2, "none" ) != 0 )
+        return 1;
+
+    return 0;
+}
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+int key_opaque_set_alg_usage( const char *alg1, const char *alg2,
+                              psa_algorithm_t *psa_alg1,
+                              psa_algorithm_t *psa_alg2,
+                              psa_key_usage_t *usage,
+                              mbedtls_pk_type_t key_type )
+{
+    if( strcmp( alg1, "none" ) != 0 )
+    {
+        const char * algs[] = { alg1, alg2 };
+        psa_algorithm_t *psa_algs[] = { psa_alg1, psa_alg2 };
+
+        for ( int i = 0; i < 2; i++ )
+        {
+            if( strcmp( algs[i], "rsa-sign-pkcs1" ) == 0 )
+            {
+                *psa_algs[i] = PSA_ALG_RSA_PKCS1V15_SIGN( PSA_ALG_ANY_HASH );
+                *usage |= PSA_KEY_USAGE_SIGN_HASH;
+            }
+            else if( strcmp( algs[i], "rsa-sign-pss" ) == 0 )
+            {
+                *psa_algs[i] = PSA_ALG_RSA_PSS( PSA_ALG_ANY_HASH );
+                *usage |= PSA_KEY_USAGE_SIGN_HASH;
+            }
+            else if( strcmp( algs[i], "rsa-decrypt" ) == 0 )
+            {
+                *psa_algs[i] = PSA_ALG_RSA_PKCS1V15_CRYPT;
+                *usage |= PSA_KEY_USAGE_DECRYPT;
+            }
+            else if( strcmp( algs[i], "ecdsa-sign" ) == 0 )
+            {
+                *psa_algs[i] = PSA_ALG_ECDSA( PSA_ALG_ANY_HASH );
+                *usage |= PSA_KEY_USAGE_SIGN_HASH;
+            }
+            else if( strcmp( algs[i], "ecdh" ) == 0 )
+            {
+                *psa_algs[i] = PSA_ALG_ECDH;
+                *usage |= PSA_KEY_USAGE_DERIVE;
+            }
+            else if( strcmp( algs[i], "none" ) == 0 )
+            {
+                *psa_algs[i] = PSA_ALG_NONE;
+            }
+        }
+    }
+    else
+    {
+        if( key_type == MBEDTLS_PK_ECKEY )
+        {
+            *psa_alg1 = PSA_ALG_ECDSA( PSA_ALG_ANY_HASH );
+            *psa_alg2 = PSA_ALG_ECDH;
+            *usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_DERIVE;
+        }
+        else if( key_type == MBEDTLS_PK_RSA )
+        {
+            *psa_alg1 = PSA_ALG_RSA_PKCS1V15_SIGN( PSA_ALG_ANY_HASH );
+            *psa_alg2 = PSA_ALG_RSA_PSS( PSA_ALG_ANY_HASH );
+            *usage = PSA_KEY_USAGE_SIGN_HASH;
+        }
+        else
+        {
+            return 1;
+        }
+    }
+
+    return 0;
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
 #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
 int ca_callback( void *data, mbedtls_x509_crt const *child,
                  mbedtls_x509_crt **candidates )
diff --git a/programs/ssl/ssl_test_lib.h b/programs/ssl/ssl_test_lib.h
index a359b3f..03349ba 100644
--- a/programs/ssl/ssl_test_lib.h
+++ b/programs/ssl/ssl_test_lib.h
@@ -221,6 +221,48 @@
  */
 int rng_get( void *p_rng, unsigned char *output, size_t output_len );
 
+/** Parse command-line option: key_opaque_algs
+ *
+ *
+ * \param arg           String value of key_opaque_algs
+ *                      Coma-separated pair of values among the following:
+ *                      - "rsa-sign-pkcs1"
+ *                      - "rsa-sign-pss"
+ *                      - "rsa-decrypt"
+ *                      - "ecdsa-sign"
+ *                      - "ecdh"
+ *                      - "none" (only acceptable for the second value).
+ * \param alg1          Address of pointer to alg #1
+ * \param alg2          Address of pointer to alg #2
+ *
+ * \return              \c 0 on success.
+ * \return              \c 1 on parse failure.
+ */
+int key_opaque_alg_parse( const char *arg, const char **alg1, const char **alg2 );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/** Parse given opaque key algorithms to obtain psa algs and usage
+ *  that will be passed to mbedtls_pk_wrap_as_opaque().
+ *
+ *
+ * \param alg1          input string opaque key algorithm #1
+ * \param alg2          input string opaque key algorithm #2
+ * \param psa_alg1      output PSA algorithm #1
+ * \param psa_alg2      output PSA algorithm #2
+ * \param usage         output key usage
+ * \param key_type      key type used to set default psa algorithm/usage
+ *                      when alg1 in "none"
+ *
+ * \return              \c 0 on success.
+ * \return              \c 1 on parse failure.
+ */
+int key_opaque_set_alg_usage( const char *alg1, const char *alg2,
+                              psa_algorithm_t *psa_alg1,
+                              psa_algorithm_t *psa_alg2,
+                              psa_key_usage_t *usage,
+                              mbedtls_pk_type_t key_type );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
 #if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
 /* The test implementation of the PSA external RNG is insecure. When
  * MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled, before using any PSA crypto
@@ -236,7 +278,7 @@
 
 /*
  * Test recv/send functions that make sure each try returns
- * WANT_READ/WANT_WRITE at least once before sucesseding
+ * WANT_READ/WANT_WRITE at least once before succeeding
  */
 int delayed_recv( void *ctx, unsigned char *buf, size_t len );
 int delayed_send( void *ctx, const unsigned char *buf, size_t len );
diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c
index 6ff2eb8..a6d83e7 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -179,7 +179,7 @@
  *
  * This computes the maximum length of a title +3, because we appends "/s" and
  * want at least one space. (If the value is too small, the only consequence
- * is poor alignement.) */
+ * is poor alignment.) */
 #define TITLE_SPACE 17
 
 #define MEMORY_MEASURE_INIT                                             \
@@ -1280,11 +1280,6 @@
     mbedtls_memory_buffer_alloc_free();
 #endif
 
-#if defined(_WIN32)
-    mbedtls_printf( "  Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( 0 );
 }
 
diff --git a/programs/test/selftest.c b/programs/test/selftest.c
index 0c40686..a314bd2 100644
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -537,10 +537,6 @@
         {
             mbedtls_printf( "  [ All tests PASS ]\n\n" );
         }
-#if defined(_WIN32)
-        mbedtls_printf( "  Press Enter to exit this program.\n" );
-        fflush( stdout ); getchar();
-#endif
     }
 
     if( suites_failed > 0)
diff --git a/programs/test/udp_proxy.c b/programs/test/udp_proxy.c
index 41a90a9..e3386d1 100644
--- a/programs/test/udp_proxy.c
+++ b/programs/test/udp_proxy.c
@@ -1,5 +1,5 @@
 /*
- *  UDP proxy: emulate an unreliable UDP connexion for DTLS testing
+ *  UDP proxy: emulate an unreliable UDP connection for DTLS testing
  *
  *  Copyright The Mbed TLS Contributors
  *  SPDX-License-Identifier: Apache-2.0
@@ -73,9 +73,10 @@
 #endif
 #endif /* _MSC_VER */
 #else /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
-#if defined(MBEDTLS_HAVE_TIME)
+#if defined(MBEDTLS_HAVE_TIME) || (defined(MBEDTLS_TIMING_C) && !defined(MBEDTLS_TIMING_ALT))
 #include <sys/time.h>
 #endif
+#include <sys/select.h>
 #include <sys/types.h>
 #include <unistd.h>
 #endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
@@ -1015,11 +1016,6 @@
     mbedtls_net_free( &server_fd );
     mbedtls_net_free( &listen_fd );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 
diff --git a/programs/test/zeroize.c b/programs/test/zeroize.c
index a44099d..d6e5561 100644
--- a/programs/test/zeroize.c
+++ b/programs/test/zeroize.c
@@ -63,7 +63,7 @@
 
     if( argc != 2 )
     {
-        mbedtls_printf( "This program takes exactly 1 agument\n" );
+        mbedtls_printf( "This program takes exactly 1 argument\n" );
         usage();
         mbedtls_exit( exit_code );
     }
diff --git a/programs/util/pem2der.c b/programs/util/pem2der.c
index e273200..cf6a56c 100644
--- a/programs/util/pem2der.c
+++ b/programs/util/pem2der.c
@@ -279,11 +279,6 @@
 exit:
     free( pem_buffer );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BASE64_C && MBEDTLS_FS_IO */
diff --git a/programs/util/strerror.c b/programs/util/strerror.c
index 4b776d3..f91da13 100644
--- a/programs/util/strerror.c
+++ b/programs/util/strerror.c
@@ -78,11 +78,6 @@
         mbedtls_printf("Last error was: -0x%04x - %s\n\n", (unsigned int) -val, error_buf );
     }
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( val );
 }
 #endif /* MBEDTLS_ERROR_C */
diff --git a/programs/x509/cert_app.c b/programs/x509/cert_app.c
index 3d8f37b..985b970 100644
--- a/programs/x509/cert_app.c
+++ b/programs/x509/cert_app.c
@@ -486,11 +486,6 @@
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C &&
diff --git a/programs/x509/cert_req.c b/programs/x509/cert_req.c
index ed42079..7460bbf 100644
--- a/programs/x509/cert_req.c
+++ b/programs/x509/cert_req.c
@@ -389,11 +389,6 @@
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_X509_CSR_WRITE_C && MBEDTLS_PK_PARSE_C && MBEDTLS_FS_IO &&
diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c
index 763f868..793982d 100644
--- a/programs/x509/cert_write.c
+++ b/programs/x509/cert_write.c
@@ -793,11 +793,6 @@
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_X509_CRT_WRITE_C && MBEDTLS_X509_CRT_PARSE_C &&
diff --git a/programs/x509/crl_app.c b/programs/x509/crl_app.c
index 2720b1d..aa353be 100644
--- a/programs/x509/crl_app.c
+++ b/programs/x509/crl_app.c
@@ -138,11 +138,6 @@
 exit:
     mbedtls_x509_crl_free( &crl );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_RSA_C && MBEDTLS_X509_CRL_PARSE_C &&
diff --git a/programs/x509/req_app.c b/programs/x509/req_app.c
index fd316e2..24324ff 100644
--- a/programs/x509/req_app.c
+++ b/programs/x509/req_app.c
@@ -138,11 +138,6 @@
 exit:
     mbedtls_x509_csr_free( &csr );
 
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
     mbedtls_exit( exit_code );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_RSA_C && MBEDTLS_X509_CSR_PARSE_C &&
diff --git a/scripts/code_size_compare.py b/scripts/code_size_compare.py
index 85393d0..0ef438d 100755
--- a/scripts/code_size_compare.py
+++ b/scripts/code_size_compare.py
@@ -37,7 +37,7 @@
         """
         old_revision: revision to compare against
         new_revision:
-        result_dir: directory for comparision result
+        result_dir: directory for comparison result
         """
         self.repo_path = "."
         self.result_dir = os.path.abspath(result_dir)
@@ -140,7 +140,7 @@
                                      + "-" + self.new_rev + ".csv"), "w")
 
         res_file.write("file_name, this_size, old_size, change, change %\n")
-        print("Generating comparision results.")
+        print("Generating comparison results.")
 
         old_ds = {}
         for line in old_file.readlines()[1:]:
@@ -199,7 +199,7 @@
     parser.add_argument(
         "-n", "--new-rev", type=str, default=None,
         help="new revision for comparison, default is the current work \
-              directory, including uncommited changes."
+              directory, including uncommitted changes."
     )
     comp_args = parser.parse_args()
 
diff --git a/scripts/config.py b/scripts/config.py
index c09212b..356b998 100755
--- a/scripts/config.py
+++ b/scripts/config.py
@@ -418,7 +418,7 @@
         value = setting.value
         if value is None:
             value = ''
-        # Normally the whitespace to separte the symbol name from the
+        # Normally the whitespace to separate the symbol name from the
         # value is part of middle, and there's no whitespace for a symbol
         # with no value. But if a symbol has been changed from having a
         # value to not having one, the whitespace is wrong, so fix it.
diff --git a/scripts/driver.requirements.txt b/scripts/driver.requirements.txt
index 0d75a3d..5364d8e 100644
--- a/scripts/driver.requirements.txt
+++ b/scripts/driver.requirements.txt
@@ -10,7 +10,9 @@
 # See https://github.com/Mbed-TLS/mbedtls/pull/5067#discussion_r738794607 .
 # Note that Jinja 3.0 drops support for Python 3.5, so we need to support
 # Jinja 2.x as long as we're still using Python 3.5 anywhere.
-Jinja2 >= 2.10.1
+# Jinja 2.10.1 doesn't support Python 3.10+
+Jinja2 >= 2.10.1; python_version <  '3.10'
+Jinja2 >= 2.10.3; python_version >= '3.10'
 # Jinja2 >=2.10, <3.0 needs a separate package for type annotations
 types-Jinja2
 
diff --git a/scripts/generate_driver_wrappers.py b/scripts/generate_driver_wrappers.py
index 42331ac..71b881e 100755
--- a/scripts/generate_driver_wrappers.py
+++ b/scripts/generate_driver_wrappers.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python3
 """Generate library/psa_crypto_driver_wrappers.c
 
-   This module is invoked by the build sripts to auto generate the
+   This module is invoked by the build scripts to auto generate the
    psa_crypto_driver_wrappers.c based on template files in
    script/data_files/driver_templates/.
 """
diff --git a/scripts/generate_ssl_debug_helpers.py b/scripts/generate_ssl_debug_helpers.py
index 42e4fc8..959cbbc 100755
--- a/scripts/generate_ssl_debug_helpers.py
+++ b/scripts/generate_ssl_debug_helpers.py
@@ -53,7 +53,7 @@
     """
         Simple preprocessor for C source code.
 
-        Only processses condition directives without expanding them.
+        Only processes condition directives without expanding them.
         Yield object according to the classes input. Most match firstly
 
         If the directive pair does not match , raise CondDirectiveNotMatch.
@@ -234,6 +234,7 @@
                            prototype=self._prototype)
         return body
 
+
 class SignatureAlgorithmDefinition:
     """
         Generate helper functions for signature algorithms.
@@ -267,6 +268,7 @@
 
     def span(self):
         return self._definitions[0].span()
+
     def __str__(self):
         """
             Generate function for translating value to string
@@ -277,7 +279,7 @@
             translation_table.append(
                 '\tcase {}:\n\t    return "{}";'.format(name,
                                                         name[len('MBEDTLS_TLS1_3_SIG_'):].lower())
-                )
+            )
 
         body = textwrap.dedent('''\
             const char *mbedtls_ssl_sig_alg_to_str( uint16_t in )
@@ -287,11 +289,70 @@
             {translation_table}
                 }};
 
+                return "UNKNOWN";
+            }}''')
+        body = body.format(translation_table='\n'.join(translation_table))
+        return body
+
+
+class NamedGroupDefinition:
+    """
+        Generate helper functions for named group
+
+        It generates translation function from named group define to string.
+        Named group definition looks like:
+        #define MBEDTLS_SSL_IANA_TLS_GROUP_[ upper case named group ] [ value(hex) ]
+
+        Known limitation:
+        - the definitions SHOULD exist in same macro blocks.
+    """
+
+    @classmethod
+    def extract(cls, source_code, start=0, end=-1):
+        named_group_pattern = re.compile(r'#define\s+(?P<name>MBEDTLS_SSL_IANA_TLS_GROUP_\w+)\s+' +
+                                         r'(?P<value>0[xX][0-9a-fA-F]+)$',
+                                         re.MULTILINE | re.DOTALL)
+        matches = list(named_group_pattern.finditer(source_code, start, end))
+        if matches:
+            yield NamedGroupDefinition(source_code, definitions=matches)
+
+    def __init__(self, source_code, definitions=None):
+        if definitions is None:
+            definitions = []
+        assert isinstance(definitions, list) and definitions
+        self._definitions = definitions
+        self._source = source_code
+
+    def __repr__(self):
+        return 'NamedGroup({})'.format(self._definitions[0].span())
+
+    def span(self):
+        return self._definitions[0].span()
+
+    def __str__(self):
+        """
+            Generate function for translating value to string
+        """
+        translation_table = []
+        for m in self._definitions:
+            name = m.groupdict()['name']
+            iana_name = name[len('MBEDTLS_SSL_IANA_TLS_GROUP_'):].lower()
+            translation_table.append('\tcase {}:\n\t    return "{}";'.format(name, iana_name))
+
+        body = textwrap.dedent('''\
+            const char *mbedtls_ssl_named_group_to_str( uint16_t in )
+            {{
+                switch( in )
+                {{
+            {translation_table}
+                }};
+
                 return "UNKOWN";
             }}''')
         body = body.format(translation_table='\n'.join(translation_table))
         return body
 
+
 OUTPUT_C_TEMPLATE = '''\
 /* Automatically generated by generate_ssl_debug_helpers.py. DO NOT EDIT. */
 
@@ -335,14 +396,16 @@
     """
         Generate functions of debug helps
     """
-    mbedtls_root = os.path.abspath(mbedtls_root or build_tree.guess_mbedtls_root())
+    mbedtls_root = os.path.abspath(
+        mbedtls_root or build_tree.guess_mbedtls_root())
     with open(os.path.join(mbedtls_root, 'include/mbedtls/ssl.h')) as f:
         source_code = remove_c_comments(f.read())
 
     definitions = dict()
     for start, instance in preprocess_c_source_code(source_code,
                                                     EnumDefinition,
-                                                    SignatureAlgorithmDefinition):
+                                                    SignatureAlgorithmDefinition,
+                                                    NamedGroupDefinition):
         if start in definitions:
             continue
         if isinstance(instance, EnumDefinition):
diff --git a/scripts/min_requirements.py b/scripts/min_requirements.py
index eecab1c..c00d58e 100755
--- a/scripts/min_requirements.py
+++ b/scripts/min_requirements.py
@@ -44,8 +44,9 @@
         """Adjust a requirement to the minimum specified version."""
         # allow inheritance #pylint: disable=no-self-use
         # If a requirement specifies a minimum version, impose that version.
-        req = re.sub(r'>=|~=', r'==', req)
-        return req
+        split_req = req.split(';', 1)
+        split_req[0] = re.sub(r'>=|~=', r'==', split_req[0])
+        return ';'.join(split_req)
 
     def add_file(self, filename: str) -> None:
         """Add requirements from the specified file.
diff --git a/tests/data_files/Readme-x509.txt b/tests/data_files/Readme-x509.txt
index d07241a..84c775f 100644
--- a/tests/data_files/Readme-x509.txt
+++ b/tests/data_files/Readme-x509.txt
@@ -89,8 +89,8 @@
     _int-ca.crt: S7 + I1
     _int-ca_ca2.crt: S7 + I1 + 2
     _all_space.crt: S7 + I1 both with misplaced spaces (invalid PEM)
-    _pem_space.crt: S7 with misplace space (invalid PEM) + I1
-    _trailing_space.crt: S7 + I1 both with trainling space (valid PEM)
+    _pem_space.crt: S7 with misplaced space (invalid PEM) + I1
+    _trailing_space.crt: S7 + I1 both with trailing space (valid PEM)
     _spurious_int-ca.crt: S7 + I2(spurious) + I1
 - server8*.crt: I2 R L: RSA signed by EC signed by RSA (P1 for _int-ca2)
 - server9*.crt: 1 R C* L P1*: signed using RSASSA-PSS
diff --git a/tests/data_files/base64/def_b64_too_big_1.txt b/tests/data_files/base64/def_b64_too_big_1.txt
index 0fe8a18..47be05c 100644
--- a/tests/data_files/base64/def_b64_too_big_1.txt
+++ b/tests/data_files/base64/def_b64_too_big_1.txt
@@ -1,2 +1,2 @@
-// Context with added '1234' at the begining to simulate too much data in the base64 code
+// Context with added '1234' at the beginning to simulate too much data in the base64 code
 1234AhUAAH8AAA4AAAQ8AAAAAF6HQx3MqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACG2QbHbUj8eGpdx5KVIebiwk0jvRj9/3m6BOSzpA7qBXeEunhqr3D11NE7ciGjeHMAAAAAAAM7MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcNMTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTNowCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKzNtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kMtQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8PhYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjyaHT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgwFoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQELBQADggEBAC465FJhPqel7zJngHIHJrqj/wVAxGAFOTF396XKATGAp+HRCqJ81Ry60CNK1jDzk8dv6M6UHoS7RIFiM/9rXQCbJfiPD5xMTejZp5n5UYHAmxsxDaazfA5FuBhkfokKK6jD4Eq91C94xGKb6X4/VkaPF7cqoBBw/bHxawXc0UEPjqayiBpCYU/rJoVZgLqFVP7Px3sva1nOrNx8rPPI1hJ+ZOg8maiPTxHZnBVLakSSLQy/sWeWyazO1RnrbxjrbgQtYKz0e3nwGpu1w13vfckFmUSBhHXH7AAS/HpKC4IH7G2GAk3+n8iSSN71sZzpxonQwVbopMZqLmbBm/7WPLcAAJTfQC2Ek91INP5ihHNzImPOAHJCk+YTO/pQuEnNWwXbdmKAi+IRp671iAwtpkjSxCBXVzKX925F1A66caCOQptlw+9zFukDQgblM2JyAJLG0j6B4RtBTDWJ8ZTMUPHUoLJoEpm8APZgRi//DMRyCKP9pbBLGlDzgUvl0w11LzBAlJHkWau5NoqQBlG7w4HFrKweovskAAFRgAAAAF6HQx248L77RH0Z973tSYNQ8zBsz861CZG5/T09TJz3XodDHe/iJ+cgXb5An3zTdnTBtw3EWAb68T+gCE33GN8AAAAAAAAAAAAAAAEAAAAAAAAAAwAAAQAAAAAAAgAAAA==
diff --git a/tests/include/test/helpers.h b/tests/include/test/helpers.h
index ef32cdf..080b46e 100644
--- a/tests/include/test/helpers.h
+++ b/tests/include/test/helpers.h
@@ -155,6 +155,48 @@
                         unsigned long long value1, unsigned long long value2 );
 
 /**
+ * \brief           Record the current test case as a failure based
+ *                  on comparing two unsigned integers.
+ *
+ *                  This function is usually called via the macro
+ *                  #TEST_LE_U.
+ *
+ * \param test      Description of the failure or assertion that failed. This
+ *                  MUST be a string literal. This normally has the form
+ *                  "EXPR1 <= EXPR2" where EXPR1 has the value \p value1
+ *                  and EXPR2 has the value \p value2.
+ * \param line_no   Line number where the failure originated.
+ * \param filename  Filename where the failure originated.
+ * \param value1    The first value to compare.
+ * \param value2    The second value to compare.
+ *
+ * \return          \c 1 if \p value1 <= \p value2, otherwise \c 0.
+ */
+int mbedtls_test_le_u( const char *test, int line_no, const char* filename,
+                       unsigned long long value1, unsigned long long value2 );
+
+/**
+ * \brief           Record the current test case as a failure based
+ *                  on comparing two signed integers.
+ *
+ *                  This function is usually called via the macro
+ *                  #TEST_LE_S.
+ *
+ * \param test      Description of the failure or assertion that failed. This
+ *                  MUST be a string literal. This normally has the form
+ *                  "EXPR1 <= EXPR2" where EXPR1 has the value \p value1
+ *                  and EXPR2 has the value \p value2.
+ * \param line_no   Line number where the failure originated.
+ * \param filename  Filename where the failure originated.
+ * \param value1    The first value to compare.
+ * \param value2    The second value to compare.
+ *
+ * \return          \c 1 if \p value1 <= \p value2, otherwise \c 0.
+ */
+int mbedtls_test_le_s( const char *test, int line_no, const char* filename,
+                       long long value1, long long value2 );
+
+/**
  * \brief          This function decodes the hexadecimal representation of
  *                 data.
  *
diff --git a/tests/include/test/macros.h b/tests/include/test/macros.h
index a88b2e8..8535b93 100644
--- a/tests/include/test/macros.h
+++ b/tests/include/test/macros.h
@@ -89,6 +89,32 @@
             goto exit;                                                  \
     } while( 0 )
 
+/** Evaluate two unsigned integer expressions and fail the test case
+ * if they are not in increasing order (left <= right).
+ *
+ * \param expr1     An integral-typed expression to evaluate.
+ * \param expr2     Another integral-typed expression to evaluate.
+ */
+#define TEST_LE_U( expr1, expr2 )                                       \
+    do {                                                                \
+        if( ! mbedtls_test_le_u( #expr1 " <= " #expr2, __LINE__, __FILE__, \
+                                 expr1, expr2 ) )                      \
+            goto exit;                                                  \
+    } while( 0 )
+
+/** Evaluate two signed integer expressions and fail the test case
+ * if they are not in increasing order (left <= right).
+ *
+ * \param expr1     An integral-typed expression to evaluate.
+ * \param expr2     Another integral-typed expression to evaluate.
+ */
+#define TEST_LE_S( expr1, expr2 )                                       \
+    do {                                                                \
+        if( ! mbedtls_test_le_s( #expr1 " <= " #expr2, __LINE__, __FILE__, \
+                                 expr1, expr2 ) )                      \
+            goto exit;                                                  \
+    } while( 0 )
+
 /** Allocate memory dynamically and fail the test case if this fails.
  * The allocated memory will be filled with zeros.
  *
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 1e5cd65..6144c2f 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -259,7 +259,7 @@
      --no-force         Refuse to overwrite modified files (default).
      --no-keep-going    Stop at the first error (default).
      --no-memory        No additional memory tests (default).
-     --no-quiet         Print full ouput from components.
+     --no-quiet         Print full output from components.
      --out-of-source-dir=<path>  Directory used for CMake out-of-source build tests.
      --outcome-file=<path>  File where test outcomes are written (not done if
                             empty; default: \$MBEDTLS_TEST_OUTCOME_FILE).
@@ -1203,6 +1203,81 @@
     tests/ssl-opt.sh -f 'Default\|opaque'
 }
 
+component_test_crypto_full_no_md () {
+    msg "build: crypto_full minus MD"
+    scripts/config.py crypto_full
+    scripts/config.py unset MBEDTLS_MD_C
+    # Direct dependencies
+    scripts/config.py unset MBEDTLS_ECJPAKE_C
+    scripts/config.py unset MBEDTLS_HKDF_C
+    scripts/config.py unset MBEDTLS_HMAC_DRBG_C
+    scripts/config.py unset MBEDTLS_PK_C
+    scripts/config.py unset MBEDTLS_PKCS1_V15
+    scripts/config.py unset MBEDTLS_PKCS1_V21
+    scripts/config.py unset MBEDTLS_PKCS5_C
+    scripts/config.py unset MBEDTLS_PKCS12_C
+    # Indirect dependencies
+    scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC
+    scripts/config.py unset MBEDTLS_PK_PARSE_C
+    scripts/config.py unset MBEDTLS_PK_WRITE_C
+    scripts/config.py unset MBEDTLS_RSA_C
+    make
+
+    msg "test: crypto_full minus MD"
+    make test
+}
+
+component_test_full_no_cipher () {
+    msg "build: full minus CIPHER"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_CIPHER_C
+    # Direct dependencies
+    scripts/config.py unset MBEDTLS_CCM_C
+    scripts/config.py unset MBEDTLS_CMAC_C
+    scripts/config.py unset MBEDTLS_GCM_C
+    scripts/config.py unset MBEDTLS_NIST_KW_C
+    scripts/config.py unset MBEDTLS_PKCS12_C
+    scripts/config.py unset MBEDTLS_PKCS5_C
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_C
+    scripts/config.py unset MBEDTLS_SSL_TLS_C
+    scripts/config.py unset MBEDTLS_SSL_TICKET_C
+    # Indirect dependencies
+    scripts/config.py unset MBEDTLS_SSL_CLI_C
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C
+    scripts/config.py unset MBEDTLS_SSL_DTLS_ANTI_REPLAY
+    scripts/config.py unset MBEDTLS_SSL_DTLS_CONNECTION_ID
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    scripts/config.py unset MBEDTLS_SSL_SRV_C
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    make
+
+    msg "test: full minus CIPHER"
+    make test
+}
+
+component_test_crypto_full_no_cipher () {
+    msg "build: crypto_full minus CIPHER"
+    scripts/config.py crypto_full
+    scripts/config.py unset MBEDTLS_CIPHER_C
+    # Direct dependencies
+    scripts/config.py unset MBEDTLS_CCM_C
+    scripts/config.py unset MBEDTLS_CMAC_C
+    scripts/config.py unset MBEDTLS_GCM_C
+    scripts/config.py unset MBEDTLS_NIST_KW_C
+    scripts/config.py unset MBEDTLS_PKCS12_C
+    scripts/config.py unset MBEDTLS_PKCS5_C
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_C
+    # Indirect dependencies
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    make
+
+    msg "test: crypto_full minus CIPHER"
+    make test
+}
+
 component_test_psa_external_rng_use_psa_crypto () {
     msg "build: full + PSA_CRYPTO_EXTERNAL_RNG + USE_PSA_CRYPTO minus CTR_DRBG"
     scripts/config.py full
diff --git a/tests/scripts/check_files.py b/tests/scripts/check_files.py
index 8857e00..a0f5e1f 100755
--- a/tests/scripts/check_files.py
+++ b/tests/scripts/check_files.py
@@ -187,7 +187,7 @@
     # Allow either /bin/sh, /bin/bash, or /usr/bin/env.
     # Allow at most one argument (this is a Linux limitation).
     # For sh and bash, the argument if present must be options.
-    # For env, the argument must be the base name of the interpeter.
+    # For env, the argument must be the base name of the interpreter.
     _shebang_re = re.compile(rb'^#! ?(?:/bin/(bash|sh)(?: -[^\n ]*)?'
                              rb'|/usr/bin/env ([^\n /]+))$')
     _extensions = {
diff --git a/tests/scripts/check_names.py b/tests/scripts/check_names.py
index 8bb4923..96117a2 100755
--- a/tests/scripts/check_names.py
+++ b/tests/scripts/check_names.py
@@ -813,7 +813,7 @@
 
     def check_for_typos(self):
         """
-        Perform a check that all words in the soure code beginning with MBED are
+        Perform a check that all words in the source code beginning with MBED are
         either defined as macros, or as enum constants.
         Assumes parse_names_in_source() was called before this.
 
diff --git a/tests/scripts/depends-hashes.pl b/tests/scripts/depends-hashes.pl
index cd17066..68297a6 100755
--- a/tests/scripts/depends-hashes.pl
+++ b/tests/scripts/depends-hashes.pl
@@ -46,12 +46,12 @@
 
 # as many SSL options depend on specific hashes,
 # and SSL is not in the test suites anyways,
-# disable it to avoid dependcies issues
+# disable it to avoid dependency issues
 my $ssl_sed_cmd = 's/^#define \(MBEDTLS_SSL.*\)/\1/p';
 my @ssl = split( /\s+/, `sed -n -e '$ssl_sed_cmd' $config_h` );
 
 # Each element of this array holds list of configuration options that
-# should be tested together. Certain options depend on eachother and
+# should be tested together. Certain options depend on each other and
 # separating them would generate invalid configurations.
 my @hash_configs = (
     ['unset MBEDTLS_MD5_C'],
diff --git a/tests/scripts/generate_psa_tests.py b/tests/scripts/generate_psa_tests.py
index 492810b..3d23edd 100755
--- a/tests/scripts/generate_psa_tests.py
+++ b/tests/scripts/generate_psa_tests.py
@@ -165,6 +165,7 @@
     ALWAYS_SUPPORTED = frozenset([
         'PSA_KEY_TYPE_DERIVE',
         'PSA_KEY_TYPE_RAW_DATA',
+        'PSA_KEY_TYPE_HMAC'
     ])
     def test_cases_for_key_type_not_supported(
             self,
@@ -830,7 +831,7 @@
     def gather_key_types_for_sign_alg(self) -> Dict[str, List[str]]:
         # pylint: disable=too-many-locals
         """Match possible key types for sign algorithms."""
-        # To create a valid combinaton both the algorithms and key types
+        # To create a valid combination both the algorithms and key types
         # must be filtered. Pair them with keywords created from its names.
         incompatible_alg_keyword = frozenset(['RAW', 'ANY', 'PURE'])
         incompatible_key_type_keywords = frozenset(['MONTGOMERY'])
@@ -854,7 +855,7 @@
                     if re.match(pattern, keyword):
                         alg_keywords.remove(keyword)
                         alg_keywords.add(replace)
-            # Filter out incompatible algortihms
+            # Filter out incompatible algorithms
             if not alg_keywords.isdisjoint(incompatible_alg_keyword):
                 continue
 
@@ -862,7 +863,7 @@
                 # Generate keywords from the of the key type
                 key_type_keywords = set(key_type.translate(translation_table).split(sep='_')[3:])
 
-                # Remove ambigious keywords
+                # Remove ambiguous keywords
                 for keyword1, keyword2 in exclusive_keywords.items():
                     if keyword1 in key_type_keywords:
                         key_type_keywords.remove(keyword2)
@@ -879,7 +880,7 @@
         """Generate test keys for usage flag extensions."""
         # Generate a key type and algorithm pair for each extendable usage
         # flag to generate a valid key for exercising. The key is generated
-        # without usage extension to check the extension compatiblity.
+        # without usage extension to check the extension compatibility.
         alg_with_keys = self.gather_key_types_for_sign_alg()
 
         for usage in sorted(StorageKey.IMPLICIT_USAGE_FLAGS, key=str):
@@ -922,7 +923,7 @@
         filename = self.filename_for(basename)
         test_case.write_data_file(filename, test_cases)
 
-    # Note that targets whose name containns 'test_format' have their content
+    # Note that targets whose names contain 'test_format' have their content
     # validated by `abi_check.py`.
     TARGETS = {
         'test_suite_psa_crypto_generate_key.generated':
diff --git a/tests/scripts/recursion.pl b/tests/scripts/recursion.pl
index e4b2d94..2a7dba5 100755
--- a/tests/scripts/recursion.pl
+++ b/tests/scripts/recursion.pl
@@ -4,7 +4,7 @@
 # (Multiple recursion where a() calls b() which calls a() not covered.)
 #
 # When the recursion depth might depend on data controlled by the attacker in
-# an unbounded way, those functions should use interation instead.
+# an unbounded way, those functions should use iteration instead.
 #
 # Typical usage: scripts/recursion.pl library/*.c
 #
diff --git a/tests/scripts/test_psa_compliance.py b/tests/scripts/test_psa_compliance.py
index 3e7a9a6..7d06db1 100755
--- a/tests/scripts/test_psa_compliance.py
+++ b/tests/scripts/test_psa_compliance.py
@@ -1,5 +1,5 @@
 #!/usr/bin/env python3
-"""Run the PSA Cryto API compliance test suite.
+"""Run the PSA Crypto API compliance test suite.
 Clone the repo and check out the commit specified by PSA_ARCH_TEST_REPO and PSA_ARCH_TEST_REF,
 then complie and run the test suite. The clone is stored at <Mbed TLS root>/psa-arch-tests.
 Known defects in either the test suite or mbedtls - identified by their test number - are ignored,
@@ -47,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 = 'fix-pr-5139-3'
+PSA_ARCH_TESTS_REF = 'fix-pr-5736'
 
 #pylint: disable=too-many-branches,too-many-statements
 def main():
diff --git a/tests/src/helpers.c b/tests/src/helpers.c
index ec4d84e..8f4d7f2 100644
--- a/tests/src/helpers.c
+++ b/tests/src/helpers.c
@@ -122,6 +122,52 @@
     return( 0 );
 }
 
+int mbedtls_test_le_u( const char *test, int line_no, const char* filename,
+                       unsigned long long value1, unsigned long long value2 )
+{
+    if( value1 <= value2 )
+        return( 1 );
+    if( mbedtls_test_info.result == MBEDTLS_TEST_RESULT_FAILED )
+    {
+        /* We've already recorded the test as having failed. Don't
+         * overwrite any previous information about the failure. */
+        return( 0 );
+    }
+    mbedtls_test_fail( test, line_no, filename );
+    (void) mbedtls_snprintf( mbedtls_test_info.line1,
+                             sizeof( mbedtls_test_info.line1 ),
+                             "lhs = 0x%016llx = %llu",
+                             value1, value1 );
+    (void) mbedtls_snprintf( mbedtls_test_info.line2,
+                             sizeof( mbedtls_test_info.line2 ),
+                             "rhs = 0x%016llx = %llu",
+                             value2, value2 );
+    return( 0 );
+}
+
+int mbedtls_test_le_s( const char *test, int line_no, const char* filename,
+                       long long value1, long long value2 )
+{
+    if( value1 <= value2 )
+        return( 1 );
+    if( mbedtls_test_info.result == MBEDTLS_TEST_RESULT_FAILED )
+    {
+        /* We've already recorded the test as having failed. Don't
+         * overwrite any previous information about the failure. */
+        return( 0 );
+    }
+    mbedtls_test_fail( test, line_no, filename );
+    (void) mbedtls_snprintf( mbedtls_test_info.line1,
+                             sizeof( mbedtls_test_info.line1 ),
+                             "lhs = 0x%016llx = %lld",
+                             (unsigned long long) value1, value1 );
+    (void) mbedtls_snprintf( mbedtls_test_info.line2,
+                             sizeof( mbedtls_test_info.line2 ),
+                             "rhs = 0x%016llx = %lld",
+                             (unsigned long long) value2, value2 );
+    return( 0 );
+}
+
 int mbedtls_test_unhexify( unsigned char *obuf,
                            size_t obufmax,
                            const char *ibuf,
diff --git a/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c
index 9576afd..d1650f1 100644
--- a/tests/src/psa_exercise_key.c
+++ b/tests/src/psa_exercise_key.c
@@ -221,7 +221,7 @@
                                     sizeof( decrypted ) - part_length,
                                     &part_length );
         /* For a stream cipher, all inputs are valid. For a block cipher,
-         * if the input is some aribtrary data rather than an actual
+         * if the input is some arbitrary data rather than an actual
          ciphertext, a padding error is likely.  */
         if( maybe_invalid_padding )
             TEST_ASSERT( status == PSA_SUCCESS ||
@@ -929,7 +929,7 @@
         return( 0 );
 
     if( alg == 0 )
-        ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
+        ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
     else if( PSA_ALG_IS_MAC( alg ) )
         ok = exercise_mac_key( key, usage, alg );
     else if( PSA_ALG_IS_CIPHER( alg ) )
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index dcee5df..21d17f9 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -81,7 +81,7 @@
 if [ -n "${OPENSSL_NEXT:-}" ]; then
     O_NEXT_SRV="$OPENSSL_NEXT s_server -www -cert data_files/server5.crt -key data_files/server5.key"
     O_NEXT_SRV_NO_CERT="$OPENSSL_NEXT s_server -www "
-    O_NEXT_CLI="echo 'GET / HTTP/1.0' | $OPENSSL_NEXT s_client"
+    O_NEXT_CLI="echo 'GET / HTTP/1.0' | $OPENSSL_NEXT s_client -CAfile data_files/test-ca_cat12.crt"
 else
     O_NEXT_SRV=false
     O_NEXT_SRV_NO_CERT=false
@@ -1743,6 +1743,36 @@
             -S "error" \
             -C "error"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_RSA_C
+run_test    "RSA opaque key on server configured for decryption" \
+            "$P_SRV debug_level=1 key_opaque=1 key_opaque_algs=rsa-decrypt,none" \
+            "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA256" \
+            0 \
+            -c "Verifying peer X.509 certificate... ok" \
+            -c "Ciphersuite is TLS-RSA-" \
+            -s "key types: Opaque, Opaque" \
+            -s "Ciphersuite is TLS-RSA-" \
+            -S "error" \
+            -C "error"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_RSA_C
+run_test    "RSA-PSK opaque key on server configured for decryption" \
+            "$P_SRV debug_level=1 key_opaque=1 key_opaque_algs=rsa-decrypt,none \
+             psk=abc123 psk_identity=foo" \
+            "$P_CLI force_ciphersuite=TLS-RSA-PSK-WITH-AES-128-CBC-SHA256 \
+             psk=abc123 psk_identity=foo" \
+            0 \
+            -c "Verifying peer X.509 certificate... ok" \
+            -c "Ciphersuite is TLS-RSA-PSK-" \
+            -s "key types: Opaque, Opaque" \
+            -s "Ciphersuite is TLS-RSA-PSK-" \
+            -S "error" \
+            -C "error"
+
 # Test using an EC opaque private key for server authentication
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
@@ -4580,7 +4610,7 @@
             -C "error" \
             -s "Extra-header:"
 
-# Test for the "secure renegotation" extension only (no actual renegotiation)
+# Test for the "secure renegotiation" extension only (no actual renegotiation)
 
 requires_gnutls
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
@@ -5317,7 +5347,7 @@
             -s "use CA callback for X.509 CRT verification" \
             -S "X509 - A fatal error occurred"
 
-# Tests for certificate selection based on SHA verson
+# Tests for certificate selection based on SHA version
 
 requires_config_disabled MBEDTLS_X509_REMOVE_INFO
 run_test    "Certificate hash: client TLS 1.2 -> SHA-2" \
@@ -6399,8 +6429,6 @@
             "$P_CLI extended_ms=0 debug_level=1 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=foo psk=abc123 psk_opaque=1" \
             0 \
-            -c "skip PMS generation for opaque PSK"\
-            -S "skip PMS generation for opaque PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6414,8 +6442,6 @@
             "$P_CLI extended_ms=0 debug_level=1 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384 \
             psk_identity=foo psk=abc123 psk_opaque=1" \
             0 \
-            -c "skip PMS generation for opaque PSK"\
-            -S "skip PMS generation for opaque PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6429,8 +6455,6 @@
             "$P_CLI extended_ms=1 debug_level=3 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=foo psk=abc123 psk_opaque=1" \
             0 \
-            -c "skip PMS generation for opaque PSK"\
-            -S "skip PMS generation for opaque PSK"\
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6444,8 +6468,6 @@
             "$P_CLI extended_ms=1 debug_level=3 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384 \
             psk_identity=foo psk=abc123 psk_opaque=1" \
             0 \
-            -c "skip PMS generation for opaque PSK"\
-            -S "skip PMS generation for opaque PSK"\
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6459,8 +6481,6 @@
             "$P_CLI extended_ms=0 debug_level=1 min_version=tls12 force_ciphersuite=TLS-RSA-PSK-WITH-AES-128-CBC-SHA256 \
             psk_identity=foo psk=abc123 psk_opaque=1" \
             0 \
-            -c "skip PMS generation for opaque RSA-PSK"\
-            -S "skip PMS generation for opaque RSA-PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6474,8 +6494,6 @@
             "$P_CLI extended_ms=0 debug_level=1 min_version=tls12 force_ciphersuite=TLS-RSA-PSK-WITH-AES-256-CBC-SHA384 \
             psk_identity=foo psk=abc123 psk_opaque=1" \
             0 \
-            -c "skip PMS generation for opaque RSA-PSK"\
-            -S "skip PMS generation for opaque RSA-PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6489,8 +6507,6 @@
             "$P_CLI extended_ms=1 debug_level=3 min_version=tls12 force_ciphersuite=TLS-RSA-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=foo psk=abc123 psk_opaque=1" \
             0 \
-            -c "skip PMS generation for opaque RSA-PSK"\
-            -S "skip PMS generation for opaque RSA-PSK"\
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6504,8 +6520,6 @@
             "$P_CLI extended_ms=1 debug_level=3 min_version=tls12 force_ciphersuite=TLS-RSA-PSK-WITH-AES-256-CBC-SHA384 \
             psk_identity=foo psk=abc123 psk_opaque=1" \
             0 \
-            -c "skip PMS generation for opaque RSA-PSK"\
-            -S "skip PMS generation for opaque RSA-PSK"\
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6519,8 +6533,6 @@
             "$P_CLI extended_ms=0 debug_level=1 min_version=tls12 force_ciphersuite=TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256 \
             psk_identity=foo psk=abc123 psk_opaque=1" \
             0 \
-            -c "skip PMS generation for opaque ECDHE-PSK"\
-            -S "skip PMS generation for opaque ECDHE-PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6534,8 +6546,6 @@
             "$P_CLI extended_ms=0 debug_level=1 min_version=tls12 force_ciphersuite=TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384 \
             psk_identity=foo psk=abc123 psk_opaque=1" \
             0 \
-            -c "skip PMS generation for opaque ECDHE-PSK"\
-            -S "skip PMS generation for opaque ECDHE-PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6549,8 +6559,6 @@
             "$P_CLI extended_ms=1 debug_level=3 min_version=tls12 force_ciphersuite=TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=foo psk=abc123 psk_opaque=1" \
             0 \
-            -c "skip PMS generation for opaque ECDHE-PSK"\
-            -S "skip PMS generation for opaque ECDHE-PSK"\
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6564,8 +6572,6 @@
             "$P_CLI extended_ms=1 debug_level=3 min_version=tls12 force_ciphersuite=TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384 \
             psk_identity=foo psk=abc123 psk_opaque=1" \
             0 \
-            -c "skip PMS generation for opaque ECDHE-PSK"\
-            -S "skip PMS generation for opaque ECDHE-PSK"\
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6579,8 +6585,6 @@
             "$P_CLI extended_ms=0 debug_level=1 min_version=tls12 force_ciphersuite=TLS-DHE-PSK-WITH-AES-128-CBC-SHA256 \
             psk_identity=foo psk=abc123 psk_opaque=1" \
             0 \
-            -c "skip PMS generation for opaque DHE-PSK"\
-            -S "skip PMS generation for opaque DHE-PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6594,8 +6598,6 @@
             "$P_CLI extended_ms=0 debug_level=1 min_version=tls12 force_ciphersuite=TLS-DHE-PSK-WITH-AES-256-CBC-SHA384 \
             psk_identity=foo psk=abc123 psk_opaque=1" \
             0 \
-            -c "skip PMS generation for opaque DHE-PSK"\
-            -S "skip PMS generation for opaque DHE-PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6609,8 +6611,6 @@
             "$P_CLI extended_ms=1 debug_level=3 min_version=tls12 force_ciphersuite=TLS-DHE-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=foo psk=abc123 psk_opaque=1" \
             0 \
-            -c "skip PMS generation for opaque DHE-PSK"\
-            -S "skip PMS generation for opaque DHE-PSK"\
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6624,8 +6624,6 @@
             "$P_CLI extended_ms=1 debug_level=3 min_version=tls12 force_ciphersuite=TLS-DHE-PSK-WITH-AES-256-CBC-SHA384 \
             psk_identity=foo psk=abc123 psk_opaque=1" \
             0 \
-            -c "skip PMS generation for opaque DHE-PSK"\
-            -S "skip PMS generation for opaque DHE-PSK"\
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6639,8 +6637,6 @@
             "$P_CLI extended_ms=0 debug_level=1 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=foo psk=abc123" \
             0 \
-            -C "skip PMS generation for opaque PSK"\
-            -s "skip PMS generation for opaque PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6654,8 +6650,6 @@
             "$P_CLI extended_ms=0 debug_level=1 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384 \
             psk_identity=foo psk=abc123" \
             0 \
-            -C "skip PMS generation for opaque PSK"\
-            -s "skip PMS generation for opaque PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6672,8 +6666,6 @@
             0 \
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
-            -C "skip PMS generation for opaque PSK"\
-            -s "skip PMS generation for opaque PSK"\
             -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
@@ -6688,8 +6680,6 @@
             0 \
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
-            -C "skip PMS generation for opaque PSK"\
-            -s "skip PMS generation for opaque PSK"\
             -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
@@ -6701,8 +6691,6 @@
             "$P_CLI extended_ms=0 debug_level=5 min_version=tls12 force_ciphersuite=TLS-RSA-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=foo psk=abc123" \
             0 \
-            -C "skip PMS generation for opaque RSA-PSK"\
-            -s "skip PMS generation for opaque RSA-PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6716,8 +6704,6 @@
             "$P_CLI extended_ms=0 debug_level=1 min_version=tls12 force_ciphersuite=TLS-RSA-PSK-WITH-AES-256-CBC-SHA384 \
             psk_identity=foo psk=abc123" \
             0 \
-            -C "skip PMS generation for opaque RSA-PSK"\
-            -s "skip PMS generation for opaque RSA-PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6734,8 +6720,6 @@
             0 \
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
-            -C "skip PMS generation for opaque RSA-PSK"\
-            -s "skip PMS generation for opaque RSA-PSK"\
             -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
@@ -6750,8 +6734,6 @@
             0 \
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
-            -C "skip PMS generation for opaque RSA-PSK"\
-            -s "skip PMS generation for opaque RSA-PSK"\
             -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
@@ -6763,8 +6745,6 @@
             "$P_CLI extended_ms=0 debug_level=5 min_version=tls12 force_ciphersuite=TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=foo psk=abc123" \
             0 \
-            -C "skip PMS generation for opaque ECDHE-PSK"\
-            -s "skip PMS generation for opaque ECDHE-PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6778,8 +6758,6 @@
             "$P_CLI extended_ms=0 debug_level=1 min_version=tls12 force_ciphersuite=TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384 \
             psk_identity=foo psk=abc123" \
             0 \
-            -C "skip PMS generation for opaque ECDHE-PSK"\
-            -s "skip PMS generation for opaque ECDHE-PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6796,8 +6774,6 @@
             0 \
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
-            -C "skip PMS generation for opaque ECDHE-PSK"\
-            -s "skip PMS generation for opaque ECDHE-PSK"\
             -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
@@ -6812,8 +6788,6 @@
             0 \
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
-            -C "skip PMS generation for opaque ECDHE-PSK"\
-            -s "skip PMS generation for opaque ECDHE-PSK"\
             -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
@@ -6825,8 +6799,6 @@
             "$P_CLI extended_ms=0 debug_level=5 min_version=tls12 force_ciphersuite=TLS-DHE-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=foo psk=abc123" \
             0 \
-            -C "skip PMS generation for opaque DHE-PSK"\
-            -s "skip PMS generation for opaque DHE-PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6840,8 +6812,6 @@
             "$P_CLI extended_ms=0 debug_level=1 min_version=tls12 force_ciphersuite=TLS-DHE-PSK-WITH-AES-256-CBC-SHA384 \
             psk_identity=foo psk=abc123" \
             0 \
-            -C "skip PMS generation for opaque DHE-PSK"\
-            -s "skip PMS generation for opaque DHE-PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6858,8 +6828,6 @@
             0 \
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
-            -C "skip PMS generation for opaque DHE-PSK"\
-            -s "skip PMS generation for opaque DHE-PSK"\
             -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
@@ -6874,8 +6842,6 @@
             0 \
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
-            -C "skip PMS generation for opaque DHE-PSK"\
-            -s "skip PMS generation for opaque DHE-PSK"\
             -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
@@ -6887,8 +6853,6 @@
             "$P_CLI extended_ms=0 debug_level=3 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=def psk=beef" \
             0 \
-            -C "skip PMS generation for opaque PSK"\
-            -s "skip PMS generation for opaque PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6902,8 +6866,6 @@
             "$P_CLI extended_ms=0 debug_level=3 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384 \
             psk_identity=def psk=beef" \
             0 \
-            -C "skip PMS generation for opaque PSK"\
-            -s "skip PMS generation for opaque PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6920,8 +6882,6 @@
             0 \
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
-            -C "skip PMS generation for opaque PSK"\
-            -s "skip PMS generation for opaque PSK"\
             -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
@@ -6936,8 +6896,6 @@
             0 \
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
-            -C "skip PMS generation for opaque PSK"\
-            -s "skip PMS generation for opaque PSK"\
             -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
@@ -6949,8 +6907,6 @@
             "$P_CLI extended_ms=0 debug_level=3 min_version=tls12 force_ciphersuite=TLS-RSA-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=def psk=beef" \
             0 \
-            -C "skip PMS generation for opaque RSA-PSK"\
-            -s "skip PMS generation for opaque RSA-PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6964,8 +6920,6 @@
             "$P_CLI extended_ms=0 debug_level=3 min_version=tls12 force_ciphersuite=TLS-RSA-PSK-WITH-AES-256-CBC-SHA384 \
             psk_identity=def psk=beef" \
             0 \
-            -C "skip PMS generation for opaque RSA-PSK"\
-            -s "skip PMS generation for opaque RSA-PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -6982,8 +6936,6 @@
             0 \
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
-            -C "skip PMS generation for opaque RSA-PSK"\
-            -s "skip PMS generation for opaque RSA-PSK"\
             -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
@@ -6998,8 +6950,6 @@
             0 \
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
-            -C "skip PMS generation for opaque RSA-PSK"\
-            -s "skip PMS generation for opaque RSA-PSK"\
             -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
@@ -7011,8 +6961,6 @@
             "$P_CLI extended_ms=0 debug_level=3 min_version=tls12 force_ciphersuite=TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=def psk=beef" \
             0 \
-            -C "skip PMS generation for opaque ECDHE-PSK"\
-            -s "skip PMS generation for opaque ECDHE-PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -7026,8 +6974,6 @@
             "$P_CLI extended_ms=0 debug_level=3 min_version=tls12 force_ciphersuite=TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384 \
             psk_identity=def psk=beef" \
             0 \
-            -C "skip PMS generation for opaque ECDHE-PSK"\
-            -s "skip PMS generation for opaque ECDHE-PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -7044,8 +6990,6 @@
             0 \
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
-            -C "skip PMS generation for opaque ECDHE-PSK"\
-            -s "skip PMS generation for opaque ECDHE-PSK"\
             -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
@@ -7060,8 +7004,6 @@
             0 \
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
-            -C "skip PMS generation for opaque ECDHE-PSK"\
-            -s "skip PMS generation for opaque ECDHE-PSK"\
             -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
@@ -7073,8 +7015,6 @@
             "$P_CLI extended_ms=0 debug_level=3 min_version=tls12 force_ciphersuite=TLS-DHE-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=def psk=beef" \
             0 \
-            -C "skip PMS generation for opaque DHE-PSK"\
-            -s "skip PMS generation for opaque DHE-PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -7088,8 +7028,6 @@
             "$P_CLI extended_ms=0 debug_level=3 min_version=tls12 force_ciphersuite=TLS-DHE-PSK-WITH-AES-256-CBC-SHA384 \
             psk_identity=def psk=beef" \
             0 \
-            -C "skip PMS generation for opaque DHE-PSK"\
-            -s "skip PMS generation for opaque DHE-PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -7106,8 +7044,6 @@
             0 \
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
-            -C "skip PMS generation for opaque DHE-PSK"\
-            -s "skip PMS generation for opaque DHE-PSK"\
             -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
@@ -7122,8 +7058,6 @@
             0 \
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
-            -C "skip PMS generation for opaque DHE-PSK"\
-            -s "skip PMS generation for opaque DHE-PSK"\
             -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
@@ -7135,8 +7069,6 @@
             "$P_CLI extended_ms=0 debug_level=3 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=def psk=beef" \
             0 \
-            -C "skip PMS generation for opaque PSK"\
-            -s "skip PMS generation for opaque PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -7150,8 +7082,6 @@
             "$P_CLI extended_ms=0 debug_level=3 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=def psk=beef" \
             0 \
-            -C "skip PMS generation for opaque PSK"\
-            -s "skip PMS generation for opaque PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -7165,7 +7095,6 @@
             "$P_CLI extended_ms=0 debug_level=3 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=def psk=beef" \
             0 \
-            -C "skip PMS generation for opaque PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -7179,7 +7108,6 @@
             "$P_CLI extended_ms=0 debug_level=3 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=def psk=beef" \
             0 \
-            -C "skip PMS generation for opaque PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
             -S "SSL - The handshake negotiation failed" \
@@ -9170,7 +9098,7 @@
 # certificate obtained from the server. Here, however, it
 # connects to 127.0.0.1 while our test certificates use 'localhost'
 # as the server name in the certificate. This will make the
-# certifiate validation fail, but passing --insecure makes
+# certificate validation fail, but passing --insecure makes
 # GnuTLS continue the connection nonetheless.
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
@@ -10941,7 +10869,7 @@
             -c "client state: MBEDTLS_SSL_CLIENT_CERTIFICATE" \
             -c "client state: MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY" \
             -c "signature algorithm not in received or offered list." \
-            -C "unkown pk type"
+            -C "unknown pk type"
 
 requires_gnutls_tls1_3
 requires_gnutls_next_no_ticket
@@ -10959,7 +10887,7 @@
             -c "client state: MBEDTLS_SSL_CLIENT_CERTIFICATE" \
             -c "client state: MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY" \
             -c "signature algorithm not in received or offered list." \
-            -C "unkown pk type"
+            -C "unknown pk type"
 
 # Test using an opaque private key for client authentication
 requires_openssl_tls1_3
@@ -11296,18 +11224,39 @@
             -c "Protocol is TLSv1.3" \
             -c "HTTP/1.0 200 OK"
 
+requires_openssl_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test    "TLS 1.3: Server side check - openssl" \
+            "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=0" \
+            "$O_NEXT_CLI -msg -debug -tls1_3 -no_middlebox" \
+            0 \
+            -s "tls13 server state: MBEDTLS_SSL_CLIENT_HELLO" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_HELLO" \
+            -s "tls13 server state: MBEDTLS_SSL_ENCRYPTED_EXTENSIONS" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_CERTIFICATE" \
+            -s "tls13 server state: MBEDTLS_SSL_CERTIFICATE_VERIFY" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_FINISHED" \
+            -s "tls13 server state: MBEDTLS_SSL_CLIENT_FINISHED" \
+            -s "tls13 server state: MBEDTLS_SSL_HANDSHAKE_WRAPUP"
+
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_SRV_C
 requires_openssl_tls1_3
-run_test    "TLS 1.3: Server side check - openssl" \
-            "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=0" \
-            "$O_NEXT_CLI -msg -debug -tls1_3" \
-            1 \
+run_test    "TLS 1.3: Server side check - openssl with client authentication" \
+            "$P_SRV debug_level=4 auth_mode=required crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=0" \
+            "$O_NEXT_CLI -msg -debug -cert data_files/server5.crt -key data_files/server5.key -tls1_3 -no_middlebox" \
+            0 \
             -s "tls13 server state: MBEDTLS_SSL_CLIENT_HELLO" \
             -s "tls13 server state: MBEDTLS_SSL_SERVER_HELLO" \
             -s "tls13 server state: MBEDTLS_SSL_ENCRYPTED_EXTENSIONS" \
-            -s "SSL - The requested feature is not available" \
+            -s "tls13 server state: MBEDTLS_SSL_CERTIFICATE_REQUEST" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_CERTIFICATE" \
+            -s "tls13 server state: MBEDTLS_SSL_CERTIFICATE_VERIFY" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_FINISHED" \
+            -s "=> write certificate request" \
             -s "=> parse client hello" \
             -s "<= parse client hello"
 
@@ -11319,11 +11268,34 @@
 run_test    "TLS 1.3: Server side check - gnutls" \
             "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=0" \
             "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:%NO_TICKETS:%DISABLE_TLS13_COMPAT_MODE -V" \
-            1 \
+            0 \
             -s "tls13 server state: MBEDTLS_SSL_CLIENT_HELLO" \
             -s "tls13 server state: MBEDTLS_SSL_SERVER_HELLO" \
             -s "tls13 server state: MBEDTLS_SSL_ENCRYPTED_EXTENSIONS" \
-            -s "SSL - The requested feature is not available" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_CERTIFICATE" \
+            -s "tls13 server state: MBEDTLS_SSL_CERTIFICATE_VERIFY" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_FINISHED" \
+            -s "tls13 server state: MBEDTLS_SSL_CLIENT_FINISHED" \
+            -s "tls13 server state: MBEDTLS_SSL_HANDSHAKE_WRAPUP" \
+            -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_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test    "TLS 1.3: Server side check - gnutls with client authentication" \
+            "$P_SRV debug_level=4 auth_mode=required crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=0" \
+            "$G_NEXT_CLI localhost -d 4 --x509certfile data_files/server5.crt --x509keyfile data_files/server5.key --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:%NO_TICKETS:%DISABLE_TLS13_COMPAT_MODE -V" \
+            0 \
+            -s "tls13 server state: MBEDTLS_SSL_CLIENT_HELLO" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_HELLO" \
+            -s "tls13 server state: MBEDTLS_SSL_ENCRYPTED_EXTENSIONS" \
+            -s "tls13 server state: MBEDTLS_SSL_CERTIFICATE_REQUEST" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_CERTIFICATE" \
+            -s "tls13 server state: MBEDTLS_SSL_CERTIFICATE_VERIFY" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_FINISHED" \
+            -s "=> write certificate request" \
             -s "=> parse client hello" \
             -s "<= parse client hello"
 
@@ -11334,15 +11306,98 @@
 run_test    "TLS 1.3: Server side check - mbedtls" \
             "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=0" \
             "$P_CLI debug_level=4 force_version=tls13" \
+            0 \
+            -s "tls13 server state: MBEDTLS_SSL_CLIENT_HELLO" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_HELLO" \
+            -s "tls13 server state: MBEDTLS_SSL_ENCRYPTED_EXTENSIONS" \
+            -s "tls13 server state: MBEDTLS_SSL_CERTIFICATE_REQUEST" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_CERTIFICATE" \
+            -s "tls13 server state: MBEDTLS_SSL_CERTIFICATE_VERIFY" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_FINISHED" \
+            -s "tls13 server state: MBEDTLS_SSL_CLIENT_FINISHED" \
+            -s "tls13 server state: MBEDTLS_SSL_HANDSHAKE_WRAPUP" \
+            -c "HTTP/1.0 200 OK"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3: Server side check - mbedtls with client authentication" \
+            "$P_SRV debug_level=4 auth_mode=required crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=0" \
+            "$P_CLI debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13" \
+            0 \
+            -s "tls13 server state: MBEDTLS_SSL_CLIENT_HELLO" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_HELLO" \
+            -s "tls13 server state: MBEDTLS_SSL_ENCRYPTED_EXTENSIONS" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_CERTIFICATE" \
+            -s "=> write certificate request" \
+            -c "client state: MBEDTLS_SSL_CERTIFICATE_REQUEST" \
+            -s "=> parse client hello" \
+            -s "<= parse client hello"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3: Server side check - mbedtls with client empty certificate" \
+            "$P_SRV debug_level=4 auth_mode=required crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=0" \
+            "$P_CLI debug_level=4 crt_file=none key_file=none force_version=tls13" \
             1 \
             -s "tls13 server state: MBEDTLS_SSL_CLIENT_HELLO" \
             -s "tls13 server state: MBEDTLS_SSL_SERVER_HELLO" \
             -s "tls13 server state: MBEDTLS_SSL_ENCRYPTED_EXTENSIONS" \
-            -c "client state: MBEDTLS_SSL_ENCRYPTED_EXTENSIONS" \
-            -s "SSL - The requested feature is not available" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_CERTIFICATE" \
+            -s "=> write certificate request" \
+            -s "SSL - No client certification received from the client, but required by the authentication mode" \
+            -c "client state: MBEDTLS_SSL_CERTIFICATE_REQUEST" \
             -s "=> parse client hello" \
             -s "<= parse client hello"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3: Server side check - mbedtls with optional client authentication" \
+            "$P_SRV debug_level=4 auth_mode=optional crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=0" \
+            "$P_CLI debug_level=4 force_version=tls13 crt_file=none key_file=none" \
+            0 \
+            -s "tls13 server state: MBEDTLS_SSL_CLIENT_HELLO" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_HELLO" \
+            -s "tls13 server state: MBEDTLS_SSL_ENCRYPTED_EXTENSIONS" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_CERTIFICATE" \
+            -s "=> write certificate request" \
+            -c "client state: MBEDTLS_SSL_CERTIFICATE_REQUEST" \
+            -s "=> parse client hello" \
+            -s "<= parse client hello"
+
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+run_test "TLS 1.3: server: HRR check - mbedtls" \
+         "$P_SRV debug_level=4 force_version=tls13 curves=secp384r1" \
+         "$P_CLI debug_level=4 force_version=tls13 curves=secp256r1,secp384r1" \
+         0 \
+        -s "tls13 server state: MBEDTLS_SSL_CLIENT_HELLO" \
+        -s "tls13 server state: MBEDTLS_SSL_SERVER_HELLO" \
+        -s "tls13 server state: MBEDTLS_SSL_ENCRYPTED_EXTENSIONS" \
+        -s "tls13 server state: MBEDTLS_SSL_HELLO_RETRY_REQUEST" \
+        -c "client state: MBEDTLS_SSL_ENCRYPTED_EXTENSIONS" \
+        -s "selected_group: secp384r1" \
+        -s "=> write hello retry request" \
+        -s "<= write hello retry request"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3: Server side check, no server certificate available" \
+            "$P_SRV debug_level=4 crt_file=none key_file=none force_version=tls13" \
+            "$P_CLI debug_level=4 force_version=tls13" \
+            1 \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_CERTIFICATE" \
+            -s "No certificate available."
+
 for i in opt-testcases/*.sh
 do
     TEST_SUITE_NAME=${i##*/}
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index 7481c5b..a620178 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -44,9 +44,12 @@
 
 #include <string.h>
 
+#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__MINGW32__)
+#include <strings.h>
+#endif
+
 #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
 #include <unistd.h>
-#include <strings.h>
 #endif
 
 /* Type for Hex parameters */
diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function
index 17926eb..b9ea3d6 100644
--- a/tests/suites/host_test.function
+++ b/tests/suites/host_test.function
@@ -519,7 +519,7 @@
     FILE *file;
     char buf[5000];
     char *params[50];
-    /* Store for proccessed integer params. */
+    /* Store for processed integer params. */
     int32_t int_params[50];
     void *pointer;
 #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
diff --git a/tests/suites/test_suite_aria.function b/tests/suites/test_suite_aria.function
index 0426324..ad7c773 100644
--- a/tests/suites/test_suite_aria.function
+++ b/tests/suites/test_suite_aria.function
@@ -1,7 +1,7 @@
 /* BEGIN_HEADER */
 #include "mbedtls/aria.h"
 
-/* Maxium size of data used by test vectors
+/* Maximum size of data used by test vectors
  * WARNING: to be adapted if and when adding larger test cases */
 #define ARIA_MAX_DATASIZE  160
 
diff --git a/tests/suites/test_suite_ecdh.function b/tests/suites/test_suite_ecdh.function
index 6893bcf..68db8fe 100644
--- a/tests/suites/test_suite_ecdh.function
+++ b/tests/suites/test_suite_ecdh.function
@@ -262,7 +262,7 @@
     rnd_info_B.buf = dB->x;
     rnd_info_B.length = dB->len;
 
-    /* The ECDH context is not guaranteed ot have an mbedtls_ecp_group structure
+    /* The ECDH context is not guaranteed to have an mbedtls_ecp_group structure
      * in every configuration, therefore we load it separately. */
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
 
diff --git a/tests/suites/test_suite_ecjpake.data b/tests/suites/test_suite_ecjpake.data
index fe14f88..73808c9 100644
--- a/tests/suites/test_suite_ecjpake.data
+++ b/tests/suites/test_suite_ecjpake.data
@@ -49,7 +49,7 @@
 ECJPAKE round one: KKP1: no second point data
 read_round_one:MBEDTLS_ECJPAKE_CLIENT:"41047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b0104":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
 
-ECJPAKE round one: KKP1: unknow second point format
+ECJPAKE round one: KKP1: unknown second point format
 read_round_one:MBEDTLS_ECJPAKE_CLIENT:"41047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b410509f85b3d20ebd7885ce464c08d056d6428fe4dd9287aa365f131f4360ff386d846898bc4b41583c2a5197f65d78742746c12a5ec0a4ffe2f270a750a1d8fb516":MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
 
 ECJPAKE round one: KKP1: nothing after second point
@@ -97,7 +97,7 @@
 ECJPAKE round one: KKP2: no second point data
 read_round_one:MBEDTLS_ECJPAKE_CLIENT:"4104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb1241047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b0104":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
 
-ECJPAKE round one: KKP2: unknow second point format
+ECJPAKE round one: KKP2: unknown second point format
 read_round_one:MBEDTLS_ECJPAKE_CLIENT:"4104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb1241047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b410509f85b3d20ebd7885ce464c08d056d6428fe4dd9287aa365f131f4360ff386d846898bc4b41583c2a5197f65d78742746c12a5ec0a4ffe2f270a750a1d8fb516":MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
 
 ECJPAKE round one: KKP2: nothing after second point
@@ -190,7 +190,7 @@
 ECJPAKE round two server: no data
 read_round_two_srv:"":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
 
-ECJPAKE round two server: length of forst point too small
+ECJPAKE round two server: length of first point too small
 read_round_two_srv:"00":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
 
 ECJPAKE round two server: length of first point too big
diff --git a/tests/suites/test_suite_md.function b/tests/suites/test_suite_md.function
index 2deb92a..602afa4 100644
--- a/tests/suites/test_suite_md.function
+++ b/tests/suites/test_suite_md.function
@@ -21,7 +21,7 @@
     /*
      * Very minimal testing of mbedtls_md_process, just make sure the various
      * xxx_process_wrap() function pointers are valid. (Testing that they
-     * indeed do the right thing whould require messing with the internal
+     * indeed do the right thing would require messing with the internal
      * state of the underlying mbedtls_md/sha context.)
      *
      * Also tests that mbedtls_md_list() only returns valid MDs.
diff --git a/tests/suites/test_suite_net.function b/tests/suites/test_suite_net.function
index 513b723..08d48b3 100644
--- a/tests/suites/test_suite_net.function
+++ b/tests/suites/test_suite_net.function
@@ -28,7 +28,7 @@
  *                      On success, it refers to the opened file (\p wanted_fd).
  * \param wanted_fd     The desired file descriptor.
  *
- * \return              \c 0 on succes, a negative error code on error.
+ * \return              \c 0 on success, a negative error code on error.
  */
 static int open_file_on_fd( mbedtls_net_context *ctx, int wanted_fd )
 {
diff --git a/tests/suites/test_suite_oid.function b/tests/suites/test_suite_oid.function
index 5c56ef4..a255530 100644
--- a/tests/suites/test_suite_oid.function
+++ b/tests/suites/test_suite_oid.function
@@ -82,7 +82,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_MD_C */
 void oid_get_md_alg_id( data_t *oid, int exp_md_id )
 {
     mbedtls_asn1_buf md_oid = { 0, 0, NULL };
diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data
index a0844ea..6fd595c 100644
--- a/tests/suites/test_suite_pk.data
+++ b/tests/suites/test_suite_pk.data
@@ -49,6 +49,266 @@
 depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
 pk_psa_utils:1
 
+PK can do ext: ECDSA(ANY)/NONE, invalid check STREAM_CIPHER
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_ALG_NONE:256:PSA_ALG_STREAM_CIPHER:PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: ECDSA(ANY)/NONE, invalid check RSA_PKCS1V15_SIGN(SHA256)
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_ALG_NONE:256:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: ECDSA(ANY)/NONE, invalid check RSA_PKCS1V15_CRYPT
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_ALG_NONE:256:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: ECDSA(ANY)/NONE, invalid check RSA_PSS(SHA256)
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_ALG_NONE:256:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: ECDSA(ANY)/NONE, invalid check ECDH
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_ALG_NONE:256:PSA_ALG_ECDH:PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: ECDSA(ANY)/NONE, check ECDSA(SHA256)
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_ALG_NONE:256:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: ECDSA(SHA256)/NONE, check ECDSA(SHA256)
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_ALG_NONE:256:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: NONE/ECDSA(ANY_HASH), check ECDSA(SHA256)
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_NONE:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):256:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: NONE/ECDSA(SHA256), check ECDSA(SHA256)
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_NONE:PSA_ALG_ECDSA(PSA_ALG_SHA_256):256:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: ECDSA(SHA256)/NONE, invalid check ECDSA(ANY)
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_ALG_NONE:256:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: ECDSA(SHA1)/NONE, invalid check ECDSA(SHA256)
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_ECDSA(PSA_ALG_SHA_1):PSA_ALG_NONE:256:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: ECDH/NONE, invalid check STREAM_CIPHER
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_ALG_NONE:256:PSA_ALG_STREAM_CIPHER:PSA_KEY_USAGE_DERIVE:0
+
+PK can do ext: ECDH/NONE, invalid check RSA_PKCS1V15_SIGN(SHA256)
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_ALG_NONE:256:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_USAGE_DERIVE:0
+
+PK can do ext: ECDH/NONE, invalid check RSA_PKCS1V15_CRYPT
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_ALG_NONE:256:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_USAGE_DERIVE:0
+
+PK can do ext: ECDH/NONE, invalid check RSA_PSS(SHA256)
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_ALG_NONE:256:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_KEY_USAGE_DERIVE:0
+
+PK can do ext: ECDH/NONE, invalid check ECDSA(SHA256)
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_ALG_NONE:256:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_KEY_USAGE_DERIVE:0
+
+PK can do ext: ECDH/NONE, check ECDH
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_ALG_NONE:256:PSA_ALG_ECDH:PSA_KEY_USAGE_DERIVE:1
+
+PK can do ext: ECDH/ECDSA(ANY), check ECDH+SIGN
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_DERIVE|PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_ECDH:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):256:PSA_ALG_ECDH:PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: ECDH/ECDSA(ANY), check ECDH+DERIVE
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_DERIVE|PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_ECDH:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):256:PSA_ALG_ECDH:PSA_KEY_USAGE_DERIVE:1
+
+PK can do ext: ECDH/ECDSA(ANY), check ECDH+DERIVE|SIGN
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_DERIVE|PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_ECDH:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):256:PSA_ALG_ECDH:PSA_KEY_USAGE_DERIVE|PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: ECDH/ECDSA(ANY), check ECDSA(SHA256)+DERIVE|SIGN
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_DERIVE|PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_ECDH:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):256:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_KEY_USAGE_DERIVE|PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: ECDH/ECDSA(ANY), check ECDSA(SHA256)+SIGN
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_DERIVE|PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_ECDH:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):256:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: ECDH/ECDSA(ANY), check ECDSA(SHA256)+DERIVE
+depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_KEY_USAGE_DERIVE|PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_ECDH:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):256:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_KEY_USAGE_DERIVE:1
+
+PK can do ext: RSA_PKCS1V15_SIGN(ANY)/NONE, check not allowed COPY usage
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_ALG_NONE:1024:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_USAGE_COPY:0
+
+PK can do ext: RSA_PKCS1V15_SIGN(ANY)/NONE, invalid check STREAM_CIPHER
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_ALG_NONE:1024:PSA_ALG_STREAM_CIPHER:PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: RSA_PKCS1V15_SIGN(ANY)/NONE, invalid check ECDSA(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_ALG_NONE:1024:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: RSA_PKCS1V15_SIGN(ANY)/NONE, invalid check ECDH
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_ALG_NONE:1024:PSA_ALG_ECDH:PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: RSA_PKCS1V15_SIGN(ANY)/NONE, invalid check RSA_PKCS1V15_CRYPT
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_ALG_NONE:1024:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: RSA_PKCS1V15_SIGN(ANY)/NONE, invalid check RSA_PSS(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_ALG_NONE:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: RSA_PKCS1V15_SIGN(ANY)/NONE, check RSA_PKCS1V15_SIGN(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_ALG_NONE:1024:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: RSA_PKCS1V15_SIGN(ANY)/NONE, check non-present usage
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_ALG_NONE:1024:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_USAGE_DERIVE:0
+
+PK can do ext: RSA_PKCS1V15_SIGN(SHA256)/NONE, check RSA_PKCS1V15_SIGN(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_ALG_NONE:1024:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: NONE, RSA_PKCS1V15_SIGN(ANY), check RSA_PKCS1V15_SIGN(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_NONE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):1024:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: NONE, RSA_PKCS1V15_SIGN(SHA256), check RSA_PKCS1V15_SIGN(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_NONE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):1024:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: RSA_PKCS1V15_SIGN(SHA256)/NONE, invalid check RSA_PKCS1V15_SIGN(ANY)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_ALG_NONE:1024:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: RSA_PKCS1V15_SIGN(SHA1)/NONE, invalid check RSA_PKCS1V15_SIGN(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_1):PSA_ALG_NONE:1024:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: RSA_PSS(ANY)/NONE, invalid check STREAM_CIPHER
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH):PSA_ALG_NONE:1024:PSA_ALG_STREAM_CIPHER:PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: RSA_PSS(ANY)/NONE, invalid check ECDSA(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH):PSA_ALG_NONE:1024:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: RSA_PSS(ANY)/NONE, invalid check RSA_PKCS1V15_CRYPT
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH):PSA_ALG_NONE:1024:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: RSA_PSS(ANY)/NONE, invalid check RSA_PKCS1V15_SIGN(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH):PSA_ALG_NONE:1024:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: RSA_PSS(ANY)/NONE, check RSA_PSS(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH):PSA_ALG_NONE:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: RSA_PSS(SHA256)/NONE, check RSA_PSS(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_ALG_NONE:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: NONE, RSA_PSS(ANY), check RSA_PSS(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_NONE:PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH):1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: NONE, RSA_PSS(SHA256), check RSA_PSS(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_NONE:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: RSA_PSS(SHA256)/NONE, invalid check RSA_PSS(ANY)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_ALG_NONE:1024:PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH):PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: RSA_PSS(SHA1)/NONE, invalid check RSA_PSS(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PSS(PSA_ALG_SHA_1):PSA_ALG_NONE:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: RSA_PKCS1V15_SIGN_RAW/NONE, check RSA_PKCS1V15_SIGN_RAW
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_ALG_NONE:1024:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: RSA_PKCS1V15_SIGN_RAW/NONE, invalid check RSA_PKCS1V15_SIGN(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_ALG_NONE:1024:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:0
+
+PK can do ext: RSA_PKCS1V15_CRYPT/NONE, invalid check STREAM_CIPHER
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_ENCRYPT|PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ALG_NONE:1024:PSA_ALG_STREAM_CIPHER:PSA_KEY_USAGE_ENCRYPT|PSA_KEY_USAGE_DECRYPT:0
+
+PK can do ext: RSA_PKCS1V15_CRYPT/NONE, invalid check ECDSA(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_ENCRYPT|PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ALG_NONE:1024:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_KEY_USAGE_ENCRYPT|PSA_KEY_USAGE_DECRYPT:0
+
+PK can do ext: RSA_PKCS1V15_CRYPT/NONE, invalid check ECDH
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_ENCRYPT|PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ALG_NONE:1024:PSA_ALG_ECDH:PSA_KEY_USAGE_ENCRYPT|PSA_KEY_USAGE_DECRYPT:0
+
+PK can do ext: RSA_PKCS1V15_CRYPT/NONE, invalid check RSA_PSS(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_ENCRYPT|PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ALG_NONE:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_KEY_USAGE_ENCRYPT|PSA_KEY_USAGE_DECRYPT:0
+
+PK can do ext: RSA_PKCS1V15_CRYPT/NONE, invalid check RSA_PKCS1V15_SIGN(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_ENCRYPT|PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ALG_NONE:1024:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_USAGE_ENCRYPT|PSA_KEY_USAGE_DECRYPT:0
+
+PK can do ext: RSA_PKCS1V15_CRYPT/NONE, check RSA_PKCS1V15_CRYPT
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_ENCRYPT|PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ALG_NONE:1024:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_USAGE_DECRYPT:1
+
+PK can do ext: RSA_PKCS1V15_CRYPT/RSA_PSS(ANY), check RSA_PKCS1V15_CRYPT
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_ENCRYPT|PSA_KEY_USAGE_DECRYPT|PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH):1024:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_USAGE_DECRYPT:1
+
+PK can do ext: RSA_PKCS1V15_CRYPT/RSA_PSS(ANY), check RSA_PSS(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_ENCRYPT|PSA_KEY_USAGE_DECRYPT|PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH):1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_KEY_USAGE_DECRYPT:1
+
+PK can do ext: RSA_PKCS1V15_CRYPT/RSA_PSS(ANY), check non allowed ENCRYPT usage
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_ENCRYPT|PSA_KEY_USAGE_DECRYPT|PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH):1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_KEY_USAGE_ENCRYPT:0
+
+PK can do ext: RSA_PKCS1V15_SIGN(ANY)/RSA_PSS(ANY), check RSA_PSS(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH):1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: RSA_PKCS1V15_SIGN(ANY)/RSA_PSS(ANY), check RSA_PKCS1V15_SIGN(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:1:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH):1024:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: MBEDTLS_PK_ECKEY, check ECDSA(SHA256)
+depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:0:MBEDTLS_PK_ECKEY:0:0:0:MBEDTLS_ECP_DP_SECP256R1:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: MBEDTLS_PK_ECKEY, check ECDH
+depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_can_do_ext:0:MBEDTLS_PK_ECKEY:0:0:0:MBEDTLS_ECP_DP_SECP256R1:PSA_ALG_ECDH:PSA_KEY_USAGE_DERIVE:1
+
+PK can do ext: MBEDTLS_PK_RSA, check RSA_PKCS1V15_SIGN(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:0:MBEDTLS_PK_RSA:0:0:0:1024:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:1
+
+PK can do ext: MBEDTLS_PK_RSA, check PSA_ALG_RSA_PKCS1V15_CRYPT
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:0:MBEDTLS_PK_RSA:0:0:0:1024:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_USAGE_DECRYPT:1
+
+PK can do ext: MBEDTLS_PK_RSA, check invalid PSA_KEY_USAGE_ENCRYPT
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:0:MBEDTLS_PK_RSA:0:0:0:1024:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_USAGE_ENCRYPT:0
+
+PK can do ext: MBEDTLS_PK_RSA, check RSA_PSS(SHA256)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_can_do_ext:0:MBEDTLS_PK_RSA:0:0:0:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN_HASH:1
+
 RSA verify test vector #1 (good)
 depends_on:MBEDTLS_SHA1_C:MBEDTLS_PKCS1_V15
 pk_rsa_verify_test_vec:"206ef4bf396c6087f8229ef196fd35f37ccb8de5efcdb238f20d556668f114257a11fbe038464a67830378e62ae9791453953dac1dbd7921837ba98e84e856eb80ed9487e656d0b20c28c8ba5e35db1abbed83ed1c7720a97701f709e3547a4bfcabca9c89c57ad15c3996577a0ae36d7c7b699035242f37954646c1cd5c08ac":MBEDTLS_MD_SHA1:1024:16:"e28a13548525e5f36dccb24ecb7cc332cc689dfd64012604c9c7816d72a16c3f5fcdc0e86e7c03280b1c69b586ce0cd8aec722cc73a5d3b730310bf7dfebdc77ce5d94bbc369dc18a2f7b07bd505ab0f82224aef09fdc1e5063234255e0b3c40a52e9e8ae60898eb88a766bdd788fe9493d8fd86bcdd2884d5c06216c65469e5":16:"3":"5abc01f5de25b70867ff0c24e222c61f53c88daf42586fddcd56f3c4588f074be3c328056c063388688b6385a8167957c6e5355a510e005b8a851d69c96b36ec6036644078210e5d7d326f96365ee0648882921492bc7b753eb9c26cdbab37555f210df2ca6fec1b25b463d38b81c0dcea202022b04af5da58aa03d77be949b7":0
@@ -153,6 +413,14 @@
 depends_on:MBEDTLS_PKCS1_V15
 pk_rsa_decrypt_test_vec:"a42eda41e56235e666e7faaa77100197f657288a1bf183e4820f0c37ce2c456b960278d6003e0bbcd4be4a969f8e8fd9231e1f492414f00ed09844994c86ec32db7cde3bec7f0c3dbf6ae55baeb2712fa609f5fc3207a824eb3dace31849cd6a6084318523912bccb84cf42e3c6d6d1685131d69bb545acec827d2b0dfdd5568b7dcc4f5a11d6916583fefa689d367f8c9e1d95dcd2240895a9470b0c1730f97cd6e8546860bd254801769f54be96e16362ddcbf34d56035028890199e0f48db38642cb66a4181e028a6443a404feb284ce02b4614b683367d40874e505611d23142d49f06feea831d52d347b13610b413c4efc43a6de9f0b08d2a951dc503b6":2048:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"4E636AF98E40F3ADCFCCB698F4E80B9F":MBEDTLS_ERR_RSA_INVALID_PADDING
 
+RSA Opaque decrypt test vector #1
+depends_on:MBEDTLS_PKCS1_V15
+pk_wrap_rsa_decrypt_test_vec:"a42eda41e56235e666e7faaa77100197f657288a1bf183e4820f0c37ce2c456b960278d6003e0bbcd4be4a969f8e8fd9231e1f492414f00ed09844994c86ec32db7cde3bec7f0c3dbf6ae55baeb2712fa609f5fc3207a824eb3dace31849cd6a6084318523912bccb84cf42e3c6d6d1685131d69bb545acec827d2b0dfdd5568b7dcc4f5a11d6916583fefa689d367f8c9e1d95dcd2240895a9470b0c1730f97cd6e8546860bd254801769f54be96e16362ddcbf34d56035028890199e0f48db38642cb66a4181e028a6443a404fea284ce02b4614b683367d40874e505611d23142d49f06feea831d52d347b13610b413c4efc43a6de9f0b08d2a951dc503b6":2048:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"4E636AF98E40F3ADCFCCB698F4E80B9F":0
+
+RSA Opaque decrypt test vector #2
+depends_on:MBEDTLS_PKCS1_V15
+pk_wrap_rsa_decrypt_test_vec:"a42eda41e56235e666e7faaa77100197f657288a1bf183e4820f0c37ce2c456b960278d6003e0bbcd4be4a969f8e8fd9231e1f492414f00ed09844994c86ec32db7cde3bec7f0c3dbf6ae55baeb2712fa609f5fc3207a824eb3dace31849cd6a6084318523912bccb84cf42e3c6d6d1685131d69bb545acec827d2b0dfdd5568b7dcc4f5a11d6916583fefa689d367f8c9e1d95dcd2240895a9470b0c1730f97cd6e8546860bd254801769f54be96e16362ddcbf34d56035028890199e0f48db38642cb66a4181e028a6443a404feb284ce02b4614b683367d40874e505611d23142d49f06feea831d52d347b13610b413c4efc43a6de9f0b08d2a951dc503b6":2048:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"4E636AF98E40F3ADCFCCB698F4E80B9F":MBEDTLS_ERR_RSA_INVALID_PADDING
+
 EC nocrypt
 depends_on:MBEDTLS_ECP_C
 pk_ec_nocrypt:MBEDTLS_PK_ECKEY
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index 32c2644..34ebdcc 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -168,12 +168,12 @@
 
     if( key_is_rsa )
     {
-        bitlen = 1024; /* harcoded in genkey() */
+        bitlen = 1024; /* hardcoded in genkey() */
         key = pk_psa_genkey_rsa();
     }
     else
     {
-        bitlen = 256; /* harcoded in genkey() */
+        bitlen = 256; /* hardcoded in genkey() */
         key = pk_psa_genkey_ecc();
     }
     if( mbedtls_svc_key_id_is_null( key ) )
@@ -204,10 +204,13 @@
     TEST_ASSERT( mbedtls_pk_verify( &pk, md_alg,
                                     b1, sizeof( b1), b2, sizeof( b2 ) )
                  == MBEDTLS_ERR_PK_TYPE_MISMATCH );
-    TEST_ASSERT( mbedtls_pk_decrypt( &pk, b1, sizeof( b1 ),
-                                     b2, &len, sizeof( b2 ),
-                                     NULL, NULL )
-                 == MBEDTLS_ERR_PK_TYPE_MISMATCH );
+    if( key_is_rsa == 0 )
+    {
+        TEST_ASSERT( mbedtls_pk_decrypt( &pk, b1, sizeof( b1 ),
+                                         b2, &len, sizeof( b2 ),
+                                         NULL, NULL )
+                     == MBEDTLS_ERR_PK_TYPE_MISMATCH );
+    }
     TEST_ASSERT( mbedtls_pk_encrypt( &pk, b1, sizeof( b1 ),
                                      b2, &len, sizeof( b2 ),
                                      NULL, NULL )
@@ -244,6 +247,54 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:MBEDTLS_USE_PSA_CRYPTO */
+void pk_can_do_ext( int opaque_key, int key_type, int key_usage, int key_alg,
+                    int key_alg2, int parameter, int alg_check, int usage_check,
+                    int result )
+{
+    mbedtls_pk_context pk;
+    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    mbedtls_pk_init( &pk );
+
+    if( opaque_key == 1 )
+    {
+        psa_set_key_usage_flags( &attributes, key_usage );
+        psa_set_key_algorithm( &attributes, key_alg );
+        if( key_alg2 != 0 )
+            psa_set_key_enrollment_algorithm( &attributes, key_alg2 );
+        psa_set_key_type( &attributes, key_type );
+        psa_set_key_bits( &attributes, parameter );
+
+        PSA_ASSERT( psa_generate_key( &attributes, &key ) );
+
+        if( mbedtls_svc_key_id_is_null( key ) )
+            goto exit;
+
+        TEST_EQUAL( mbedtls_pk_setup_opaque( &pk, key ), 0 );
+
+        TEST_EQUAL( mbedtls_pk_get_type( &pk ), MBEDTLS_PK_OPAQUE );
+    }
+    else
+    {
+        TEST_EQUAL( mbedtls_pk_setup( &pk,
+                            mbedtls_pk_info_from_type( key_type ) ), 0 );
+        TEST_EQUAL( pk_genkey( &pk, parameter ), 0 );
+        TEST_EQUAL( mbedtls_pk_get_type( &pk ), key_type );
+    }
+
+    TEST_EQUAL( mbedtls_pk_can_do_ext( &pk, alg_check, usage_check ), result );
+
+exit:
+    psa_reset_key_attributes( &attributes );
+    PSA_ASSERT( psa_destroy_key( key ) );
+    mbedtls_pk_free( &pk );
+    USE_PSA_DONE( );
+}
+/* END_CASE */
 
 /* BEGIN_CASE */
 void valid_parameters( )
@@ -916,6 +967,72 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_USE_PSA_CRYPTO */
+void pk_wrap_rsa_decrypt_test_vec( data_t * cipher, int mod, int radix_P,
+                                   char * input_P, int radix_Q, char * input_Q,
+                                   int radix_N, char * input_N, int radix_E,
+                                   char * input_E, data_t * clear, int ret )
+{
+    unsigned char output[256];
+    mbedtls_test_rnd_pseudo_info rnd_info;
+    mbedtls_mpi N, P, Q, E;
+    mbedtls_rsa_context *rsa;
+    mbedtls_pk_context pk;
+    mbedtls_svc_key_id_t key_id;
+    size_t olen;
+
+    USE_PSA_INIT( );
+
+    mbedtls_pk_init( &pk );
+    mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P );
+    mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E );
+
+    memset( &rnd_info,  0, sizeof( mbedtls_test_rnd_pseudo_info ) );
+
+    /* init pk-rsa context */
+    TEST_EQUAL( mbedtls_pk_setup( &pk,
+                        mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ), 0 );
+    rsa = mbedtls_pk_rsa( pk );
+
+    /* load public key */
+    TEST_EQUAL( mbedtls_test_read_mpi( &N, radix_N, input_N ), 0 );
+    TEST_EQUAL( mbedtls_test_read_mpi( &E, radix_E, input_E ), 0 );
+
+    /* load private key */
+    TEST_EQUAL( mbedtls_test_read_mpi( &P, radix_P, input_P ), 0 );
+    TEST_EQUAL( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ), 0 );
+    TEST_EQUAL( mbedtls_rsa_import( rsa, &N, &P, &Q, NULL, &E ), 0 );
+    TEST_EQUAL( mbedtls_rsa_get_len( rsa ), (size_t) ( mod / 8 ) );
+    TEST_EQUAL( mbedtls_rsa_complete( rsa ), 0 );
+
+    /* Turn PK context into an opaque one. */
+    TEST_EQUAL( mbedtls_pk_wrap_as_opaque( &pk, &key_id,
+                                           PSA_ALG_RSA_PKCS1V15_CRYPT,
+                                           PSA_KEY_USAGE_DECRYPT,
+                                           PSA_ALG_NONE ), 0 );
+
+    /* decryption test */
+    memset( output, 0, sizeof( output ) );
+    olen = 0;
+    TEST_EQUAL( mbedtls_pk_decrypt( &pk, cipher->x, cipher->len,
+                            output, &olen, sizeof( output ),
+                            mbedtls_test_rnd_pseudo_rand, &rnd_info ), ret );
+    if( ret == 0 )
+    {
+        TEST_EQUAL( olen, clear->len );
+        TEST_EQUAL( memcmp( output, clear->x, olen ), 0 );
+    }
+
+    TEST_EQUAL( PSA_SUCCESS, psa_destroy_key( key_id ) );
+
+exit:
+    mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P );
+    mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &E );
+    mbedtls_pk_free( &pk );
+    USE_PSA_DONE( );
+}
+/* END_CASE */
+
 /* BEGIN_CASE */
 void pk_ec_nocrypt( int type )
 {
@@ -1011,7 +1128,7 @@
     memset( ciph, 0, sizeof ciph );
     memset( test, 0, sizeof test );
 
-    /* Initiliaze PK RSA context with random key */
+    /* Initialize PK RSA context with random key */
     TEST_ASSERT( mbedtls_pk_setup( &rsa,
                               mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == 0 );
     TEST_ASSERT( pk_genkey( &rsa, RSA_KEY_SIZE ) == 0 );
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 14343aa..7250753 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -2259,7 +2259,7 @@
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
 cipher_decrypt_fail:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee223":PSA_ERROR_INVALID_ARGUMENT
 
-PSA symetric decrypt: CCM*-no-tag, input too short (15 bytes)
+PSA symmetric decrypt: CCM*-no-tag, input too short (15 bytes)
 depends_on:PSA_WANT_ALG_CCM_STAR_NO_TAG:MBEDTLS_AES_C
 cipher_decrypt_fail:PSA_ALG_CCM_STAR_NO_TAG:PSA_KEY_TYPE_AES:"19ebfde2d5468ba0a3031bde629b11fd":"5a8aa485c316e9":"2a2a2a2a2a2a2a2a":PSA_ERROR_INVALID_ARGUMENT
 
@@ -2315,6 +2315,18 @@
 depends_on:PSA_WANT_ALG_CCM_STAR_NO_TAG:PSA_WANT_KEY_TYPE_AES
 cipher_decrypt:PSA_ALG_CCM_STAR_NO_TAG:PSA_KEY_TYPE_AES:"90929a4b0ac65b350ad1591611fe4829":"5a8aa485c316e9403aff859fbb":"4bfe4e35784f0a65b545477e5e2f4bae0e1e6fa717eaf2cb":"a16a2e741f1cd9717285b6d882c1fc53655e9773761ad697"
 
+PSA symmetric decrypt: ChaCha20, RFC7539 keystream
+depends_on:PSA_WANT_ALG_STREAM_CIPHER:PSA_WANT_KEY_TYPE_CHACHA20
+# Keystream from RFC 7539 §2.4.2, with an extra 64-byte output block prepended
+# because the test vector starts at counter=1 but our API starts at counter=0.
+cipher_decrypt:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f":"000000000000004a00000000":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":"af051e40bba0354981329a806a140eafd258a22a6dcb4bb9f6569cb3efe2deaf837bd87ca20b5ba12081a306af0eb35c41a239d20dfc74c81771560d9c9c1e4b224f51f3401bd9e12fde276fb8631ded8c131f823d2c06e27e4fcaec9ef3cf788a3b0aa372600a92b57974cded2b9334794cba40c63e34cdea212c4cf07d41b769a6749f3f630f4122cafe28ec4dc47e26d4346d70b98c73f3e9c53ac40c5945398b6eda1a832c89c167eacd901d7e2bf363"
+
+PSA symmetric decrypt: ChaCha20, RFC7539 sunscreen
+depends_on:PSA_WANT_ALG_STREAM_CIPHER:PSA_WANT_KEY_TYPE_CHACHA20
+# Test vector from RFC 7539 §2.4.2, with an extra 64-byte block prepended
+# because the test vector starts at counter=1 but our API starts at counter=0.
+cipher_decrypt:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f":"000000000000004a00000000":"fb6d7b60e9e67669b607a9b94a606bdca678d44f0ebf24cbd623efd69cc2bdc0f615ac19d0366a8d00e3d6728f5ee01d61d74ab77edc17a7621f2268eea12e656e2e359a2568f98041ba0728dd0d6981e97e7aec1d4360c20a27afccfd9fae0bf91b65c5524733ab8f593dabcd62b3571639d624e65152ab8f530c359f0861d807ca0dbf500d6a6156a38e088a22b65e52bc514d16ccf806818ce91ab77937365af90bbf74a35be6b40b8eedf2785e42874d":"546865205246432037353339207465737420766563746f72207573657320636f756e7465723d312c2062757420505341207573657320636f756e7465723d302e4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e"
+
 PSA symmetric decrypt multipart: AES-ECB, 0 bytes, good
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
 cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"":0:0:0:"":PSA_SUCCESS
@@ -2611,6 +2623,12 @@
 depends_on:PSA_WANT_ALG_STREAM_CIPHER:PSA_WANT_KEY_TYPE_CHACHA20
 cipher_encrypt_multipart:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"4bddc98c551a95395ef719557f813656b566bc45aac04eca3866324cc75489f2":"a170d9349d24955aa4501891":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":14:14:50:"9ba7d8de0c6b579fc436e368619e09228070d23246c836d6c6b4c476af6f5eb2b78fbe809d03f7881e6af28cfe3746e8dcf1eb7f762fe7d003141f1539a6cec4":PSA_SUCCESS
 
+PSA symmetric encryption multipart: ChaCha20, RFC7539 sunscreen
+depends_on:PSA_WANT_ALG_STREAM_CIPHER:PSA_WANT_KEY_TYPE_CHACHA20
+# Test vector from RFC 7539 §2.4.2, with an extra 64-byte block prepended
+# because the test vector starts at counter=1 but our API starts at counter=0.
+cipher_encrypt_multipart:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f":"000000000000004a00000000":"546865205246432037353339207465737420766563746f72207573657320636f756e7465723d312c2062757420505341207573657320636f756e7465723d302e4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":64:64:114:"fb6d7b60e9e67669b607a9b94a606bdca678d44f0ebf24cbd623efd69cc2bdc0f615ac19d0366a8d00e3d6728f5ee01d61d74ab77edc17a7621f2268eea12e656e2e359a2568f98041ba0728dd0d6981e97e7aec1d4360c20a27afccfd9fae0bf91b65c5524733ab8f593dabcd62b3571639d624e65152ab8f530c359f0861d807ca0dbf500d6a6156a38e088a22b65e52bc514d16ccf806818ce91ab77937365af90bbf74a35be6b40b8eedf2785e42874d":PSA_SUCCESS
+
 PSA symmetric decrypt multipart: ChaCha20, K=rand N=rand
 depends_on:PSA_WANT_ALG_STREAM_CIPHER:PSA_WANT_KEY_TYPE_CHACHA20
 cipher_decrypt_multipart:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"4bddc98c551a95395ef719557f813656b566bc45aac04eca3866324cc75489f2":"a170d9349d24955aa4501891":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":64:64:0:"9ba7d8de0c6b579fc436e368619e09228070d23246c836d6c6b4c476af6f5eb2b78fbe809d03f7881e6af28cfe3746e8dcf1eb7f762fe7d003141f1539a6cec4":PSA_SUCCESS
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 6cd6bee..0bfabb1 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -396,12 +396,12 @@
     if( is_encrypt )
     {
         final_output_size = PSA_AEAD_FINISH_OUTPUT_SIZE( key_type, alg );
-        TEST_ASSERT( final_output_size <= PSA_AEAD_FINISH_OUTPUT_MAX_SIZE );
+        TEST_LE_U( final_output_size, PSA_AEAD_FINISH_OUTPUT_MAX_SIZE );
     }
     else
     {
         final_output_size = PSA_AEAD_VERIFY_OUTPUT_SIZE( key_type, alg );
-        TEST_ASSERT( final_output_size <= PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE );
+        TEST_LE_U( final_output_size, PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE );
     }
 
     ASSERT_ALLOC( final_data, final_output_size );
@@ -557,18 +557,18 @@
         output_length += tag_length;
 
         TEST_EQUAL( output_length,
-                      PSA_AEAD_ENCRYPT_OUTPUT_SIZE( key_type, alg,
-                                                    input_data->len ) );
-        TEST_ASSERT( output_length <=
-                      PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE( input_data->len ) );
+                    PSA_AEAD_ENCRYPT_OUTPUT_SIZE( key_type, alg,
+                                                  input_data->len ) );
+        TEST_LE_U( output_length,
+                   PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE( input_data->len ) );
     }
     else
     {
        TEST_EQUAL( output_length,
                       PSA_AEAD_DECRYPT_OUTPUT_SIZE( key_type, alg,
                                                     input_data->len ) );
-       TEST_ASSERT( output_length <=
-                      PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE( input_data->len ) );
+       TEST_LE_U( output_length,
+                  PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE( input_data->len ) );
     }
 
 
@@ -721,7 +721,7 @@
     /* Check that the length for a truncated MAC always fits in the algorithm
      * encoding. The shifted mask is the maximum truncated value. The
      * untruncated algorithm may be one byte larger. */
-    TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
+    TEST_LE_U( PSA_MAC_MAX_SIZE, 1 + max_truncated_mac_size );
 }
 /* END_CASE */
 
@@ -834,7 +834,7 @@
     size_t n;
 
     /* Skip the test case if the target running the test cannot
-     * accomodate large keys due to heap size constraints */
+     * accommodate large keys due to heap size constraints */
     ASSERT_ALLOC_WEAK( buffer, buffer_size );
     memset( buffer, 'K', byte_size );
 
@@ -965,7 +965,7 @@
      * and export_size. On errors, the exported length must be 0. */
     TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
     TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
-    TEST_ASSERT( exported_length <= export_size );
+    TEST_LE_U( exported_length, export_size );
 
     TEST_ASSERT( mem_is_char( exported + exported_length, 0,
                               export_size - exported_length ) );
@@ -1000,10 +1000,10 @@
                          reexported, reexported_length );
         PSA_ASSERT( psa_destroy_key( key2 ) );
     }
-    TEST_ASSERT( exported_length <=
+    TEST_LE_U( exported_length,
              PSA_EXPORT_KEY_OUTPUT_SIZE( type,
                                          psa_get_key_bits( &got_attributes ) ) );
-    TEST_ASSERT( exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE );
+    TEST_LE_U( exported_length, PSA_EXPORT_KEY_PAIR_MAX_SIZE );
 
 destroy:
     /* Destroy the key */
@@ -1065,12 +1065,12 @@
         size_t bits;
         PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
         bits = psa_get_key_bits( &attributes );
-        TEST_ASSERT( expected_public_key->len <=
-                     PSA_EXPORT_KEY_OUTPUT_SIZE( public_type, bits ) );
-        TEST_ASSERT( expected_public_key->len <=
-                     PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE( public_type, bits ) );
-        TEST_ASSERT( expected_public_key->len <=
-                     PSA_EXPORT_PUBLIC_KEY_MAX_SIZE );
+        TEST_LE_U( expected_public_key->len,
+                   PSA_EXPORT_KEY_OUTPUT_SIZE( public_type, bits ) );
+        TEST_LE_U( expected_public_key->len,
+                   PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE( public_type, bits ) );
+        TEST_LE_U( expected_public_key->len,
+                   PSA_EXPORT_PUBLIC_KEY_MAX_SIZE );
         ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
                         exported, exported_length );
     }
@@ -1198,7 +1198,7 @@
     /* Test each valid way of initializing the object, except for `= {0}`, as
      * Clang 5 complains when `-Wmissing-field-initializers` is used, even
      * though it's OK by the C standard. We could test for this, but we'd need
-     * to supress the Clang warning for the test. */
+     * to suppress the Clang warning for the test. */
     psa_key_attributes_t func = psa_key_attributes_init( );
     psa_key_attributes_t init = PSA_KEY_ATTRIBUTES_INIT;
     psa_key_attributes_t zero;
@@ -1441,8 +1441,8 @@
     size_t tag_length = tag_length_arg;
     size_t output_length;
 
-    TEST_ASSERT( nonce_length <= sizeof( nonce ) );
-    TEST_ASSERT( tag_length <= sizeof( tag ) );
+    TEST_LE_U( nonce_length, sizeof( nonce ) );
+    TEST_LE_U( tag_length, sizeof( tag ) );
 
     PSA_ASSERT( psa_crypto_init( ) );
 
@@ -1989,7 +1989,7 @@
     /* Test each valid way of initializing the object, except for `= {0}`, as
      * Clang 5 complains when `-Wmissing-field-initializers` is used, even
      * though it's OK by the C standard. We could test for this, but we'd need
-     * to supress the Clang warning for the test. */
+     * to suppress the Clang warning for the test. */
     psa_hash_operation_t func = psa_hash_operation_init( );
     psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
     psa_hash_operation_t zero;
@@ -2077,7 +2077,7 @@
     status = psa_hash_compute( alg, input->x, input->len,
                                output, output_size, &output_length );
     TEST_EQUAL( status, expected_status );
-    TEST_ASSERT( output_length <= output_size );
+    TEST_LE_U( output_length, output_size );
 
     /* Hash Compute, multi-part */
     status = psa_hash_setup( &operation, alg );
@@ -2089,7 +2089,7 @@
             status = psa_hash_finish( &operation, output, output_size,
                                       &output_length );
             if( status == PSA_SUCCESS )
-                TEST_ASSERT( output_length <= output_size );
+                TEST_LE_U( output_length, output_size );
             else
                 TEST_EQUAL( status, expected_status );
         }
@@ -2518,7 +2518,7 @@
     /* Test each valid way of initializing the object, except for `= {0}`, as
      * Clang 5 complains when `-Wmissing-field-initializers` is used, even
      * though it's OK by the C standard. We could test for this, but we'd need
-     * to supress the Clang warning for the test. */
+     * to suppress the Clang warning for the test. */
     psa_mac_operation_t func = psa_mac_operation_init( );
     psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
     psa_mac_operation_t zero;
@@ -2769,7 +2769,7 @@
         expected_mac->len + 1,
     };
 
-    TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
+    TEST_LE_U( mac_buffer_size, PSA_MAC_MAX_SIZE );
     /* We expect PSA_MAC_LENGTH to be exact. */
     TEST_ASSERT( expected_mac->len == mac_buffer_size );
 
@@ -2847,7 +2847,7 @@
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     uint8_t *perturbed_mac = NULL;
 
-    TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
+    TEST_LE_U( expected_mac->len, PSA_MAC_MAX_SIZE );
 
     PSA_ASSERT( psa_crypto_init( ) );
 
@@ -2941,7 +2941,7 @@
     /* Test each valid way of initializing the object, except for `= {0}`, as
      * Clang 5 complains when `-Wmissing-field-initializers` is used, even
      * though it's OK by the C standard. We could test for this, but we'd need
-     * to supress the Clang warning for the test. */
+     * to suppress the Clang warning for the test. */
     psa_cipher_operation_t func = psa_cipher_operation_init( );
     psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
     psa_cipher_operation_t zero;
@@ -3320,14 +3320,14 @@
     PSA_ASSERT( psa_crypto_init( ) );
 
     /* Validate size macros */
-    TEST_ASSERT( ciphertext->len <=
-                 PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, plaintext->len ) );
-    TEST_ASSERT( PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, plaintext->len ) <=
+    TEST_LE_U( ciphertext->len,
+               PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, plaintext->len ) );
+    TEST_LE_U( PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, plaintext->len ),
                  PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE( plaintext->len ) );
-    TEST_ASSERT( plaintext->len <=
-                 PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, ciphertext->len ) );
-    TEST_ASSERT( PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, ciphertext->len ) <=
-                 PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE( ciphertext->len ) );
+    TEST_LE_U( plaintext->len,
+               PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, ciphertext->len ) );
+    TEST_LE_U( PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, ciphertext->len ),
+               PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE( ciphertext->len ) );
 
 
     /* Set up key and output buffer */
@@ -3367,7 +3367,7 @@
                                    plaintext->x, plaintext->len,
                                    output, output_buffer_size,
                                    &length ) );
-    TEST_ASSERT( length <= output_buffer_size );
+    TEST_LE_U( length, output_buffer_size );
     output_length += length;
     PSA_ASSERT( psa_cipher_finish( &operation,
                                    output + output_length,
@@ -3385,7 +3385,7 @@
                                    ciphertext->x, ciphertext->len,
                                    output, output_buffer_size,
                                    &length ) );
-    TEST_ASSERT( length <= output_buffer_size );
+    TEST_LE_U( length, output_buffer_size );
     output_length += length;
     PSA_ASSERT( psa_cipher_finish( &operation,
                                    output + output_length,
@@ -3499,10 +3499,10 @@
        the output is not possible. Validating with multipart encryption. */
     PSA_ASSERT( psa_cipher_encrypt( key, alg, input->x, input->len, output1,
                                     output1_buffer_size, &output1_length ) );
-    TEST_ASSERT( output1_length <=
-                 PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, input->len ) );
-    TEST_ASSERT( output1_length <=
-                 PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE( input->len ) );
+    TEST_LE_U( output1_length,
+               PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, input->len ) );
+    TEST_LE_U( output1_length,
+               PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE( input->len ) );
 
     PSA_ASSERT( psa_cipher_encrypt_setup( &operation, key, alg ) );
     PSA_ASSERT( psa_cipher_set_iv( &operation, output1, iv_size ) );
@@ -3511,20 +3511,20 @@
                                    input->x, input->len,
                                    output2, output2_buffer_size,
                                    &function_output_length ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, input->len ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len ) );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, input->len ) );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len ) );
     output2_length += function_output_length;
 
     PSA_ASSERT( psa_cipher_finish( &operation,
                                    output2 + output2_length,
                                    output2_buffer_size - output2_length,
                                    &function_output_length ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE );
     output2_length += function_output_length;
 
     PSA_ASSERT( psa_cipher_abort( &operation ) );
@@ -3584,15 +3584,15 @@
                          PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg );
     ASSERT_ALLOC( output, output_buffer_size );
 
-    TEST_ASSERT( first_part_size <= input->len );
+    TEST_LE_U( first_part_size, input->len );
     PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
                                    output, output_buffer_size,
                                    &function_output_length ) );
     TEST_ASSERT( function_output_length == output1_length );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, first_part_size ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( first_part_size) );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, first_part_size ) );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( first_part_size) );
     total_output_length += function_output_length;
 
     if( first_part_size < input->len )
@@ -3605,12 +3605,12 @@
                                        output_buffer_size - total_output_length,
                                        &function_output_length ) );
         TEST_ASSERT( function_output_length == output2_length );
-        TEST_ASSERT( function_output_length <=
-                     PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type,
-                                                    alg,
-                                                    input->len - first_part_size ) );
-        TEST_ASSERT( function_output_length <=
-                     PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len ) );
+        TEST_LE_U( function_output_length,
+                   PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type,
+                                                  alg,
+                                                  input->len - first_part_size ) );
+        TEST_LE_U( function_output_length,
+                   PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len ) );
         total_output_length += function_output_length;
     }
 
@@ -3619,10 +3619,10 @@
                                   output + total_output_length ),
                                 output_buffer_size - total_output_length,
                                 &function_output_length );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE );
     total_output_length += function_output_length;
     TEST_EQUAL( status, expected_status );
 
@@ -3686,16 +3686,16 @@
                          PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg );
     ASSERT_ALLOC( output, output_buffer_size );
 
-    TEST_ASSERT( first_part_size <= input->len );
+    TEST_LE_U( first_part_size, input->len );
     PSA_ASSERT( psa_cipher_update( &operation,
                                    input->x, first_part_size,
                                    output, output_buffer_size,
                                    &function_output_length ) );
     TEST_ASSERT( function_output_length == output1_length );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, first_part_size ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( first_part_size ) );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, first_part_size ) );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( first_part_size ) );
     total_output_length += function_output_length;
 
     if( first_part_size < input->len )
@@ -3708,12 +3708,12 @@
                                        output_buffer_size - total_output_length,
                                        &function_output_length ) );
         TEST_ASSERT( function_output_length == output2_length );
-        TEST_ASSERT( function_output_length <=
-                     PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type,
-                                                    alg,
-                                                    input->len - first_part_size ) );
-        TEST_ASSERT( function_output_length <=
-                     PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len ) );
+        TEST_LE_U( function_output_length,
+                   PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type,
+                                                  alg,
+                                                  input->len - first_part_size ) );
+        TEST_LE_U( function_output_length,
+                   PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len ) );
         total_output_length += function_output_length;
     }
 
@@ -3722,10 +3722,10 @@
                                   output + total_output_length ),
                                 output_buffer_size - total_output_length,
                                 &function_output_length );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE );
     total_output_length += function_output_length;
     TEST_EQUAL( status, expected_status );
 
@@ -3897,10 +3897,10 @@
 
     PSA_ASSERT( psa_cipher_decrypt( key, alg, input, input_buffer_size, output,
                                     output_buffer_size, &output_length ) );
-    TEST_ASSERT( output_length <=
-                 PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, input_buffer_size ) );
-    TEST_ASSERT( output_length <=
-                 PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE( input_buffer_size ) );
+    TEST_LE_U( output_length,
+               PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, input_buffer_size ) );
+    TEST_LE_U( output_length,
+               PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE( input_buffer_size ) );
 
     ASSERT_COMPARE( expected_output->x, expected_output->len,
                     output, output_length );
@@ -3943,10 +3943,10 @@
     PSA_ASSERT( psa_cipher_encrypt( key, alg, input->x, input->len,
                                     output1, output1_size,
                                     &output1_length ) );
-    TEST_ASSERT( output1_length <=
-                 PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, input->len ) );
-    TEST_ASSERT( output1_length <=
-                 PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE( input->len ) );
+    TEST_LE_U( output1_length,
+               PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, input->len ) );
+    TEST_LE_U( output1_length,
+               PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE( input->len ) );
 
     output2_size = output1_length;
     ASSERT_ALLOC( output2, output2_size );
@@ -3954,10 +3954,10 @@
     PSA_ASSERT( psa_cipher_decrypt( key, alg, output1, output1_length,
                                     output2, output2_size,
                                     &output2_length ) );
-    TEST_ASSERT( output2_length <=
-                 PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, output1_length ) );
-    TEST_ASSERT( output2_length <=
-                 PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE( output1_length ) );
+    TEST_LE_U( output2_length,
+               PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, output1_length ) );
+    TEST_LE_U( output2_length,
+               PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE( output1_length ) );
 
     ASSERT_COMPARE( input->x, input->len, output2, output2_length );
 
@@ -4014,19 +4014,19 @@
     }
 
     output1_buffer_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, input->len );
-    TEST_ASSERT( output1_buffer_size <=
-                 PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE( input->len ) );
+    TEST_LE_U( output1_buffer_size,
+               PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE( input->len ) );
     ASSERT_ALLOC( output1, output1_buffer_size );
 
-    TEST_ASSERT( first_part_size <= input->len );
+    TEST_LE_U( first_part_size, input->len );
 
     PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
                                    output1, output1_buffer_size,
                                    &function_output_length ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, first_part_size ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( first_part_size ) );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, first_part_size ) );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( first_part_size ) );
     output1_length += function_output_length;
 
     PSA_ASSERT( psa_cipher_update( &operation1,
@@ -4034,31 +4034,31 @@
                                    input->len - first_part_size,
                                    output1, output1_buffer_size,
                                    &function_output_length ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type,
-                                                alg,
-                                                input->len - first_part_size ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len - first_part_size ) );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type,
+                                              alg,
+                                              input->len - first_part_size ) );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len - first_part_size ) );
     output1_length += function_output_length;
 
     PSA_ASSERT( psa_cipher_finish( &operation1,
                                    output1 + output1_length,
                                    output1_buffer_size - output1_length,
                                    &function_output_length ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE );
     output1_length += function_output_length;
 
     PSA_ASSERT( psa_cipher_abort( &operation1 ) );
 
     output2_buffer_size = output1_length;
-    TEST_ASSERT( output2_buffer_size <=
-                 PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, output1_length ) );
-    TEST_ASSERT( output2_buffer_size <=
-                 PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE( output1_length ) );
+    TEST_LE_U( output2_buffer_size,
+               PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, output1_length ) );
+    TEST_LE_U( output2_buffer_size,
+               PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE( output1_length ) );
     ASSERT_ALLOC( output2, output2_buffer_size );
 
     if( iv_length > 0 )
@@ -4070,10 +4070,10 @@
     PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
                                    output2, output2_buffer_size,
                                    &function_output_length ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, first_part_size ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( first_part_size ) );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, first_part_size ) );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( first_part_size ) );
     output2_length += function_output_length;
 
     PSA_ASSERT( psa_cipher_update( &operation2,
@@ -4081,22 +4081,22 @@
                                    output1_length - first_part_size,
                                    output2, output2_buffer_size,
                                    &function_output_length ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type,
-                                                alg,
-                                                output1_length - first_part_size ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( output1_length - first_part_size ) );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type,
+                                              alg,
+                                              output1_length - first_part_size ) );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( output1_length - first_part_size ) );
     output2_length += function_output_length;
 
     PSA_ASSERT( psa_cipher_finish( &operation2,
                                    output2 + output2_length,
                                    output2_buffer_size - output2_length,
                                    &function_output_length ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) );
+    TEST_LE_U( function_output_length,
+               PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE );
     output2_length += function_output_length;
 
     PSA_ASSERT( psa_cipher_abort( &operation2 ) );
@@ -4154,8 +4154,8 @@
     {
         TEST_EQUAL( output_size,
                     PSA_AEAD_ENCRYPT_OUTPUT_SIZE( key_type, alg, input_data->len ) );
-        TEST_ASSERT( output_size <=
-                     PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE( input_data->len ) );
+        TEST_LE_U( output_size,
+                   PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE( input_data->len ) );
     }
     ASSERT_ALLOC( output_data, output_size );
 
@@ -4187,8 +4187,8 @@
         TEST_EQUAL( input_data->len,
                     PSA_AEAD_DECRYPT_OUTPUT_SIZE( key_type, alg, output_length ) );
 
-        TEST_ASSERT( input_data->len <=
-                     PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE( output_length ) );
+        TEST_LE_U( input_data->len,
+                   PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE( output_length ) );
 
         TEST_EQUAL( psa_aead_decrypt( key, alg,
                                       nonce->x, nonce->len,
@@ -4246,8 +4246,8 @@
      * should be exact. */
     TEST_EQUAL( output_size,
                 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( key_type, alg, input_data->len ) );
-    TEST_ASSERT( output_size <=
-                 PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE( input_data->len ) );
+    TEST_LE_U( output_size,
+               PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE( input_data->len ) );
     ASSERT_ALLOC( output_data, output_size );
 
     status = psa_aead_encrypt( key, alg,
@@ -4317,8 +4317,8 @@
          * should be exact. */
         TEST_EQUAL( output_size,
                     PSA_AEAD_DECRYPT_OUTPUT_SIZE( key_type, alg, input_data->len ) );
-        TEST_ASSERT( output_size <=
-                     PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE( input_data->len ) );
+        TEST_LE_U( output_size,
+                   PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE( input_data->len ) );
     }
     ASSERT_ALLOC( output_data, output_size );
 
@@ -4579,7 +4579,7 @@
 
     ciphertext_size = PSA_AEAD_FINISH_OUTPUT_SIZE( key_type, alg );
 
-    TEST_ASSERT( ciphertext_size <= PSA_AEAD_FINISH_OUTPUT_MAX_SIZE );
+    TEST_LE_U( ciphertext_size, PSA_AEAD_FINISH_OUTPUT_MAX_SIZE );
 
     ASSERT_ALLOC( ciphertext, ciphertext_size );
 
@@ -4608,7 +4608,7 @@
         TEST_EQUAL( actual_nonce_length, PSA_AEAD_NONCE_LENGTH( key_type,
                                                                 alg ) );
 
-    TEST_ASSERT( actual_nonce_length <= PSA_AEAD_NONCE_MAX_SIZE );
+    TEST_LE_U( actual_nonce_length, PSA_AEAD_NONCE_MAX_SIZE );
 
     if( expected_status == PSA_SUCCESS )
     {
@@ -4683,7 +4683,7 @@
 
     ciphertext_size = PSA_AEAD_FINISH_OUTPUT_SIZE( key_type, alg );
 
-    TEST_ASSERT( ciphertext_size <= PSA_AEAD_FINISH_OUTPUT_MAX_SIZE );
+    TEST_LE_U( ciphertext_size, PSA_AEAD_FINISH_OUTPUT_MAX_SIZE );
 
     ASSERT_ALLOC( ciphertext, ciphertext_size );
 
@@ -5121,7 +5121,7 @@
 
     tag_length = PSA_AEAD_TAG_LENGTH( key_type, key_bits, alg );
 
-    TEST_ASSERT( tag_length <= PSA_AEAD_TAG_MAX_SIZE );
+    TEST_LE_U( tag_length, PSA_AEAD_TAG_MAX_SIZE );
 
     output_size = PSA_AEAD_UPDATE_OUTPUT_SIZE( key_type, alg, input_data->len );
 
@@ -5129,7 +5129,7 @@
 
     finish_output_size = PSA_AEAD_FINISH_OUTPUT_SIZE( key_type, alg );
 
-    TEST_ASSERT( finish_output_size <= PSA_AEAD_FINISH_OUTPUT_MAX_SIZE );
+    TEST_LE_U( finish_output_size, PSA_AEAD_FINISH_OUTPUT_MAX_SIZE );
 
     ASSERT_ALLOC( final_data, finish_output_size );
 
@@ -5964,12 +5964,12 @@
     PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
     key_bits = psa_get_key_bits( &attributes );
 
-    /* Allocate a buffer which has the size advertized by the
+    /* Allocate a buffer which has the size advertised by the
      * library. */
     signature_size = PSA_SIGN_OUTPUT_SIZE( key_type,
                                                       key_bits, alg );
     TEST_ASSERT( signature_size != 0 );
-    TEST_ASSERT( signature_size <= PSA_SIGNATURE_MAX_SIZE );
+    TEST_LE_U( signature_size, PSA_SIGNATURE_MAX_SIZE );
     ASSERT_ALLOC( signature, signature_size );
 
     /* Perform the signature. */
@@ -6029,7 +6029,7 @@
      * whatever it is, it should be less than signature_size, so that
      * if the caller tries to read *signature_length bytes without
      * checking the error code then they don't overflow a buffer. */
-    TEST_ASSERT( signature_length <= signature_size );
+    TEST_LE_U( signature_length, signature_size );
 
 exit:
     psa_reset_key_attributes( &attributes );
@@ -6063,12 +6063,12 @@
     PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
     key_bits = psa_get_key_bits( &attributes );
 
-    /* Allocate a buffer which has the size advertized by the
+    /* Allocate a buffer which has the size advertised by the
      * library. */
     signature_size = PSA_SIGN_OUTPUT_SIZE( key_type,
                                                       key_bits, alg );
     TEST_ASSERT( signature_size != 0 );
-    TEST_ASSERT( signature_size <= PSA_SIGNATURE_MAX_SIZE );
+    TEST_LE_U( signature_size, PSA_SIGNATURE_MAX_SIZE );
     ASSERT_ALLOC( signature, signature_size );
 
     /* Perform the signature. */
@@ -6077,7 +6077,7 @@
                                signature, signature_size,
                                &signature_length ) );
     /* Check that the signature length looks sensible. */
-    TEST_ASSERT( signature_length <= signature_size );
+    TEST_LE_U( signature_length, signature_size );
     TEST_ASSERT( signature_length > 0 );
 
     /* Use the library to verify that the signature is correct. */
@@ -6120,7 +6120,7 @@
     psa_algorithm_t alg = alg_arg;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 
-    TEST_ASSERT( signature_data->len <= PSA_SIGNATURE_MAX_SIZE );
+    TEST_LE_U( signature_data->len, PSA_SIGNATURE_MAX_SIZE );
 
     PSA_ASSERT( psa_crypto_init( ) );
 
@@ -6205,7 +6205,7 @@
 
     signature_size = PSA_SIGN_OUTPUT_SIZE( key_type, key_bits, alg );
     TEST_ASSERT( signature_size != 0 );
-    TEST_ASSERT( signature_size <= PSA_SIGNATURE_MAX_SIZE );
+    TEST_LE_U( signature_size, PSA_SIGNATURE_MAX_SIZE );
     ASSERT_ALLOC( signature, signature_size );
 
     PSA_ASSERT( psa_sign_message( key, alg,
@@ -6264,7 +6264,7 @@
      * whatever it is, it should be less than signature_size, so that
      * if the caller tries to read *signature_length bytes without
      * checking the error code then they don't overflow a buffer. */
-    TEST_ASSERT( signature_length <= signature_size );
+    TEST_LE_U( signature_length, signature_size );
 
 exit:
     psa_reset_key_attributes( &attributes );
@@ -6303,14 +6303,14 @@
 
     signature_size = PSA_SIGN_OUTPUT_SIZE( key_type, key_bits, alg );
     TEST_ASSERT( signature_size != 0 );
-    TEST_ASSERT( signature_size <= PSA_SIGNATURE_MAX_SIZE );
+    TEST_LE_U( signature_size, PSA_SIGNATURE_MAX_SIZE );
     ASSERT_ALLOC( signature, signature_size );
 
     PSA_ASSERT( psa_sign_message( key, alg,
                                   input_data->x, input_data->len,
                                   signature, signature_size,
                                   &signature_length ) );
-    TEST_ASSERT( signature_length <= signature_size );
+    TEST_LE_U( signature_length, signature_size );
     TEST_ASSERT( signature_length > 0 );
 
     PSA_ASSERT( psa_verify_message( key, alg,
@@ -6350,7 +6350,7 @@
     psa_algorithm_t alg = alg_arg;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 
-    TEST_ASSERT( signature_data->len <= PSA_SIGNATURE_MAX_SIZE );
+    TEST_LE_U( signature_data->len, PSA_SIGNATURE_MAX_SIZE );
 
     PSA_ASSERT( psa_crypto_init( ) );
 
@@ -6444,7 +6444,7 @@
     key_bits = psa_get_key_bits( &attributes );
 
     output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
-    TEST_ASSERT( output_size <= PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE );
+    TEST_LE_U( output_size, PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE );
     ASSERT_ALLOC( output, output_size );
 
     /* Encrypt the input */
@@ -6518,13 +6518,13 @@
     key_bits = psa_get_key_bits( &attributes );
 
     output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
-    TEST_ASSERT( output_size <= PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE );
+    TEST_LE_U( output_size, PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE );
     ASSERT_ALLOC( output, output_size );
 
     output2_size = input_data->len;
-    TEST_ASSERT( output2_size <=
-                 PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE( key_type, key_bits, alg ) );
-    TEST_ASSERT( output2_size <= PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE );
+    TEST_LE_U( output2_size,
+               PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE( key_type, key_bits, alg ) );
+    TEST_LE_U( output2_size, PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE );
     ASSERT_ALLOC( output2, output2_size );
 
     /* We test encryption by checking that encrypt-then-decrypt gives back
@@ -6537,7 +6537,7 @@
                                         &output_length ) );
     /* We don't know what ciphertext length to expect, but check that
      * it looks sensible. */
-    TEST_ASSERT( output_length <= output_size );
+    TEST_LE_U( output_length, output_size );
 
     PSA_ASSERT( psa_asymmetric_decrypt( key, alg,
                                         output, output_length,
@@ -6592,7 +6592,7 @@
 
     /* Determine the maximum ciphertext length */
     output_size = PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
-    TEST_ASSERT( output_size <= PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE );
+    TEST_LE_U( output_size, PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE );
     ASSERT_ALLOC( output, output_size );
 
     PSA_ASSERT( psa_asymmetric_decrypt( key, alg,
@@ -6665,7 +6665,7 @@
                                             output, output_size,
                                             &output_length );
     TEST_EQUAL( actual_status, expected_status );
-    TEST_ASSERT( output_length <= output_size );
+    TEST_LE_U( output_length, output_size );
 
     /* If the label is empty, the test framework puts a non-null pointer
      * in label->x. Test that a null pointer works as well. */
@@ -6680,7 +6680,7 @@
                                                 output, output_size,
                                                 &output_length );
         TEST_EQUAL( actual_status, expected_status );
-        TEST_ASSERT( output_length <= output_size );
+        TEST_LE_U( output_length, output_size );
     }
 
 exit:
@@ -6697,7 +6697,7 @@
     /* Test each valid way of initializing the object, except for `= {0}`, as
      * Clang 5 complains when `-Wmissing-field-initializers` is used, even
      * though it's OK by the C standard. We could test for this, but we'd need
-     * to supress the Clang warning for the test. */
+     * to suppress the Clang warning for the test. */
     size_t capacity;
     psa_key_derivation_operation_t func = psa_key_derivation_operation_init( );
     psa_key_derivation_operation_t init = PSA_KEY_DERIVATION_OPERATION_INIT;
@@ -7021,8 +7021,8 @@
                         if( PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
                         {
                             PSA_ASSERT( psa_get_key_attributes( keys[i], &attributes1 ) );
-                            TEST_ASSERT( PSA_BITS_TO_BYTES( psa_get_key_bits( &attributes1 ) ) <=
-                                        PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE );
+                            TEST_LE_U( PSA_BITS_TO_BYTES( psa_get_key_bits( &attributes1 ) ),
+                                       PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE );
                         }
 
                         PSA_ASSERT( psa_key_derivation_input_key( &operation,
@@ -7550,7 +7550,6 @@
     size_t output_length = ~0;
     size_t key_bits;
 
-    ASSERT_ALLOC( output, expected_output->len );
     PSA_ASSERT( psa_crypto_init( ) );
 
     psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
@@ -7563,16 +7562,47 @@
     PSA_ASSERT( psa_get_key_attributes( our_key, &attributes ) );
     key_bits = psa_get_key_bits( &attributes );
 
+    /* Validate size macros */
+    TEST_LE_U( expected_output->len,
+               PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE( our_key_type, key_bits ) );
+    TEST_LE_U( PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE( our_key_type, key_bits ),
+               PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE );
+
+    /* Good case with exact output size */
+    ASSERT_ALLOC( output, expected_output->len );
     PSA_ASSERT( psa_raw_key_agreement( alg, our_key,
                                        peer_key_data->x, peer_key_data->len,
                                        output, expected_output->len,
                                        &output_length ) );
     ASSERT_COMPARE( output, output_length,
                     expected_output->x, expected_output->len );
-    TEST_ASSERT( output_length <=
-                 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE( our_key_type, key_bits ) );
-    TEST_ASSERT( output_length <=
-                 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE );
+    mbedtls_free( output );
+    output = NULL;
+    output_length = ~0;
+
+    /* Larger buffer */
+    ASSERT_ALLOC( output, expected_output->len + 1 );
+    PSA_ASSERT( psa_raw_key_agreement( alg, our_key,
+                                       peer_key_data->x, peer_key_data->len,
+                                       output, expected_output->len + 1,
+                                       &output_length ) );
+    ASSERT_COMPARE( output, output_length,
+                    expected_output->x, expected_output->len );
+    mbedtls_free( output );
+    output = NULL;
+    output_length = ~0;
+
+    /* Buffer too small */
+    ASSERT_ALLOC( output, expected_output->len - 1 );
+    TEST_EQUAL( psa_raw_key_agreement( alg, our_key,
+                                       peer_key_data->x, peer_key_data->len,
+                                       output, expected_output->len - 1,
+                                       &output_length ),
+                PSA_ERROR_BUFFER_TOO_SMALL );
+    /* Not required by the spec, but good robustness */
+    TEST_LE_U( output_length, expected_output->len - 1 );
+    mbedtls_free( output );
+    output = NULL;
 
 exit:
     mbedtls_free( output );
@@ -7617,7 +7647,7 @@
                                                     NULL, 0 ) );
     }
 
-    /* Test the advertized capacity. */
+    /* Test the advertised capacity. */
     PSA_ASSERT( psa_key_derivation_get_capacity(
                     &operation, &actual_capacity ) );
     TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function
index a5ea840..128352b 100644
--- a/tests/suites/test_suite_psa_crypto_driver_wrappers.function
+++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.function
@@ -995,7 +995,7 @@
     /*
      * Test encrypt failure
      * First test that if we don't force a driver error, encryption is
-     * successfull, then force driver error.
+     * successful, then force driver error.
      */
     status = psa_cipher_encrypt(
         key, alg, input->x, input->len,
diff --git a/tests/suites/test_suite_psa_crypto_entropy.data b/tests/suites/test_suite_psa_crypto_entropy.data
index 49d3f69..322363d 100644
--- a/tests/suites/test_suite_psa_crypto_entropy.data
+++ b/tests/suites/test_suite_psa_crypto_entropy.data
@@ -7,7 +7,7 @@
 # randomization for (e.g.) blinding. An external implementation could use
 # its own randomness source which is not affected by the forced failure of
 # the RNG driver.
-# Key types and non-randomized auxilary algorithms (in practice, hashes) can
+# Key types and non-randomized auxiliary algorithms (in practice, hashes) can
 # use an external implementation.
 PSA external RNG failure: randomized ECDSA
 depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PSA_BUILTIN_ALG_ECDSA:PSA_WANT_ECC_SECP_R1_256
diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal.function b/tests/suites/test_suite_psa_crypto_se_driver_hal.function
index 79d658f..9f68491 100644
--- a/tests/suites/test_suite_psa_crypto_se_driver_hal.function
+++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.function
@@ -170,6 +170,7 @@
 }
 
 /* Null import: do nothing, but pretend it worked. */
+#if defined(AT_LEAST_ONE_BUILTIN_KDF)
 static psa_status_t null_import( psa_drv_se_context_t *context,
                                  psa_key_slot_number_t slot_number,
                                  const psa_key_attributes_t *attributes,
@@ -186,8 +187,10 @@
     *bits = PSA_BYTES_TO_BITS( data_length );
     return( PSA_SUCCESS );
 }
+#endif /* AT_LEAST_ONE_BUILTIN_KDF */
 
 /* Null generate: do nothing, but pretend it worked. */
+#if defined(AT_LEAST_ONE_BUILTIN_KDF)
 static psa_status_t null_generate( psa_drv_se_context_t *context,
                                    psa_key_slot_number_t slot_number,
                                    const psa_key_attributes_t *attributes,
@@ -208,6 +211,7 @@
 
     return( PSA_SUCCESS );
 }
+#endif /* AT_LEAST_ONE_BUILTIN_KDF */
 
 /* Null destroy: do nothing, but pretend it worked. */
 static psa_status_t null_destroy( psa_drv_se_context_t *context,
@@ -635,6 +639,7 @@
 /* Check that a function's return status is "smoke-free", i.e. that
  * it's an acceptable error code when calling an API function that operates
  * on a key with potentially bogus parameters. */
+#if defined(AT_LEAST_ONE_BUILTIN_KDF)
 static int is_status_smoke_free( psa_status_t status )
 {
     switch( status )
@@ -651,6 +656,8 @@
             return( 0 );
     }
 }
+#endif /* AT_LEAST_ONE_BUILTIN_KDF */
+
 #define SMOKE_ASSERT( expr )                    \
     TEST_ASSERT( is_status_smoke_free( expr ) )
 
@@ -658,6 +665,7 @@
  * mostly bogus parameters: the goal is to ensure that there is no memory
  * corruption or crash. This test function is most useful when run under
  * an environment with sanity checks such as ASan or MSan. */
+#if defined(AT_LEAST_ONE_BUILTIN_KDF)
 static int smoke_test_key( mbedtls_svc_key_id_t key )
 {
     int ok = 0;
@@ -766,6 +774,7 @@
 
     return( ok );
 }
+#endif /* AT_LEAST_ONE_BUILTIN_KDF */
 
 static void psa_purge_storage( void )
 {
@@ -1073,7 +1082,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:AT_LEAST_ONE_BUILTIN_KDF */
 void import_key_smoke( int type_arg, int alg_arg,
                        data_t *key_material )
 {
@@ -1186,7 +1195,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:AT_LEAST_ONE_BUILTIN_KDF */
 void generate_key_smoke( int type_arg, int bits_arg, int alg_arg )
 {
     psa_key_type_t type = type_arg;
diff --git a/tests/suites/test_suite_psa_crypto_slot_management.function b/tests/suites/test_suite_psa_crypto_slot_management.function
index aa3ce28..d577663 100644
--- a/tests/suites/test_suite_psa_crypto_slot_management.function
+++ b/tests/suites/test_suite_psa_crypto_slot_management.function
@@ -325,7 +325,7 @@
         case INVALIDATE_BY_DESTROYING:
         case INVALIDATE_BY_DESTROYING_WITH_SHUTDOWN:
             /*
-             * Test that the key handle and identifier are now not refering to an
+             * Test that the key handle and identifier are now not referring to an
              * existing key.
              */
             TEST_EQUAL( psa_get_key_attributes( handle, &read_attributes ),
diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data
index 848a497..274f0de 100644
--- a/tests/suites/test_suite_ssl.data
+++ b/tests/suites/test_suite_ssl.data
@@ -10,7 +10,7 @@
 Attempt to register multiple PSKs, incl. opaque PSK, #2
 test_multiple_psks_opaque:2
 
-Test calback buffer sanity
+Test callback buffer sanity
 test_callback_buffer_sanity:
 
 Callback buffer test: Exercise simple write/read
@@ -624,7 +624,7 @@
 SSL DTLS replay: delayed
 ssl_dtls_replay:"abcd12340000abcd12340001abcd12340003":"abcd12340002":0
 
-SSL DTLS replay: lastest replayed
+SSL DTLS replay: last replayed
 ssl_dtls_replay:"abcd12340000abcd12340001abcd12340003":"abcd12340003":-1
 
 SSL DTLS replay: older replayed
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index e42f8ba..2685e6a 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -2229,7 +2229,7 @@
 
         /* After calling mbedtls_ssl_renegotiate for the client all renegotiation
          * should happen inside this function. However in this test, we cannot
-         * perform simultaneous communication betwen client and server so this
+         * perform simultaneous communication between client and server so this
          * function will return waiting error on the socket. All rest of
          * renegotiation should happen during data exchanging */
         ret = mbedtls_ssl_renegotiate( &(client.ssl) );
@@ -2321,7 +2321,7 @@
     TEST_ASSERT( mbedtls_test_buffer_get( NULL, NULL, 0 ) == -1 );
 
     /* Make sure calling put and get on a buffer that hasn't been set up results
-     * in eror. */
+     * in error. */
     mbedtls_test_buffer_init( &buf );
 
     TEST_ASSERT( mbedtls_test_buffer_put( &buf, input, sizeof( input ) ) == -1 );
@@ -5310,6 +5310,7 @@
 
     mbedtls_ssl_config conf;
 
+    USE_PSA_INIT( );
     mbedtls_ssl_config_init( &conf );
 
     TEST_ASSERT( mbedtls_ssl_conf_psk( &conf,
@@ -5323,6 +5324,8 @@
 exit:
 
     mbedtls_ssl_config_free( &conf );
+
+    USE_PSA_DONE( );
 }
 /* END_CASE */
 
diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data
index 0ce4a2e..da12382 100644
--- a/tests/suites/test_suite_version.data
+++ b/tests/suites/test_suite_version.data
@@ -1,4 +1,4 @@
-Check compiletime library version
+Check compile time library version
 check_compiletime_version:"3.1.0"
 
 Check runtime library version
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index 33591d3..8605b63 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -87,7 +87,7 @@
 
     return -1;
 }
-
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
 int ca_callback( void *data, mbedtls_x509_crt const *child,
                  mbedtls_x509_crt **candidates )
 {
@@ -141,6 +141,7 @@
     *candidates = first;
     return( ret );
 }
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
 #endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
 
 int verify_fatal( void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags )