Merge pull request #5835 from superna9999/5831-tls-1-2-ciphersuite-selection

Permissions 2a: TLS 1.2 ciphersuite selection
diff --git a/BRANCHES.md b/BRANCHES.md
index bc8e750..3aca159 100644
--- a/BRANCHES.md
+++ b/BRANCHES.md
@@ -28,7 +28,7 @@
 compatibility on major version changes (e.g. from 3.x to 4.0). We also maintain
 ABI compatibility within LTS branches; see the next section for details.
 
-## Backwards Compatibility
+## Backwards Compatibility for application code
 
 We maintain API compatibility in released versions of Mbed TLS. If you have
 code that's working and secure with Mbed TLS x.y.z and does not rely on
@@ -36,6 +36,14 @@
 modification with any later release x.y'.z' with the same major version
 number, and your code will still build, be secure, and work.
 
+Note that this guarantee only applies if you either use the default
+compile-time configuration (`mbedtls/mbedtls_config.h`) or the same modified
+compile-time configuration. Changing compile-time configuration options can
+result in an incompatible API or ABI, although features will generally not
+affect unrelated features (for example, enabling or disabling a
+cryptographic algorithm does not break code that does not use that
+algorithm).
+
 Note that new releases of Mbed TLS may extend the API. Here are some
 examples of changes that are common in minor releases of Mbed TLS, and are
 not considered API compatibility breaks:
@@ -57,6 +65,25 @@
 comes in conflict with backwards compatibility, we will put security first,
 but always attempt to provide a compatibility option.
 
+## Backward compatibility for the key store
+
+We maintain backward compatibility with previous versions of the
+PSA Crypto persistent storage since Mbed TLS 2.25.0, provided that the
+storage backend (PSA ITS implementation) is configured in a compatible way.
+We intend to maintain this backward compatibility throughout a major version
+of Mbed TLS (for example, all Mbed TLS 3.y versions will be able to read
+keys written under any Mbed TLS 3.x with x <= y).
+
+Mbed TLS 3.x can also read keys written by Mbed TLS 2.25.0 through 2.28.x
+LTS, but future major version upgrades (for example from 2.28.x/3.x to 4.y)
+may require the use of an upgrade tool.
+
+Note that this guarantee does not currently fully extend to drivers, which
+are an experimental feature. We intend to maintain compatibility with the
+basic use of drivers from Mbed TLS 2.28.0 onwards, even if driver APIs
+change. However, for more experimental parts of the driver interface, such
+as the use of driver state, we do not yet guarantee backward compatibility.
+
 ## Long-time support branches
 
 For the LTS branches, additionally we try very hard to also maintain ABI
diff --git a/ChangeLog.d/add_final_delay_accessor b/ChangeLog.d/add_final_delay_accessor
index 8d341df..4b8117f 100644
--- a/ChangeLog.d/add_final_delay_accessor
+++ b/ChangeLog.d/add_final_delay_accessor
@@ -1,4 +1,4 @@
 Features
-   * Add the function mbedtls_timing_get_final_delay() to access the private
+   * Add function mbedtls_timing_get_final_delay() to access the private
      final delay field in an mbedtls_timing_delay_context, as requested in
-     #5183
+     #5183.
diff --git a/ChangeLog.d/add_handshake_completion_accessor b/ChangeLog.d/add_handshake_completion_accessor
index e2b28cf..c06a539 100644
--- a/ChangeLog.d/add_handshake_completion_accessor
+++ b/ChangeLog.d/add_handshake_completion_accessor
@@ -1,4 +1,4 @@
 Features
    * Add function mbedtls_ssl_is_handshake_over() to enable querying if the SSL
      Handshake has completed or not, and thus whether to continue calling
-     mbedtls_ssl_handshake_step(), requested in #4383
+     mbedtls_ssl_handshake_step(), requested in #4383.
diff --git a/ChangeLog.d/add_own_cid_accessors b/ChangeLog.d/add_own_cid_accessors
index fb02868..553299c 100644
--- a/ChangeLog.d/add_own_cid_accessors
+++ b/ChangeLog.d/add_own_cid_accessors
@@ -1,4 +1,4 @@
 Features
    * Add the function mbedtls_ssl_get_own_cid() to access our own connection id
-     within mbedtls_ssl_context, as requested in #5184
+     within mbedtls_ssl_context, as requested in #5184.
 
diff --git a/ChangeLog.d/asn1write-0-fix b/ChangeLog.d/asn1write-0-fix
new file mode 100644
index 0000000..2e01244
--- /dev/null
+++ b/ChangeLog.d/asn1write-0-fix
@@ -0,0 +1,2 @@
+Bugfix
+   * Fix mbedtls_asn1_write_mpi() writing an incorrect encoding of 0.
diff --git a/ChangeLog.d/cmake_add_subdirectory_support.txt b/ChangeLog.d/cmake_add_subdirectory_support.txt
index afcc4b6..f14f3f8 100644
--- a/ChangeLog.d/cmake_add_subdirectory_support.txt
+++ b/ChangeLog.d/cmake_add_subdirectory_support.txt
@@ -1,4 +1,4 @@
 Changes
-   * Add aliases for libraries so that the normal MbedTLS::* targets
-     work when MbedTLS is built as a subdirectory.  Allows use of
-     CMake's FetchContent, as requested in #5688.
+   * In CMake builds, add aliases for libraries so that the normal MbedTLS::*
+     targets work when MbedTLS is built as a subdirectory. This allows the
+     use of FetchContent, as requested in #5688.
diff --git a/ChangeLog.d/cmake_fix_dll_install.txt b/ChangeLog.d/cmake_fix_dll_install.txt
index df51c65..7f407c4 100644
--- a/ChangeLog.d/cmake_fix_dll_install.txt
+++ b/ChangeLog.d/cmake_fix_dll_install.txt
@@ -1,3 +1,3 @@
 Changes
-   * cmake: Fix runtime library install location in mingw
-     This install DLLs in bin directory instead of lib.
+   * Fix runtime library install location when building with CMake and MinGW.
+     DLLs are now installed in the bin directory instead of lib.
diff --git a/ChangeLog.d/deprecate_mbedtls_cipher_setup_psa.txt b/ChangeLog.d/deprecate_mbedtls_cipher_setup_psa.txt
index 782b751..b145243 100644
--- a/ChangeLog.d/deprecate_mbedtls_cipher_setup_psa.txt
+++ b/ChangeLog.d/deprecate_mbedtls_cipher_setup_psa.txt
@@ -1,3 +1,3 @@
 New deprecations
-   * Deprecate mbedtls_cipher_setup_psa() function.
-     Use psa_aead_xxx() / psa_cipher_xxx() directly instead.
+   * Deprecate mbedtls_cipher_setup_psa(). Use psa_aead_xxx() or
+     psa_cipher_xxx() directly instead.
diff --git a/ChangeLog.d/fix-csr_subject_commas.txt b/ChangeLog.d/fix-csr_subject_commas.txt
new file mode 100644
index 0000000..e01c9a8
--- /dev/null
+++ b/ChangeLog.d/fix-csr_subject_commas.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Fix string representation of DNs when outputting values containing commas
+     and other special characters, conforming to RFC 1779. Fixes #769.
diff --git a/ChangeLog.d/fix-parllel-cmake-build-fail.txt b/ChangeLog.d/fix-parllel-cmake-build-fail.txt
index 4746c7b..112fa85 100644
--- a/ChangeLog.d/fix-parllel-cmake-build-fail.txt
+++ b/ChangeLog.d/fix-parllel-cmake-build-fail.txt
@@ -1,3 +1,3 @@
 Bugfix
    * Fix a race condition in out-of-source builds with CMake when generated data
-     files are already present. Fixes #5374
+     files are already present. Fixes #5374.
diff --git a/ChangeLog.d/fix-windows-cmake-build-with-shared-libraries.txt b/ChangeLog.d/fix-windows-cmake-build-with-shared-libraries.txt
index 6878645..a6540a1 100644
--- a/ChangeLog.d/fix-windows-cmake-build-with-shared-libraries.txt
+++ b/ChangeLog.d/fix-windows-cmake-build-with-shared-libraries.txt
@@ -1,3 +1,3 @@
 Bugfix
-   * Fix compilation on Windows when building shared library, by setting
-     library search path to CMAKE_CURRENT_BINARY_DIR.
+   * Fix the library search path when building a shared library with CMake
+     on Windows.
diff --git a/ChangeLog.d/fix-x25519-program.txt b/ChangeLog.d/fix-x25519-program.txt
index af60465..bf5d6ac 100644
--- a/ChangeLog.d/fix-x25519-program.txt
+++ b/ChangeLog.d/fix-x25519-program.txt
@@ -1,4 +1,4 @@
 Bugfix
-   * Fix a bug in x25519 example program where the removal of
+   * Fix a bug in the x25519 example program where the removal of
      MBEDTLS_ECDH_LEGACY_CONTEXT caused the program not to run. Fixes #4901 and
      #3191.
diff --git a/ChangeLog.d/mbedtls_ecp_export.txt b/ChangeLog.d/mbedtls_ecp_export.txt
index 4b5d7d4..5dce5b4 100644
--- a/ChangeLog.d/mbedtls_ecp_export.txt
+++ b/ChangeLog.d/mbedtls_ecp_export.txt
@@ -1,3 +1,3 @@
 Features
-   * Add mbedtls_ecp_export() function to export ECP
-     keypair parameters. Fixes #4838.
+   * Add function mbedtls_ecp_export() to export ECP key pair parameters.
+     Fixes #4838.
diff --git a/ChangeLog.d/mbedtls_sha256_a64_crypto_acceleration.txt b/ChangeLog.d/mbedtls_sha256_a64_crypto_acceleration.txt
deleted file mode 100644
index 865b337..0000000
--- a/ChangeLog.d/mbedtls_sha256_a64_crypto_acceleration.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Features
-   * A64 SHA-2 crypto extension support for SHA-256
diff --git a/ChangeLog.d/mbedtls_sha2_a64_crypto_acceleration.txt b/ChangeLog.d/mbedtls_sha2_a64_crypto_acceleration.txt
new file mode 100644
index 0000000..a6e7f6d
--- /dev/null
+++ b/ChangeLog.d/mbedtls_sha2_a64_crypto_acceleration.txt
@@ -0,0 +1,3 @@
+Features
+   * Add support for the ARMv8 SHA-2 acceleration instructions when building
+     for Aarch64.
diff --git a/ChangeLog.d/mbedtls_sha512_a64_crypto_acceleration.txt b/ChangeLog.d/mbedtls_sha512_a64_crypto_acceleration.txt
deleted file mode 100644
index 01be0b3..0000000
--- a/ChangeLog.d/mbedtls_sha512_a64_crypto_acceleration.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Features
-   * A64 crypto extension support for SHA-512
diff --git a/ChangeLog.d/mbedtls_ssl_comfig_defaults-memleak.txt b/ChangeLog.d/mbedtls_ssl_comfig_defaults-memleak.txt
index d55c016..043b273 100644
--- a/ChangeLog.d/mbedtls_ssl_comfig_defaults-memleak.txt
+++ b/ChangeLog.d/mbedtls_ssl_comfig_defaults-memleak.txt
@@ -1,2 +1,2 @@
 Bugfix
-   * Fix memory leak if mbedtls_ssl_config_defaults() call is repeated
+   * Fix a memory leak if mbedtls_ssl_config_defaults() is called twice.
diff --git a/ChangeLog.d/mbedtls_ssl_dn_hint.txt b/ChangeLog.d/mbedtls_ssl_dn_hint.txt
new file mode 100644
index 0000000..f569a36
--- /dev/null
+++ b/ChangeLog.d/mbedtls_ssl_dn_hint.txt
@@ -0,0 +1,3 @@
+Features
+   * Add accessors to configure DN hints for certificate request:
+     mbedtls_ssl_conf_dn_hints() and mbedtls_ssl_set_hs_dn_hints()
diff --git a/ChangeLog.d/mbedtls_ssl_tls13_client.txt b/ChangeLog.d/mbedtls_ssl_tls13_client.txt
index 855945b..57a26e1 100644
--- a/ChangeLog.d/mbedtls_ssl_tls13_client.txt
+++ b/ChangeLog.d/mbedtls_ssl_tls13_client.txt
@@ -1,4 +1,2 @@
 Features
-   * Add ALPN support in tls13 client. Client is able to write ALPN extension
-     in client hello, and able to parse the response from server encrypted
-     extension.
+   * Add ALPN support in TLS 1.3 clients.
diff --git a/ChangeLog.d/mbedtls_tlsver_enum.txt b/ChangeLog.d/mbedtls_tlsver_enum.txt
index 16435c6..c027ab7 100644
--- a/ChangeLog.d/mbedtls_tlsver_enum.txt
+++ b/ChangeLog.d/mbedtls_tlsver_enum.txt
@@ -1,6 +1,10 @@
+New deprecations
+   * Deprecate mbedtls_ssl_conf_max_version() and
+     mbedtls_ssl_conf_min_version() in favor of
+     mbedtls_ssl_conf_max_tls_version() and
+     mbedtls_ssl_conf_min_tls_version().
+
 Features
-   * Unify internal/external TLS protocol version enums
-   * Deprecate mbedtls_ssl_conf_max_version()
-     Replaced with mbedtls_ssl_conf_max_tls_version()
-   * Deprecate mbedtls_ssl_conf_min_version()
-     Replaced with mbedtls_ssl_conf_min_tls_version()
+   * Add functions mbedtls_ssl_conf_max_tls_version() and
+     mbedtls_ssl_conf_min_tls_version() that use a single value to specify
+     the protocol version.
diff --git a/ChangeLog.d/md_info_from_ctx.txt b/ChangeLog.d/md_info_from_ctx.txt
index f8ec1a0..aa61e1a 100644
--- a/ChangeLog.d/md_info_from_ctx.txt
+++ b/ChangeLog.d/md_info_from_ctx.txt
@@ -1,3 +1,3 @@
 Features
-   * Add a function to extract message digest information from a message
-     digest context.
+   * Add function mbedtls_md_info_from_ctx() to recall the message digest
+     information that was used to set up a message digest context.
diff --git a/ChangeLog.d/psa_aead_singleshot_error.txt b/ChangeLog.d/psa_aead_singleshot_error.txt
index 7243874..ccf1d4c 100644
--- a/ChangeLog.d/psa_aead_singleshot_error.txt
+++ b/ChangeLog.d/psa_aead_singleshot_error.txt
@@ -1,4 +1,4 @@
 Changes
-   * Return PSA_ERROR_INVALID_ARGUMENT if the algorithm passed to singleshot
+   * Return PSA_ERROR_INVALID_ARGUMENT if the algorithm passed to one-shot
      AEAD functions is not an AEAD algorithm. This aligns them with the
-     multipart functions, and the PSA Crypto API 1.1 spec.
+     multipart functions, and the PSA Crypto API 1.1 specification.
diff --git a/ChangeLog.d/psa_crypto_reduced_configs.txt b/ChangeLog.d/psa_crypto_reduced_configs.txt
deleted file mode 100644
index 5bc9bc1..0000000
--- a/ChangeLog.d/psa_crypto_reduced_configs.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Changes
-   * Automatically enable MBEDTLS_PK_WRITE_C if MBEDTLS_PK_C and
-     MBEDTLS_USE_PSA_CRYPTO are enabled. This is due to ecdsa_verify_wrap
-     requirements, but will also probably be needed by RSA soon, hence the
-     broader PK_C requirement.
diff --git a/ChangeLog.d/psa_crypto_se.txt b/ChangeLog.d/psa_crypto_se.txt
new file mode 100644
index 0000000..f8136b1
--- /dev/null
+++ b/ChangeLog.d/psa_crypto_se.txt
@@ -0,0 +1,5 @@
+New deprecations
+   * Secure element drivers enabled by MBEDTLS_PSA_CRYPTO_SE_C are deprecated.
+     This was intended as an experimental feature, but had not been explicitly
+     documented as such. Use opaque drivers with the interface enabled by
+     MBEDTLS_PSA_CRYPTO_DRIVERS instead.
diff --git a/ChangeLog.d/psk_to_ms_mixed_psk.txt b/ChangeLog.d/psk_to_ms_mixed_psk.txt
index b189661..998cc11 100644
--- a/ChangeLog.d/psk_to_ms_mixed_psk.txt
+++ b/ChangeLog.d/psk_to_ms_mixed_psk.txt
@@ -1,4 +1,4 @@
 Features
     * Extend the existing PSA_ALG_TLS12_PSK_TO_MS() algorithm to support
-      mixed-psk. Add an optional input PSA_KEY_DERIVATION_INPUT_OTHER_SECRET
+      mixed-PSK. Add an optional input PSA_KEY_DERIVATION_INPUT_OTHER_SECRET
       holding the other secret.
diff --git a/ChangeLog.d/raw-agreement-destroy-missing.txt b/ChangeLog.d/raw-agreement-destroy-missing.txt
deleted file mode 100644
index 7342b8c..0000000
--- a/ChangeLog.d/raw-agreement-destroy-missing.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
-   * Add missing key slot destruction calls when a raw key agreement or
-     a public key export fails in ssl_write_client_key_exchange.
diff --git a/ChangeLog.d/selftest-gcc12.txt b/ChangeLog.d/selftest-gcc12.txt
new file mode 100644
index 0000000..aafa256
--- /dev/null
+++ b/ChangeLog.d/selftest-gcc12.txt
@@ -0,0 +1,2 @@
+Bugfix
+   * Silence a warning from GCC 12 in the selftest program. Fixes #5974.
diff --git a/ChangeLog.d/tls13-fix-finished-fetch.txt b/ChangeLog.d/tls13-fix-finished-fetch.txt
index 28c30f9..9a8acb3 100644
--- a/ChangeLog.d/tls13-fix-finished-fetch.txt
+++ b/ChangeLog.d/tls13-fix-finished-fetch.txt
@@ -1,5 +1,3 @@
 Bugfix
-   * Fix handshake failure when the peer Finished message has not been received
-     yet when we first try to fetch it. The fetching is moved before the
-     preprocessing computations to avoid doing them multiple times, which was
-     causing the handshake to fail.
+   * Fix a TLS 1.3 handshake failure when the peer Finished message has not
+     been received yet when we first try to fetch it.
diff --git a/ChangeLog.d/tls13-misc-changelogs.txt b/ChangeLog.d/tls13-misc-changelogs.txt
new file mode 100644
index 0000000..a575b33
--- /dev/null
+++ b/ChangeLog.d/tls13-misc-changelogs.txt
@@ -0,0 +1,18 @@
+Bugfix
+   * Fix a TLS 1.3 handshake failure when the first attempt to send the client
+     Finished message on the network cannot be satisfied. Fixes #5499.
+
+Features
+   * Add support for authentication of TLS 1.3 clients by TLS 1.3 servers.
+   * Add support for server HelloRetryRequest message. The TLS 1.3 client is
+     now capable of negotiating another shared secret if the one sent in its
+     first ClientHello was not suitable to the server.
+   * Add support for client-side TLS version negotiation. If both TLS 1.2 and
+     TLS 1.3 protocols are enabled in the build of Mbed TLS, the TLS client now
+     negotiates TLS 1.3 or TLS 1.2 with TLS servers.
+   * Enable building of Mbed TLS with TLS 1.3 protocol support but without TLS
+     1.2 protocol support.
+   * Mbed TLS provides an implementation of a TLS 1.3 server (ephemeral key
+     establishment only). See docs/architecture/tls13-support.md for a
+     description of the support. The MBEDTLS_SSL_PROTO_TLS1_3 and
+     MBEDTLS_SSL_SRV_C configuration options control this.
diff --git a/ChangeLog.d/tls13_and_keep_certificates.txt b/ChangeLog.d/tls13_and_keep_certificates.txt
new file mode 100644
index 0000000..8c2421f
--- /dev/null
+++ b/ChangeLog.d/tls13_and_keep_certificates.txt
@@ -0,0 +1,4 @@
+Bugfix
+   * Fix check_config.h to check that we have MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
+     when MBEDTLS_SSL_PROTO_TLS1_3 is specified, and make this and other
+     dependencies explicit in the documentation. Fixes #5610.
diff --git a/ChangeLog.d/use-psa-ecdhe-curve.txt b/ChangeLog.d/use-psa-ecdhe-curve.txt
index cc432bd..658f88f 100644
--- a/ChangeLog.d/use-psa-ecdhe-curve.txt
+++ b/ChangeLog.d/use-psa-ecdhe-curve.txt
@@ -4,4 +4,4 @@
      client would fail to check that the curve selected by the server for
      ECDHE was indeed one that was offered. As a result, the client would
      accept any curve that it supported, even if that curve was not allowed
-     according to its configuration.
+     according to its configuration. Fixes #5291.
diff --git a/docs/3.0-migration-guide.md b/docs/3.0-migration-guide.md
index 3653683..b933edf 100644
--- a/docs/3.0-migration-guide.md
+++ b/docs/3.0-migration-guide.md
@@ -2,7 +2,7 @@
 
 This guide details the steps required to migrate from Mbed TLS version 2.x to
 Mbed TLS version 3.0 or greater. Unlike normal releases, Mbed TLS 3.0 breaks
-compatibility with previous versions, so users (and alt implementors) might
+compatibility with previous versions, so users (and alt implementers) might
 need to change their own code in order to make it work with Mbed TLS 3.0.
 
 Here's the list of breaking changes; each entry should help you answer these
@@ -13,7 +13,28 @@
 - Removal of many insecure or obsolete features
 - Tidying up of configuration options (including removing some less useful options).
 - Changing function signatures, e.g. adding return codes, adding extra parameters, or making some arguments const.
-- Removal of functions previously marked as deprecated.
+- Removal of functions, macros, and types previously marked as deprecated.
+
+Much of the information needed to determine a migration path can be found in the Mbed TLS 2.x documentation.
+
+
+## Accessing the Mbed TLS 2.x documentation
+
+For features previously marked as deprecated, Mbed TLS 2.x documentation may
+explain how to upgrade, and should be referred to when migrating code. Where a
+migration path is not provided in prior documentation, changes made and the
+upgrade steps required will be explained later in this guide.
+
+It's best to use the latest version of Mbed TLS 2.x for this purpose, which is the 2.28 LTS release.
+So to generate the documentation, checkout the `mbedtls-2.28` branch and follow
+the instructions in the [Documentation section of the README](https://github.com/Mbed-TLS/mbedtls/blob/mbedtls-2.28/README.md#documentation).
+Then browse `apidoc/deprecated.html` for guidance on upgrading deprecated code.
+
+For some deprecated functions, 2.x documentation will suggest using a variant
+suffixed with `_ret`. In Mbed TLS 3.x, this change may not be required, as most
+of these variants have been renamed without the suffix. The section
+[Rename mbedtls_*_ret...](#rename-mbedtls__ret-cryptography-functions-whose-deprecated-variants-have-been-removed)
+has further detail on which functions this applies to.
 
 
 ## General changes
@@ -157,7 +178,7 @@
 `MBEDTLS_DHM_RFC3526_MODP_4096_P `and `MBEDTLS_DHM_RFC3526_MODP_4096_G` were
 removed. The primes from RFC 5114 are deprecated because their derivation is not
 documented and therefore their usage constitutes a security risk; they are fully
-removed from the library. Please use parameters from RFC3526 (still in the
+removed from the library. Please use parameters from RFC 3526 (still in the
 library, only in binary form) or RFC 7919 (also available in the library) or
 other trusted sources instead.
 
@@ -248,22 +269,29 @@
 
 ### Deprecated error codes for hardware failures were removed
 
-- The macros `MBEDTLS_ERR_xxx_FEATURE_UNSUPPORTED` from various crypto modules
+- The macros `MBEDTLS_ERR_xxx_FEATURE_UNAVAILABLE` from various crypto modules
   were removed; `MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED` is now used
   instead.
+- The macro `MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION` was removed;
+  `MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED` is now used instead.
 - The macros `MBEDTLS_ERR_xxx_HW_ACCEL_FAILED` from various crypto modules
   were removed; `MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED` is now used instead.
 
+### Deprecated error codes for invalid input data were removed
+
+- The macros `MBEDTLS_ERR_xxx_INVALID_KEY_LENGTH` from ARIA and Camellia
+  modules were removed; `MBEDTLS_ERR_xxx_BAD_INPUT_DATA` is now used instead.
+
 ### Remove the mode parameter from RSA functions
 
-This affects all users who use the RSA encryption, decryption, sign and
+This affects all users who use the RSA encrypt, decrypt, sign and
 verify APIs.
 
 The RSA module no longer supports private-key operations with the public key or
 vice versa. As a consequence, RSA operation functions no longer have a mode
 parameter. If you were calling RSA operations with the normal mode (public key
 for verification or encryption, private key for signature or decryption), remove
-the `MBEDTLS_MODE_PUBLIC` or `MBEDTLS_MODE_PRIVATE` argument. If you were calling
+the `MBEDTLS_RSA_PUBLIC` or `MBEDTLS_RSA_PRIVATE` argument. If you were calling
 RSA operations with the wrong mode, which rarely makes sense from a security
 perspective, this is no longer supported.
 
@@ -334,7 +362,7 @@
 
 ### Remove the padding parameters from `mbedtls_rsa_init()`
 
-This affects all users who use the RSA encryption, decryption, sign and
+This affects all users who use the RSA encrypt, decrypt, sign and
 verify APIs.
 
 The function `mbedtls_rsa_init()` no longer supports selecting the PKCS#1 v2.1
@@ -552,13 +580,13 @@
 ### Remove `MBEDTLS_X509_CHECK_*_KEY_USAGE` options from `mbedtls_config.h`
 
 This change affects users who have chosen the configuration options to disable the
-library's verification of the `keyUsage` and `extendedKeyUsage` fields of x509
+library's verification of the `keyUsage` and `extendedKeyUsage` fields of X.509
 certificates.
 
 The `MBEDTLS_X509_CHECK_KEY_USAGE` and `MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE`
-configuration options are removed and the X509 code now behaves as if they were
+configuration options are removed and the X.509 code now behaves as if they were
 always enabled. It is consequently not possible anymore to disable at compile
-time the verification of the `keyUsage` and `extendedKeyUsage` fields of X509
+time the verification of the `keyUsage` and `extendedKeyUsage` fields of X.509
 certificates.
 
 The verification of the `keyUsage` and `extendedKeyUsage` fields is important,
diff --git a/docs/architecture/mbed-crypto-storage-specification.md b/docs/architecture/mbed-crypto-storage-specification.md
index 914bca3..60203a0 100644
--- a/docs/architecture/mbed-crypto-storage-specification.md
+++ b/docs/architecture/mbed-crypto-storage-specification.md
@@ -112,7 +112,7 @@
 The way in which the file name is constructed from the key identifier depends on the storage backend. The content of the file is described [below](#key-file-format-for-1.0.0).
 
 * Library integration: the key file name is just the key identifier as defined in the PSA crypto specification. This is a 32-bit value.
-* PSA service integration: the key file name is `(uint32_t)owner_uid << 32 | key_id` where `key_id` is the key identifier from the owner point of view and `owner_uid` (of type `int32_t`) is the calling partition identifier provided to the server by the partition manager. This is a 64-bit value.
+* PSA service integration: the key file name is `(uint64_t)owner_uid << 32 | key_id` where `key_id` is the key identifier from the owner point of view and `owner_uid` (of type `int32_t`) is the calling partition identifier provided to the server by the partition manager. This is a 64-bit value.
 
 ### Key file format for 1.0.0
 
@@ -120,7 +120,11 @@
 
 ### Nonvolatile random seed file format for 1.0.0
 
-[Identical to 0.1.0](#nonvolatile-random-seed-file-format-for-0.1.0).
+The nonvolatile random seed file contains a seed for the random generator. If present, it is rewritten at each boot as part of the random generator initialization.
+
+The file format is just the seed as a byte string with no metadata or encoding of any kind.
+
+This is unchanged since [the feature was introduced in Mbed Crypto 0.1.0](#nonvolatile-random-seed-file-format-for-0.1.0).
 
 ### File namespace on a PSA platform for 1.0.0
 
@@ -167,7 +171,21 @@
 Released in early June 2019. <br>
 Integrated in Mbed OS 5.13.
 
-Identical to [1.0.0](#mbed-crypto-1.0.0) except for some changes in the key file format.
+Changes since [1.0.0](#mbed-crypto-1.0.0):
+
+* The stdio backend for storage has been replaced by an implementation of [PSA ITS over stdio](#file-namespace-on-stdio-for-1.1.0).
+* [Some changes in the key file format](#key-file-format-for-1.1.0).
+
+### File namespace on stdio for 1.1.0
+
+Assumption: C stdio, allowing names containing lowercase letters, digits and underscores, of length up to 23.
+
+An undocumented build-time configuration value `PSA_ITS_STORAGE_PREFIX` allows storing the key files in a directory other than the current directory. This value is simply prepended to the file name (so it must end with a directory separator to put the keys in a different directory).
+
+* `PSA_ITS_STORAGE_PREFIX "tempfile.psa_its"`: used as a temporary file. Must be writable. May be overwritten or deleted if present.
+* `sprintf(PSA_ITS_STORAGE_PREFIX "%016llx.psa_its", key_id)`: a key or non-key file. The `key_id` in the name is the 64-bit file identifier, which is the [key identifier](#key-names-for-mbed-tls-2.25.0) for a key file or some reserved identifier for a non-key file (currently: only the [nonvolatile random seed](#nonvolatile-random-seed-file-format-for-1.0.0)). The contents of the file are:
+    * Magic header (8 bytes): `"PSA\0ITS\0"`
+    * File contents.
 
 ### Key file format for 1.1.0
 
@@ -314,3 +332,134 @@
     * For an opaque key (unified driver interface): driver-specific opaque key blob.
     * For an opaque key (key in a secure element): slot number (8 bytes), in platform endianness.
 * Any trailing data is rejected on load.
+
+Mbed TLS 2.25.0
+---------------
+
+Tags: `mbedtls-2.25.0`, `mbedtls-2.26.0`, `mbedtls-2.27.0`, `mbedtls-2.28.0`, `mbedtls-3.0.0`, `mbedtls-3.1.0`
+
+First released in December 2020.
+
+Note: this is the first version that is officially supported. The version number is still 0.
+
+Backward compatibility commitments: we promise backward compatibility for stored keys when Mbed TLS is upgraded from x to y if x >= 2.25 and y < 4. See [`BRANCHES.md`](../../BRANCHES.md) for more details.
+
+Supported integrations:
+
+* [PSA platform](#file-namespace-on-a-psa-platform-on-mbed-tls-2.25.0)
+* [library using PSA ITS](#file-namespace-on-its-as-a-library-on-mbed-tls-2.25.0)
+* [library using C stdio](#file-namespace-on-stdio-for-mbed-tls-2.25.0)
+
+Supported features:
+
+* [Persistent keys](#key-file-format-for-mbed-tls-2.25.0) designated by a [key identifier and owner](#key-names-for-mbed-tls-2.25.0). Keys can be:
+    * Transparent, stored in the export format.
+    * Opaque, using the unified driver interface with statically registered drivers (`MBEDTLS_PSA_CRYPTO_DRIVERS`). The driver determines the content of the opaque key blob.
+    * Opaque, using the deprecated secure element interface with dynamically registered drivers (`MBEDTLS_PSA_CRYPTO_SE_C`). The driver picks a slot number which is stored in the place of the key material.
+* [Nonvolatile random seed](#nonvolatile-random-seed-file-format-for-mbed-tls-2.25.0) on ITS only.
+
+### Changes introduced in Mbed TLS 2.25.0
+
+* The numerical encodings of `psa_key_type_t`, `psa_key_usage_t` and `psa_algorithm_t` have changed.
+
+### File namespace on a PSA platform on Mbed TLS 2.25.0
+
+Assumption: ITS provides a 64-bit file identifier namespace. The Crypto service can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
+
+Assumption: the owner identifier is a nonzero value of type `int32_t`.
+
+* Files 0 through 0xfffeffff: unused.
+* Files 0xffff0000 through 0xffffffff: reserved for internal use of the crypto library or crypto service. See [non-key files](#non-key-files-on-mbed-tls-2.25.0).
+* Files 0x100000000 through 0xffffffffffff: [content](#key-file-format-for-mbed-tls-2.25.0) of the [key whose identifier is the file identifier](#key-names-for-mbed-tls-2.25.0). The upper 32 bits determine the owner.
+
+### File namespace on ITS as a library on Mbed TLS 2.25.0
+
+Assumption: ITS provides a 64-bit file identifier namespace. The entity using the crypto library can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
+
+This is a library integration, so there is no owner. The key file identifier is identical to the key identifier.
+
+* File 0: unused.
+* Files 1 through 0xfffeffff: [content](#key-file-format-for-mbed-tls-2.25.0) of the [key whose identifier is the file identifier](#key-names-for-mbed-tls-2.25.0).
+* Files 0xffff0000 through 0xffffffff: reserved for internal use of the crypto library or crypto service. See [non-key files](#non-key-files-on-mbed-tls-2.25.0).
+* Files 0x100000000 through 0xffffffffffffffff: unused.
+
+### File namespace on stdio for Mbed TLS 2.25.0
+
+Assumption: C stdio, allowing names containing lowercase letters, digits and underscores, of length up to 23.
+
+An undocumented build-time configuration value `PSA_ITS_STORAGE_PREFIX` allows storing the key files in a directory other than the current directory. This value is simply prepended to the file name (so it must end with a directory separator to put the keys in a different directory).
+
+* `PSA_ITS_STORAGE_PREFIX "tempfile.psa_its"`: used as a temporary file. Must be writable. May be overwritten or deleted if present.
+* `sprintf(PSA_ITS_STORAGE_PREFIX "%016llx.psa_its", key_id)`: a key or non-key file. The `key_id` in the name is the 64-bit file identifier, which is the [key identifier](#key-names-for-mbed-tls-2.25.0) for a key file or some reserved identifier for a [non-key file](#non-key-files-on-mbed-tls-2.25.0). The contents of the file are:
+    * Magic header (8 bytes): `"PSA\0ITS\0"`
+    * File contents.
+
+### Key names for Mbed TLS 2.25.0
+
+Information about each key is stored in a dedicated file designated by the key identifier. In integrations where there is no concept of key owner (in particular, in library integrations), the key identifier is exactly the key identifier as defined in the PSA Cryptography API specification (`psa_key_id_t`). In integrations where there is a concept of key owner (integration into a service for example), the key identifier is made of an owner identifier (its semantics and type are integration specific) and of the key identifier (`psa_key_id_t`) from the key owner point of view.
+
+The way in which the file name is constructed from the key identifier depends on the storage backend. The content of the file is described [below](#key-file-format-for-mbed-tls-2.25.0).
+
+* Library integration: the key file name is just the key identifier as defined in the PSA crypto specification. This is a 32-bit value which must be in the range 0x00000001..0x3fffffff (`PSA_KEY_ID_USER_MIN`..`PSA_KEY_ID_USER_MAX`).
+* PSA service integration: the key file name is `(uint64_t)owner_uid << 32 | key_id` where `key_id` is the key identifier from the owner point of view and `owner_uid` (of type `int32_t`) is the calling partition identifier provided to the server by the partition manager. This is a 64-bit value.
+
+### Key file format for Mbed TLS 2.25.0
+
+All integers are encoded in little-endian order in 8-bit bytes except where otherwise indicated.
+
+The layout of a key file is:
+
+* magic (8 bytes): `"PSA\0KEY\0"`.
+* version (4 bytes): 0.
+* lifetime (4 bytes): `psa_key_lifetime_t` value.
+* type (2 bytes): `psa_key_type_t` value.
+* bits (2 bytes): `psa_key_bits_t` value.
+* policy usage flags (4 bytes): `psa_key_usage_t` value.
+* policy usage algorithm (4 bytes): `psa_algorithm_t` value.
+* policy enrollment algorithm (4 bytes): `psa_algorithm_t` value.
+* key material length (4 bytes).
+* key material:
+    * For a transparent key: output of `psa_export_key`.
+    * For an opaque key (unified driver interface): driver-specific opaque key blob.
+    * For an opaque key (key in a dynamic secure element): slot number (8 bytes), in platform endianness.
+* Any trailing data is rejected on load.
+
+### Non-key files on Mbed TLS 2.25.0
+
+File identifiers that are outside the range of persistent key identifiers are reserved for internal use by the library. The only identifiers currently in use have the owner id (top 32 bits) set to 0.
+
+* Files 0xfffffe02 through 0xfffffeff (`PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + lifetime`): dynamic secure element driver storage. The content of the file is the secure element driver's persistent data.
+* File 0xffffff52 (`PSA_CRYPTO_ITS_RANDOM_SEED_UID`): [nonvolatile random seed](#nonvolatile-random-seed-file-format-for-mbed-tls-2.25.0).
+* File 0xffffff54 (`PSA_CRYPTO_ITS_TRANSACTION_UID`): [transaction file](#transaction-file-format-for-mbed-tls-2.25.0).
+* Other files are unused and reserved for future use.
+
+### Nonvolatile random seed file format for Mbed TLS 2.25.0
+
+[Identical to Mbed Crypto 0.1.0](#nonvolatile-random-seed-file-format-for-0.1.0).
+
+### Transaction file format for Mbed TLS 2.25.0
+
+The transaction file contains data about an ongoing action that cannot be completed atomically. It exists only if there is an ongoing transaction.
+
+All integers are encoded in platform endianness.
+
+All currently existing transactions concern a key in a dynamic secure element.
+
+The layout of a transaction file is:
+
+* type (2 bytes): the [transaction type](#transaction-types-on-mbed-tls-2.25.0).
+* unused (2 bytes)
+* lifetime (4 bytes): `psa_key_lifetime_t` value that corresponds to a key in a secure element.
+* slot number (8 bytes): `psa_key_slot_number_t` value. This is the unique designation of the key for the secure element driver.
+* key identifier (4 bytes in a library integration, 8 bytes on a PSA platform): the internal representation of the key identifier. On a PSA platform, this encodes the key owner in the same way as [in file identifiers for key files](#file-namespace-on-a-psa-platform-on-mbed-tls-2.25.0)).
+
+#### Transaction types on Mbed TLS 2.25.0
+
+* 0x0001: key creation. The following locations may or may not contain data about the key that is being created:
+    * The slot in the secure element designated by the slot number.
+    * The file containing the key metadata designated by the key identifier.
+    * The driver persistent data.
+* 0x0002: key destruction. The following locations may or may not still contain data about the key that is being destroyed:
+    * The slot in the secure element designated by the slot number.
+    * The file containing the key metadata designated by the key identifier.
+    * The driver persistent data.
diff --git a/docs/architecture/tls13-support.md b/docs/architecture/tls13-support.md
index 6c39bc5..10da3c5 100644
--- a/docs/architecture/tls13-support.md
+++ b/docs/architecture/tls13-support.md
@@ -4,8 +4,8 @@
 Overview
 --------
 
-Mbed TLS provides a minimum viable implementation of the TLS 1.3 protocol
-defined in the "MVP definition" section below. The TLS 1.3 support enablement
+Mbed TLS provides a partial implementation of the TLS 1.3 protocol defined in
+the "Support description" section below. The TLS 1.3 support enablement
 is controlled by the MBEDTLS_SSL_PROTO_TLS1_3 configuration option.
 
 The development of the TLS 1.3 protocol is based on the TLS 1.3 prototype
@@ -16,38 +16,22 @@
 status" below describes what remains to be upstreamed.
 
 
-MVP definition
---------------
+Support description
+-------------------
 
 - Overview
 
-  - The TLS 1.3 MVP implements only the client side of the protocol.
+  - Mbed TLS implements both the client and the server side of the TLS 1.3
+    protocol.
 
-  - The TLS 1.3 MVP supports ECDHE key establishment.
+  - Mbed TLS supports ECDHE key establishment.
 
-  - The TLS 1.3 MVP does not support DHE key establishment.
+  - Mbed TLS does not support DHE key establishment.
 
-  - The TLS 1.3 MVP does not support pre-shared keys, including any form of
+  - Mbed TLS does not support pre-shared keys, including any form of
     session resumption. This implies that it does not support sending early
     data (0-RTT data).
 
-  - The TLS 1.3 MVP supports the authentication of the server by the client
-    but does not support authentication of the client by the server. In terms
-    of TLS 1.3 authentication messages, this means that the TLS 1.3 MVP
-    supports the processing of the Certificate and CertificateVerify messages
-    but not of the CertificateRequest message.
-
-  - The TLS 1.3 MVP does not support the handling of server HelloRetryRequest
-    message. In practice, this means that the handshake will fail if the MVP
-    does not provide in its ClientHello the shared secret associated to the
-    group selected by the server for key establishement. For more information,
-    see the comment associated to the `key_share` extension below.
-
-  - If the TLS 1.3 MVP receives a HelloRetryRequest or a CertificateRequest
-    message, it aborts the handshake with an handshake_failure closure alert
-    and the `mbedtls_ssl_handshake()` returns in error with the
-    `MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE` error code.
-
 - Supported cipher suites: depends on the library configuration. Potentially
   all of them:
   TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256,
@@ -55,94 +39,72 @@
 
 - Supported ClientHello extensions:
 
-  | Extension                    |   MVP   | Prototype (1) |
-  | ---------------------------- | ------- | ------------- |
-  | server_name                  | YES     | YES           |
-  | max_fragment_length          | no      | YES           |
-  | status_request               | no      | no            |
-  | supported_groups             | YES     | YES           |
-  | signature_algorithms         | YES     | YES           |
-  | use_srtp                     | no      | no            |
-  | heartbeat                    | no      | no            |
-  | apln                         | no      | YES           |
-  | signed_certificate_timestamp | no      | no            |
-  | client_certificate_type      | no      | no            |
-  | server_certificate_type      | no      | no            |
-  | padding                      | no      | no            |
-  | key_share                    | YES (2) | YES           |
-  | pre_shared_key               | no      | YES           |
-  | psk_key_exchange_modes       | no      | YES           |
-  | early_data                   | no      | YES           |
-  | cookie                       | no      | YES           |
-  | supported_versions           | YES (3) | YES           |
-  | certificate_authorities      | no      | no            |
-  | post_handshake_auth          | no      | no            |
-  | signature_algorithms_cert    | no      | no            |
+  | Extension                    | Support |
+  | ---------------------------- | ------- |
+  | server_name                  | YES     |
+  | max_fragment_length          | no      |
+  | status_request               | no      |
+  | supported_groups             | YES     |
+  | signature_algorithms         | YES     |
+  | use_srtp                     | no      |
+  | heartbeat                    | no      |
+  | apln                         | YES     |
+  | signed_certificate_timestamp | no      |
+  | client_certificate_type      | no      |
+  | server_certificate_type      | no      |
+  | padding                      | no      |
+  | key_share                    | YES     |
+  | pre_shared_key               | no      |
+  | psk_key_exchange_modes       | no      |
+  | early_data                   | no      |
+  | cookie                       | no      |
+  | supported_versions           | YES     |
+  | certificate_authorities      | no      |
+  | post_handshake_auth          | no      |
+  | signature_algorithms_cert    | no      |
 
-  (1) This is just for comparison.
-
-  (2) The MVP sends only one shared secret corresponding to the configured
-      preferred group. This could end up with connection failure if the
-      server does not support our preferred curve, as the MVP does not implement
-      HelloRetryRequest. The preferred group is the group of the first curve in
-      the list of allowed curves as defined by the configuration. The allowed
-      curves are by default ordered as follows: `x25519`, `secp256r1`,
-      `secp384r1` and finally `secp521r1`. Note that, in the absence of an
-      application profile standard specifying otherwise, section 9.1 of the
-      specification rather promotes curve `secp256r1` to be supported over
-      curve `x25519`. The MVP would, however, rather keep the preference order
-      currently promoted by Mbed TLS as this applies to TLS 1.2 as well, and
-      changing the order only for TLS1.3 would be potentially difficult.
-      In the unlikely event a server does not support curve `x25519` but does
-      support curve `secp256r1`, curve `secp256r1` can be set as the preferred
-      curve through the `mbedtls_ssl_conf_curves()` API.
-
-  (3) The MVP proposes only TLS 1.3 and does not support version negotiation.
-      Out-of-protocol fallback is supported though if the Mbed TLS library
-      has been built to support both TLS 1.3 and TLS 1.2: just set the
-      maximum of the minor version of the SSL configuration to
-      MBEDTLS_SSL_MINOR_VERSION_3 (`mbedtls_ssl_conf_min_version()` API) and
-      re-initiate a server handshake.
 
 - Supported groups: depends on the library configuration.
-  Potentially all ECDHE groups but x448:
-  secp256r1, x25519, secp384r1 and secp521r1.
+  Potentially all ECDHE groups:
+  secp256r1, x25519, secp384r1, x448 and secp521r1.
 
   Finite field groups (DHE) are not supported.
 
 - Supported signature algorithms (both for certificates and CertificateVerify):
   depends on the library configuration.
   Potentially:
-  rsa_pkcs1_sha256, rsa_pss_rsae_sha256, ecdsa_secp256r1_sha256,
-  ecdsa_secp384r1_sha384 and ecdsa_secp521r1_sha512.
+  ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_secp521r1_sha512,
+  rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512, rsa_pss_rsae_sha256,
+  rsa_pss_rsae_sha384 and rsa_pss_rsae_sha512.
 
   Note that in absence of an application profile standard specifying otherwise
-  the three first ones in the list above are mandatory (see section 9.1 of the
-  specification).
+  rsa_pkcs1_sha256, rsa_pss_rsae_sha256 and ecdsa_secp256r1_sha256 are
+  mandatory (see section 9.1 of the specification).
 
 - Supported versions:
 
-  - TLS 1.2 and TLS 1.3 but version negotiation is not supported.
+  - TLS 1.2 and TLS 1.3 with version negotiation on the client side, not server
+    side.
 
-  - TLS 1.3 cannot be enabled in the build (MBEDTLS_SSL_PROTO_TLS1_3
-    configuration option) without TLS 1.2 (MBEDTLS_SSL_PROTO_TLS1_2 configuration
-    option).
-
-  - TLS 1.2 can be enabled in the build independently of TLS 1.3.
+  - TLS 1.2 and TLS 1.3 can be enabled in the build independently of each
+    other.
 
   - If both TLS 1.3 and TLS 1.2 are enabled at build time, only one of them can
-    be configured at runtime via `mbedtls_ssl_conf_{min,max}_version`. Otherwise,
-    `mbedtls_ssl_setup` will raise `MBEDTLS_ERR_SSL_BAD_CONFIG` error.
+    be configured at runtime via `mbedtls_ssl_conf_{min,max}_tls_version` for a
+    server endpoint. Otherwise, `mbedtls_ssl_setup` will raise
+    `MBEDTLS_ERR_SSL_BAD_CONFIG` error.
 
 - Compatibility with existing SSL/TLS build options:
 
-  The TLS 1.3 MVP is compatible with all TLS 1.2 configuration options in the
-  sense that when enabling the TLS 1.3 MVP in the library there is no need to
-  modify the configuration for TLS 1.2. The MBEDTLS_USE_PSA_CRYPTO configuration
-  option is an exception though, the TLS 1.3 MVP is not compatible with it.
+  The TLS 1.3 implementation is compatible with nearly all TLS 1.2
+  configuration options in the sense that when enabling TLS 1.3 in the library
+  there is rarely any need to modify the configuration from that used for
+  TLS 1.2. There are two exceptions though: the TLS 1.3 implementation requires
+  MBEDTLS_PSA_CRYPTO_C and MBEDTLS_SSL_KEEP_PEER_CERTIFICATE, so these options
+  must be enabled.
 
-  Mbed TLS SSL/TLS related features are not supported or not applicable to the
-  TLS 1.3 MVP:
+  Most of the Mbed TLS SSL/TLS related options are not supported or not
+  applicable to the TLS 1.3 implementation:
 
   | Mbed TLS configuration option            | Support |
   | ---------------------------------------- | ------- |
@@ -152,13 +114,12 @@
   | MBEDTLS_SSL_DEBUG_ALL                    | no      |
   | MBEDTLS_SSL_ENCRYPT_THEN_MAC             | n/a     |
   | MBEDTLS_SSL_EXTENDED_MASTER_SECRET       | n/a     |
-  | MBEDTLS_SSL_KEEP_PEER_CERTIFICATE        | no      |
+  | MBEDTLS_SSL_KEEP_PEER_CERTIFICATE        | no (1)  |
   | MBEDTLS_SSL_RENEGOTIATION                | n/a     |
   | MBEDTLS_SSL_MAX_FRAGMENT_LENGTH          | no      |
   |                                          |         |
   | MBEDTLS_SSL_SESSION_TICKETS              | no      |
-  | MBEDTLS_SSL_EXPORT_KEYS                  | no (1)  |
-  | MBEDTLS_SSL_SERVER_NAME_INDICATION       | no      |
+  | MBEDTLS_SSL_SERVER_NAME_INDICATION       | yes     |
   | MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH       | no      |
   |                                          |         |
   | MBEDTLS_ECP_RESTARTABLE                  | no      |
@@ -176,35 +137,20 @@
   | MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED    | n/a     |
   | MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED     | n/a     |
   |                                          |         |
-  | MBEDTLS_USE_PSA_CRYPTO                   | no      |
+  | MBEDTLS_PSA_CRYPTO_C                     | no (1)  |
+  | MBEDTLS_USE_PSA_CRYPTO                   | yes     |
 
-  (1) Some support has already been upstreamed but it is incomplete.
+  (1) These options must remain in their default state of enabled.
   (2) Key exchange configuration options for TLS 1.3 will likely to be
       organized around the notion of key exchange mode along the line
       of the MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE/PSK/PSK_EPHEMERAL/EPHEMERAL
       runtime configuration macros.
 
-- Quality considerations
-  - Standard Mbed TLS review bar
-  - Interoperability testing with OpenSSL and GnuTLS. Test with all the
-    cipher suites and signature algorithms supported by OpenSSL/GnuTLS server.
-  - Negative testing against OpenSSL/GnuTLS servers with which the
-    handshake fails due to incompatibility with the capabilities of the
-    MVP: TLS 1.2 or 1.1 server, server sending an HelloRetryRequest message in
-    response to the MVP ClientHello, server sending a CertificateRequest
-    message ...
-
 
 Prototype upstreaming status
 ----------------------------
 
-The following summarizes which parts of the TLS 1.3 prototype remain to be
-upstreamed:
-
-- Ephemeral only handshake on client side: client authentication,
-  HelloRetryRequest support, version negotiation.
-
-- Ephemeral only handshake server side.
+The following parts of the TLS 1.3 prototype remain to be upstreamed:
 
 - Pre-shared keys, session resumption and 0-RTT data (both client and server
   side).
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index bdc32e1..c08d3f7 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -581,6 +581,14 @@
 #error "MBEDTLS_PSA_CRYPTO_SE_C defined, but not all prerequisites"
 #endif
 
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+#if defined(MBEDTLS_DEPRECATED_REMOVED)
+#error "MBEDTLS_PSA_CRYPTO_SE_C is deprecated and will be removed in a future version of Mbed TLS"
+#elif defined(MBEDTLS_DEPRECATED_WARNING)
+#warning "MBEDTLS_PSA_CRYPTO_SE_C is deprecated and will be removed in a future version of Mbed TLS"
+#endif
+#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
+
 #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) &&            \
     ! defined(MBEDTLS_PSA_CRYPTO_C)
 #error "MBEDTLS_PSA_CRYPTO_STORAGE_C defined, but not all prerequisites"
@@ -729,6 +737,13 @@
 #error "MBEDTLS_SSL_PROTO_TLS1_3 defined, but not all prerequisites"
 #endif
 
+/*
+ * The current implementation of TLS 1.3 requires MBEDTLS_SSL_KEEP_PEER_CERTIFICATE.
+ */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+#error "MBEDTLS_SSL_PROTO_TLS1_3 defined without MBEDTLS_SSL_KEEP_PEER_CERTIFICATE"
+#endif
+
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2) &&                                    \
     !(defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) ||                          \
       defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                      \
diff --git a/include/mbedtls/config_psa.h b/include/mbedtls/config_psa.h
index b469d3c..2a6672e 100644
--- a/include/mbedtls/config_psa.h
+++ b/include/mbedtls/config_psa.h
@@ -606,6 +606,10 @@
 #define PSA_WANT_ALG_GCM 1
 #endif /* MBEDTLS_GCM_C */
 
+/* Enable PSA HKDF algorithm if mbedtls HKDF is supported.
+ * PSA HKDF EXTRACT and PSA HKDF EXPAND have minimal cost when
+ * PSA HKDF is enabled, so enable both algorithms together
+ * with PSA HKDF. */
 #if defined(MBEDTLS_HKDF_C)
 #define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
 #define PSA_WANT_ALG_HMAC 1
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index 9c8ec11..37200e7 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -1184,8 +1184,9 @@
  *
  * Requires: MBEDTLS_PSA_CRYPTO_C
  *
- * \warning This interface is experimental and may change or be removed
- * without notice.
+ * \warning This interface is experimental. We intend to maintain backward
+ *          compatibility with application code that relies on drivers,
+ *          but the driver interfaces may change without notice.
  */
 //#define MBEDTLS_PSA_CRYPTO_DRIVERS
 
@@ -1444,6 +1445,8 @@
  *       still ensure that certificates do not change during renegotiation,
  *       for example by keeping a hash of the peer's certificate.
  *
+ * \note This option is required if MBEDTLS_SSL_PROTO_TLS1_3 is set.
+ *
  * Comment this macro to disable storing the peer's certificate
  * after the handshake.
  */
@@ -1502,6 +1505,8 @@
  *       See docs/architecture/tls13-support.md for a description of the TLS
  *       1.3 support that this option enables.
  *
+ * Requires: MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
+ *
  * Uncomment this macro to enable the support for TLS 1.3.
  *
  */
@@ -2686,11 +2691,11 @@
 /**
  * \def MBEDTLS_PSA_CRYPTO_SE_C
  *
- * Enable secure element support in the Platform Security Architecture
+ * Enable dynamic secure element support in the Platform Security Architecture
  * cryptography API.
  *
- * \warning This feature is not yet suitable for production. It is provided
- *          for API evaluation and testing purposes only.
+ * \deprecated This feature is deprecated. Please switch to the driver
+ *             interface enabled by #MBEDTLS_PSA_CRYPTO_DRIVERS.
  *
  * Module:  library/psa_crypto_se.c
  *
@@ -2813,9 +2818,9 @@
 /**
  * \def MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
  *
- * Enable acceleration of the SHA-256 cryptographic hash algorithm with the
- * Arm A64 cryptographic extensions if they are available at runtime. If not,
- * it will fall back to the C implementation.
+ * Enable acceleration of the SHA-256 and SHA-224 cryptographic hash algorithms
+ * with the ARMv8 cryptographic extensions if they are available at runtime.
+ * If not, the library will fall back to the C implementation.
  *
  * \note If MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT is defined when building
  * for a non-Aarch64 build it will be silently ignored.
@@ -2838,9 +2843,9 @@
 /**
  * \def MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
  *
- * Enable acceleration of the SHA-256 cryptographic hash algorithm with the
- * Arm A64 cryptographic extensions, which must be available at runtime (or
- * an illegal instruction fault will occur).
+ * Enable acceleration of the SHA-256 and SHA-224 cryptographic hash algorithms
+ * with the ARMv8 cryptographic extensions, which must be available at runtime
+ * or else an illegal instruction fault will occur.
  *
  * \note This allows builds with a smaller code size than with
  * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
@@ -2896,9 +2901,9 @@
 /**
  * \def MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
  *
- * Enable acceleration of the SHA-512 cryptographic hash algorithm with the
- * Arm A64 cryptographic extensions if they are available at runtime. If not,
- * it will fall back to the C implementation.
+ * Enable acceleration of the SHA-512 and SHA-384 cryptographic hash algorithms
+ * with the ARMv8 cryptographic extensions if they are available at runtime.
+ * If not, the library will fall back to the C implementation.
  *
  * \note If MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT is defined when building
  * for a non-Aarch64 build it will be silently ignored.
@@ -2923,9 +2928,9 @@
 /**
  * \def MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
  *
- * Enable acceleration of the SHA-512 cryptographic hash algorithm with the
- * Arm A64 cryptographic extensions, which must be available at runtime (or
- * an illegal instruction fault will occur).
+ * Enable acceleration of the SHA-512 and SHA-384 cryptographic hash algorithms
+ * with the ARMv8 cryptographic extensions, which must be available at runtime
+ * or else an illegal instruction fault will occur.
  *
  * \note This allows builds with a smaller code size than with
  * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 79d7ddd..b3b5d47 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -647,6 +647,8 @@
     MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY,
     MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED,
     MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO,
+    MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO,
+    MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REQUEST,
 }
 mbedtls_ssl_states;
 
@@ -1494,6 +1496,10 @@
 #if defined(MBEDTLS_SSL_SRV_C)
     mbedtls_ssl_hs_cb_t MBEDTLS_PRIVATE(f_cert_cb);  /*!< certificate selection callback */
 #endif /* MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+    const mbedtls_x509_crt *MBEDTLS_PRIVATE(dn_hints);/*!< acceptable client cert issuers    */
+#endif
 };
 
 struct mbedtls_ssl_context
@@ -3126,6 +3132,26 @@
                                mbedtls_x509_crt *ca_chain,
                                mbedtls_x509_crl *ca_crl );
 
+#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+/**
+ * \brief          Set DN hints sent to client in CertificateRequest message
+ *
+ * \note           If not set, subject distinguished names (DNs) are taken
+ *                 from \c mbedtls_ssl_conf_ca_chain()
+ *                 or \c mbedtls_ssl_set_hs_ca_chain())
+ *
+ * \param conf     SSL configuration
+ * \param crt      crt chain whose subject DNs are issuer DNs of client certs
+ *                 from which the client should select client peer certificate.
+ */
+static inline
+void mbedtls_ssl_conf_dn_hints( mbedtls_ssl_config *conf,
+                                const mbedtls_x509_crt *crt )
+{
+    conf->MBEDTLS_PRIVATE(dn_hints) = crt;
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
+
 #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
 /**
  * \brief          Set the trusted certificate callback.
@@ -3650,6 +3676,21 @@
                                   mbedtls_x509_crt *ca_chain,
                                   mbedtls_x509_crl *ca_crl );
 
+#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+/**
+ * \brief          Set DN hints sent to client in CertificateRequest message
+ *
+ * \note           Same as \c mbedtls_ssl_conf_dn_hints() but for use within
+ *                 the SNI callback or the certificate selection callback.
+ *
+ * \param ssl      SSL context
+ * \param crt      crt chain whose subject DNs are issuer DNs of client certs
+ *                 from which the client should select client peer certificate.
+ */
+void mbedtls_ssl_set_hs_dn_hints( mbedtls_ssl_context *ssl,
+                                  const mbedtls_x509_crt *crt );
+#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
+
 /**
  * \brief          Set authmode for the current handshake.
  *
diff --git a/include/psa/crypto_types.h b/include/psa/crypto_types.h
index 2cf965d..e619cf5 100644
--- a/include/psa/crypto_types.h
+++ b/include/psa/crypto_types.h
@@ -70,38 +70,70 @@
  */
 
 /** \brief Encoding of a key type.
+ *
+ * Values of this type are generally constructed by macros called
+ * `PSA_KEY_TYPE_xxx`.
+ *
+ * \note Values of this type are encoded in the persistent key store.
+ *       Any changes to existing values will require bumping the storage
+ *       format version and providing a translation when reading the old
+ *       format.
  */
 typedef uint16_t psa_key_type_t;
 
 /** The type of PSA elliptic curve family identifiers.
  *
+ * Values of this type are generally constructed by macros called
+ * `PSA_ECC_FAMILY_xxx`.
+ *
  * The curve identifier is required to create an ECC key using the
  * PSA_KEY_TYPE_ECC_KEY_PAIR() or PSA_KEY_TYPE_ECC_PUBLIC_KEY()
  * macros.
  *
  * Values defined by this standard will never be in the range 0x80-0xff.
  * Vendors who define additional families must use an encoding in this range.
+ *
+ * \note Values of this type are encoded in the persistent key store.
+ *       Any changes to existing values will require bumping the storage
+ *       format version and providing a translation when reading the old
+ *       format.
  */
 typedef uint8_t psa_ecc_family_t;
 
 /** The type of PSA Diffie-Hellman group family identifiers.
  *
+ * Values of this type are generally constructed by macros called
+ * `PSA_DH_FAMILY_xxx`.
+ *
  * The group identifier is required to create an Diffie-Hellman key using the
  * PSA_KEY_TYPE_DH_KEY_PAIR() or PSA_KEY_TYPE_DH_PUBLIC_KEY()
  * macros.
  *
  * Values defined by this standard will never be in the range 0x80-0xff.
  * Vendors who define additional families must use an encoding in this range.
+ *
+ * \note Values of this type are encoded in the persistent key store.
+ *       Any changes to existing values will require bumping the storage
+ *       format version and providing a translation when reading the old
+ *       format.
  */
 typedef uint8_t psa_dh_family_t;
 
 /** \brief Encoding of a cryptographic algorithm.
  *
+ * Values of this type are generally constructed by macros called
+ * `PSA_ALG_xxx`.
+ *
  * For algorithms that can be applied to multiple key types, this type
  * does not encode the key type. For example, for symmetric ciphers
  * based on a block cipher, #psa_algorithm_t encodes the block cipher
  * mode and the padding mode while the block cipher itself is encoded
  * via #psa_key_type_t.
+ *
+ * \note Values of this type are encoded in the persistent key store.
+ *       Any changes to existing values will require bumping the storage
+ *       format version and providing a translation when reading the old
+ *       format.
  */
 typedef uint32_t psa_algorithm_t;
 
@@ -143,6 +175,14 @@
  * #PSA_KEY_LIFETIME_PERSISTENT is supported if persistent storage is
  * available. Other lifetime values may be supported depending on the
  * library configuration.
+ *
+ * Values of this type are generally constructed by macros called
+ * `PSA_KEY_LIFETIME_xxx`.
+ *
+ * \note Values of this type are encoded in the persistent key store.
+ *       Any changes to existing values will require bumping the storage
+ *       format version and providing a translation when reading the old
+ *       format.
  */
 typedef uint32_t psa_key_lifetime_t;
 
@@ -174,6 +214,11 @@
  * \note Key persistence levels are 8-bit values. Key management
  *       interfaces operate on lifetimes (type ::psa_key_lifetime_t) which
  *       encode the persistence as the lower 8 bits of a 32-bit value.
+ *
+ * \note Values of this type are encoded in the persistent key store.
+ *       Any changes to existing values will require bumping the storage
+ *       format version and providing a translation when reading the old
+ *       format.
  */
 typedef uint8_t psa_key_persistence_t;
 
@@ -210,6 +255,11 @@
  * \note Key location indicators are 24-bit values. Key management
  *       interfaces operate on lifetimes (type ::psa_key_lifetime_t) which
  *       encode the location as the upper 24 bits of a 32-bit value.
+ *
+ * \note Values of this type are encoded in the persistent key store.
+ *       Any changes to existing values will require bumping the storage
+ *       format version and providing a translation when reading the old
+ *       format.
  */
 typedef uint32_t psa_key_location_t;
 
@@ -221,9 +271,27 @@
  *   #PSA_KEY_ID_VENDOR_MIN to #PSA_KEY_ID_VENDOR_MAX.
  * - 0 is reserved as an invalid key identifier.
  * - Key identifiers outside these ranges are reserved for future use.
+ *
+ * \note Values of this type are encoded in the persistent key store.
+ *       Any changes to how values are allocated must require careful
+ *       consideration to allow backward compatibility.
  */
 typedef uint32_t psa_key_id_t;
 
+/** Encoding of key identifiers as seen inside the PSA Crypto implementation.
+ *
+ * When PSA Crypto is built as a library inside an application, this type
+ * is identical to #psa_key_id_t. When PSA Crypto is built as a service
+ * that can store keys on behalf of multiple clients, this type
+ * encodes the #psa_key_id_t value seen by each client application as
+ * well as extra information that identifies the client that owns
+ * the key.
+ *
+ * \note Values of this type are encoded in the persistent key store.
+ *       Any changes to existing values will require bumping the storage
+ *       format version and providing a translation when reading the old
+ *       format.
+*/
 #if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
 typedef psa_key_id_t mbedtls_svc_key_id_t;
 
@@ -247,7 +315,16 @@
  * @{
  */
 
-/** \brief Encoding of permitted usage on a key. */
+/** \brief Encoding of permitted usage on a key.
+ *
+ * Values of this type are generally constructed as bitwise-ors of macros
+ * called `PSA_KEY_USAGE_xxx`.
+ *
+ * \note Values of this type are encoded in the persistent key store.
+ *       Any changes to existing values will require bumping the storage
+ *       format version and providing a translation when reading the old
+ *       format.
+ */
 typedef uint32_t psa_key_usage_t;
 
 /**@}*/
@@ -376,7 +453,11 @@
  * @{
  */
 
-/** \brief Encoding of the step of a key derivation. */
+/** \brief Encoding of the step of a key derivation.
+ *
+ * Values of this type are generally constructed by macros called
+ * `PSA_KEY_DERIVATION_INPUT_xxx`.
+ */
 typedef uint16_t psa_key_derivation_step_t;
 
 /**@}*/
diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h
index 17cc1a9..b3526ae 100644
--- a/include/psa/crypto_values.h
+++ b/include/psa/crypto_values.h
@@ -12,6 +12,11 @@
  * designations of cryptographic algorithms, and error codes returned by
  * the library.
  *
+ * Note that many of the constants defined in this file are embedded in
+ * the persistent key store, as part of key metadata (including usage
+ * policies). As a consequence, they must not be changed (unless the storage
+ * format version changes).
+ *
  * This header file only defines preprocessor macros.
  */
 /*
@@ -41,6 +46,18 @@
 
 /* PSA error codes */
 
+/* Error codes are standardized across PSA domains (framework, crypto, storage,
+ * etc.). Do not change the values in this section or even the expansions
+ * of each macro: it must be possible to `#include` both this header
+ * and some other PSA component's headers in the same C source,
+ * which will lead to duplicate definitions of the `PSA_SUCCESS` and
+ * `PSA_ERROR_xxx` macros, which is ok if and only if the macros expand
+ * to the same sequence of tokens.
+ *
+ * If you must add a new
+ * value, check with the Arm PSA framework group to pick one that other
+ * domains aren't already using. */
+
 /** The action was completed successfully. */
 #define PSA_SUCCESS ((psa_status_t)0)
 
@@ -317,6 +334,12 @@
  * @{
  */
 
+/* Note that key type values, including ECC family and DH group values, are
+ * embedded in the persistent key store, as part of key metadata. As a
+ * consequence, they must not be changed (unless the storage format version
+ * changes).
+ */
+
 /** An invalid key type value.
  *
  * Zero is not the encoding of any key type.
@@ -719,6 +742,11 @@
      1u << PSA_GET_KEY_TYPE_BLOCK_SIZE_EXPONENT(type) :                         \
      0u)
 
+/* Note that algorithm values are embedded in the persistent key store,
+ * as part of key metadata. As a consequence, they must not be changed
+ * (unless the storage format version changes).
+ */
+
 /** Vendor-defined algorithm flag.
  *
  * Algorithms defined by this standard will never have the #PSA_ALG_VENDOR_FLAG
@@ -2207,6 +2235,11 @@
  * @{
  */
 
+/* Note that location and persistence level values are embedded in the
+ * persistent key store, as part of key metadata. As a consequence, they
+ * must not be changed (unless the storage format version changes).
+ */
+
 /** The default lifetime for volatile keys.
  *
  * A volatile key only exists as long as the identifier to it is not destroyed.
@@ -2322,6 +2355,11 @@
 
 #define PSA_KEY_LOCATION_VENDOR_FLAG            ((psa_key_location_t)0x800000)
 
+/* Note that key identifier values are embedded in the
+ * persistent key store, as part of key metadata. As a consequence, they
+ * must not be changed (unless the storage format version changes).
+ */
+
 /** The null key identifier.
  */
 #define PSA_KEY_ID_NULL                         ((psa_key_id_t)0)
@@ -2433,6 +2471,11 @@
  * @{
  */
 
+/* Note that key usage flags are embedded in the
+ * persistent key store, as part of key metadata. As a consequence, they
+ * must not be changed (unless the storage format version changes).
+ */
+
 /** Whether the key may be exported.
  *
  * A public key or the public part of a key pair may always be exported
@@ -2559,6 +2602,9 @@
  * @{
  */
 
+/* Key input steps are not embedded in the persistent storage, so you can
+ * change them if needed: it's only an ABI change. */
+
 /** A secret input for key derivation.
  *
  * This should be a key of type #PSA_KEY_TYPE_DERIVE
diff --git a/library/asn1write.c b/library/asn1write.c
index 2110052..053dbb6 100644
--- a/library/asn1write.c
+++ b/library/asn1write.c
@@ -133,6 +133,11 @@
     //
     len = mbedtls_mpi_size( X );
 
+    /* DER represents 0 with a sign bit (0=nonnegative) and 7 value bits, not
+     * as 0 digits. We need to end up with 020100, not with 0200. */
+    if( len == 0 )
+        len = 1;
+
     if( *p < start || (size_t)( *p - start ) < len )
         return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
 
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 119826f..bd8c14d 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -850,6 +850,9 @@
 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
     const unsigned char *sni_name;      /*!< raw SNI                        */
     size_t sni_name_len;                /*!< raw SNI len                    */
+#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+    const mbedtls_x509_crt *dn_hints;   /*!< acceptable client cert issuers */
+#endif
 #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
 };
 
@@ -1922,8 +1925,12 @@
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
 
 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
-    if( ssl->handshake != NULL && ssl->handshake->sig_algs != NULL )
+    if( ssl->handshake != NULL &&
+        ssl->handshake->sig_algs_heap_allocated == 1 &&
+        ssl->handshake->sig_algs != NULL )
+    {
         return( ssl->handshake->sig_algs );
+    }
 #endif
     return( ssl->conf->sig_algs );
 
@@ -1969,97 +1976,177 @@
     return( 0 );
 }
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
 static inline int mbedtls_ssl_tls13_get_pk_type_and_md_alg_from_sig_alg(
     uint16_t sig_alg, mbedtls_pk_type_t *pk_type, mbedtls_md_type_t *md_alg )
 {
-    *pk_type = MBEDTLS_PK_NONE;
-    *md_alg = MBEDTLS_MD_NONE;
+    *pk_type = mbedtls_ssl_pk_alg_from_sig( sig_alg & 0xff );
+    *md_alg = mbedtls_ssl_md_alg_from_hash( ( sig_alg >> 8 ) & 0xff );
+
+    if( *pk_type != MBEDTLS_PK_NONE && *md_alg != MBEDTLS_MD_NONE )
+        return( 0 );
 
     switch( sig_alg )
     {
-#if defined(MBEDTLS_ECDSA_C)
-
-#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
-        case MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256:
-            *md_alg = MBEDTLS_MD_SHA256;
-            *pk_type = MBEDTLS_PK_ECDSA;
-            break;
-#endif /* MBEDTLS_SHA256_C && MBEDTLS_ECP_DP_SECP256R1_ENABLED */
-
-#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
-        case MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384:
-            *md_alg = MBEDTLS_MD_SHA384;
-            *pk_type = MBEDTLS_PK_ECDSA;
-            break;
-#endif /* MBEDTLS_SHA384_C && MBEDTLS_ECP_DP_SECP384R1_ENABLED */
-
-#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
-        case MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512:
-            *md_alg = MBEDTLS_MD_SHA512;
-            *pk_type = MBEDTLS_PK_ECDSA;
-            break;
-#endif /* MBEDTLS_SHA512_C && MBEDTLS_ECP_DP_SECP521R1_ENABLED */
-
-#endif /* MBEDTLS_ECDSA_C */
-
-#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
-
+#if defined(MBEDTLS_PKCS1_V21)
 #if defined(MBEDTLS_SHA256_C)
         case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:
             *md_alg = MBEDTLS_MD_SHA256;
             *pk_type = MBEDTLS_PK_RSASSA_PSS;
             break;
 #endif /* MBEDTLS_SHA256_C  */
-
 #if defined(MBEDTLS_SHA384_C)
         case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384:
             *md_alg = MBEDTLS_MD_SHA384;
             *pk_type = MBEDTLS_PK_RSASSA_PSS;
             break;
 #endif /* MBEDTLS_SHA384_C */
-
 #if defined(MBEDTLS_SHA512_C)
         case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512:
             *md_alg = MBEDTLS_MD_SHA512;
             *pk_type = MBEDTLS_PK_RSASSA_PSS;
             break;
 #endif /* MBEDTLS_SHA512_C */
-
-#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
-
-#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C)
-
-#if defined(MBEDTLS_SHA256_C)
-        case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256:
-            *md_alg = MBEDTLS_MD_SHA256;
-            *pk_type = MBEDTLS_PK_RSA;
-            break;
-#endif /* MBEDTLS_SHA256_C */
-
-#if defined(MBEDTLS_SHA384_C)
-        case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384:
-            *md_alg = MBEDTLS_MD_SHA384;
-            *pk_type = MBEDTLS_PK_RSA;
-            break;
-#endif /* MBEDTLS_SHA384_C */
-
-#if defined(MBEDTLS_SHA512_C)
-        case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512:
-            *md_alg = MBEDTLS_MD_SHA512;
-            *pk_type = MBEDTLS_PK_RSA;
-            break;
-#endif /* MBEDTLS_SHA512_C */
-
-#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C */
-
+#endif /* MBEDTLS_PKCS1_V21 */
             default:
                 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
         }
         return( 0 );
 }
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+static inline int mbedtls_ssl_tls13_sig_alg_for_cert_verify_is_supported(
+                                                    const uint16_t sig_alg )
+{
+    switch( sig_alg )
+    {
+#if defined(MBEDTLS_ECDSA_C)
+#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+        case MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256:
+            break;
+#endif /* MBEDTLS_SHA256_C && MBEDTLS_ECP_DP_SECP256R1_ENABLED */
+#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+        case MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384:
+            break;
+#endif /* MBEDTLS_SHA384_C && MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
+        case MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512:
+            break;
+#endif /* MBEDTLS_SHA512_C && MBEDTLS_ECP_DP_SECP521R1_ENABLED */
+#endif /* MBEDTLS_ECDSA_C */
+
+#if defined(MBEDTLS_PKCS1_V21)
+#if defined(MBEDTLS_SHA256_C)
+        case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:
+            break;
+#endif /* MBEDTLS_SHA256_C  */
+#if defined(MBEDTLS_SHA384_C)
+        case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384:
+            break;
+#endif /* MBEDTLS_SHA384_C */
+#if defined(MBEDTLS_SHA512_C)
+        case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512:
+            break;
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_PKCS1_V21 */
+        default:
+            return( 0 );
+    }
+    return( 1 );
+
+}
+
+static inline int mbedtls_ssl_tls13_sig_alg_is_supported(
+                                                    const uint16_t sig_alg )
+{
+    switch( sig_alg )
+    {
+#if defined(MBEDTLS_PKCS1_V15)
+#if defined(MBEDTLS_SHA256_C)
+        case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256:
+            break;
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA384_C)
+        case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384:
+            break;
+#endif /* MBEDTLS_SHA384_C */
+#if defined(MBEDTLS_SHA512_C)
+        case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512:
+            break;
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_PKCS1_V15 */
+        default:
+            return( mbedtls_ssl_tls13_sig_alg_for_cert_verify_is_supported(
+                                                                    sig_alg ) );
+    }
+    return( 1 );
+}
+
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+static inline int mbedtls_ssl_tls12_sig_alg_is_supported(
+                                                    const uint16_t sig_alg )
+{
+    /* High byte is hash */
+    unsigned char hash = MBEDTLS_BYTE_1( sig_alg );
+    unsigned char sig = MBEDTLS_BYTE_0( sig_alg );
+
+    switch( hash )
+    {
+#if defined(MBEDTLS_MD5_C)
+        case MBEDTLS_SSL_HASH_MD5:
+            break;
+#endif
+
+#if defined(MBEDTLS_SHA1_C)
+        case MBEDTLS_SSL_HASH_SHA1:
+            break;
+#endif
+
+#if defined(MBEDTLS_SHA224_C)
+        case MBEDTLS_SSL_HASH_SHA224:
+            break;
+#endif
+
+#if defined(MBEDTLS_SHA256_C)
+        case MBEDTLS_SSL_HASH_SHA256:
+            break;
+#endif
+
+#if defined(MBEDTLS_SHA384_C)
+        case MBEDTLS_SSL_HASH_SHA384:
+            break;
+#endif
+
+#if defined(MBEDTLS_SHA512_C)
+        case MBEDTLS_SSL_HASH_SHA512:
+            break;
+#endif
+
+        default:
+            return( 0 );
+    }
+
+    switch( sig )
+    {
+#if defined(MBEDTLS_RSA_C)
+        case MBEDTLS_SSL_SIG_RSA:
+            break;
+#endif
+
+#if defined(MBEDTLS_ECDSA_C)
+        case MBEDTLS_SSL_SIG_ECDSA:
+            break;
+#endif
+
+    default:
+        return( 0 );
+    }
+
+    return( 1 );
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
 static inline int mbedtls_ssl_sig_alg_is_supported(
                                                 const mbedtls_ssl_context *ssl,
                                                 const uint16_t sig_alg )
@@ -2068,79 +2155,28 @@
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
     if( ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2 )
     {
-        /* High byte is hash */
-        unsigned char hash = MBEDTLS_BYTE_1( sig_alg );
-        unsigned char sig = MBEDTLS_BYTE_0( sig_alg );
-
-        switch( hash )
-        {
-#if defined(MBEDTLS_MD5_C)
-            case MBEDTLS_SSL_HASH_MD5:
-                break;
-#endif
-
-#if defined(MBEDTLS_SHA1_C)
-            case MBEDTLS_SSL_HASH_SHA1:
-                break;
-#endif
-
-#if defined(MBEDTLS_SHA224_C)
-            case MBEDTLS_SSL_HASH_SHA224:
-                break;
-#endif
-
-#if defined(MBEDTLS_SHA256_C)
-            case MBEDTLS_SSL_HASH_SHA256:
-                break;
-#endif
-
-#if defined(MBEDTLS_SHA384_C)
-            case MBEDTLS_SSL_HASH_SHA384:
-                break;
-#endif
-
-#if defined(MBEDTLS_SHA512_C)
-            case MBEDTLS_SSL_HASH_SHA512:
-                break;
-#endif
-
-            default:
-                return( 0 );
-        }
-
-        switch( sig )
-        {
-#if defined(MBEDTLS_RSA_C)
-            case MBEDTLS_SSL_SIG_RSA:
-                break;
-#endif
-
-#if defined(MBEDTLS_ECDSA_C)
-            case MBEDTLS_SSL_SIG_ECDSA:
-                break;
-#endif
-
-        default:
-            return( 0 );
-        }
-
-        return( 1 );
+        return( mbedtls_ssl_tls12_sig_alg_is_supported( sig_alg ) );
     }
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
     if( ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 )
     {
-        mbedtls_pk_type_t pk_type;
-        mbedtls_md_type_t md_alg;
-        return( ! mbedtls_ssl_tls13_get_pk_type_and_md_alg_from_sig_alg(
-                                                sig_alg, &pk_type, &md_alg ) );
+       return( mbedtls_ssl_tls13_sig_alg_is_supported( sig_alg ) );
     }
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
     ((void) ssl);
     ((void) sig_alg);
     return( 0 );
 }
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+
+int mbedtls_ssl_tls13_check_sig_alg_cert_key_match( uint16_t sig_alg,
+                                                    mbedtls_pk_context *key );
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
@@ -2276,10 +2312,6 @@
                                        const unsigned char *end );
 #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
 
-int mbedtls_ssl_tls13_get_sig_alg_from_pk( mbedtls_ssl_context *ssl,
-                                           mbedtls_pk_context *own_key,
-                                           uint16_t *algorithm );
-
 #if defined(MBEDTLS_SSL_ALPN)
 int mbedtls_ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
                                 const unsigned char *buf,
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index 4c9a177..d0b8a64 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -2720,7 +2720,7 @@
             if( ++ssl->cur_out_ctr[i - 1] != 0 )
                 break;
 
-        /* The loop goes to its end iff the counter is wrapping */
+        /* The loop goes to its end if the counter is wrapping */
         if( i == mbedtls_ssl_ep_len( ssl ) )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 0abf2b9..d3bb291 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -853,10 +853,9 @@
     else
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
     {
-        ssl->handshake->sig_algs = ssl->conf->sig_algs;
         ssl->handshake->sig_algs_heap_allocated = 0;
     }
-#endif /* MBEDTLS_DEPRECATED_REMOVED */
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
     return( 0 );
 }
@@ -1472,6 +1471,14 @@
     ssl->handshake->sni_ca_crl     = ca_crl;
 }
 
+#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+void mbedtls_ssl_set_hs_dn_hints( mbedtls_ssl_context *ssl,
+                                  const mbedtls_x509_crt *crt)
+{
+    ssl->handshake->dn_hints = crt;
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
+
 void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl,
                                   int authmode )
 {
@@ -4019,28 +4026,6 @@
     memset( conf, 0, sizeof( mbedtls_ssl_config ) );
 }
 
-#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-/* The selection should be the same as mbedtls_x509_crt_profile_default in
- * x509_crt.c. Here, the order matters. Currently we favor stronger hashes,
- * for no fundamental reason.
- * See the documentation of mbedtls_ssl_conf_curves() for what we promise
- * about this list. */
-static int ssl_preset_default_hashes[] = {
-#if defined(MBEDTLS_SHA512_C)
-    MBEDTLS_MD_SHA512,
-#endif
-#if defined(MBEDTLS_SHA384_C)
-    MBEDTLS_MD_SHA384,
-#endif
-#if defined(MBEDTLS_SHA256_C)
-    MBEDTLS_MD_SHA256,
-#endif
-    MBEDTLS_MD_NONE
-};
-#endif /* !MBEDTLS_DEPRECATED_REMOVED */
-#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
-
 /* The selection should be the same as mbedtls_x509_crt_profile_default in
  * x509_crt.c, plus Montgomery curves for ECDHE. Here, the order matters:
  * curves with a lower resource usage come first.
@@ -4082,17 +4067,6 @@
 };
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-static int ssl_preset_suiteb_hashes[] = {
-#if defined(MBEDTLS_SHA256_C)
-    MBEDTLS_MD_SHA256,
-#endif
-#if defined(MBEDTLS_SHA384_C)
-    MBEDTLS_MD_SHA384,
-#endif
-    MBEDTLS_MD_NONE
-};
-#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
 /* NOTICE:
  *   For ssl_preset_*_sig_algs and ssl_tls12_preset_*_sig_algs, the following
@@ -4101,6 +4075,13 @@
  *   - But if there is a good reason, do not change the order of the algorithms.
  *   - ssl_tls12_present* is for TLS 1.2 use only.
  *   - ssl_preset_* is for TLS 1.3 only or hybrid TLS 1.3/1.2 handshakes.
+ *
+ *   When GnuTLS/Openssl server is configured in TLS 1.2 mode with a certificate
+ *   declaring an RSA public key and Mbed TLS is configured in hybrid mode, if
+ *   `rsa_pss_rsae_*` algorithms are before `rsa_pkcs1_*` ones in this list then
+ *   the GnuTLS/Openssl server chooses an `rsa_pss_rsae_*` signature algorithm
+ *   for its signature in the key exchange message. As Mbed TLS 1.2 does not
+ *   support them, the handshake fails.
  */
 static uint16_t ssl_preset_default_sig_algs[] = {
 
@@ -4122,10 +4103,6 @@
 #endif /* MBEDTLS_ECDSA_C && MBEDTLS_SHA384_C &&
           MBEDTLS_ECP_DP_SECP521R1_ENABLED */
 
-#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && defined(MBEDTLS_SHA256_C)
-    MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256,
-#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT && MBEDTLS_SHA256_C */
-
 #if defined(MBEDTLS_RSA_C) &&  defined(MBEDTLS_SHA512_C)
     MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512,
 #endif /* MBEDTLS_RSA_C && MBEDTLS_SHA512_C */
@@ -4138,6 +4115,18 @@
     MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256,
 #endif /* MBEDTLS_RSA_C && MBEDTLS_SHA256_C */
 
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && defined(MBEDTLS_SHA512_C)
+    MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512,
+#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT && MBEDTLS_SHA512_C */
+
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && defined(MBEDTLS_SHA384_C)
+    MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384,
+#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT && MBEDTLS_SHA384_C */
+
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && defined(MBEDTLS_SHA256_C)
+    MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256,
+#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT && MBEDTLS_SHA256_C */
+
     MBEDTLS_TLS_SIG_NONE
 };
 
@@ -4421,9 +4410,6 @@
 #endif
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-            conf->sig_hashes = ssl_preset_suiteb_hashes;
-#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
             if( mbedtls_ssl_conf_is_tls12_only( conf ) )
                 conf->sig_algs = ssl_tls12_preset_suiteb_sig_algs;
@@ -4450,9 +4436,6 @@
 #endif
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-            conf->sig_hashes = ssl_preset_default_hashes;
-#endif /* !MBEDTLS_DEPRECATED_REMOVED */
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
             if( mbedtls_ssl_conf_is_tls12_only( conf ) )
                 conf->sig_algs = ssl_tls12_preset_default_sig_algs;
@@ -4937,13 +4920,20 @@
         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 ) )
+        MBEDTLS_SSL_DEBUG_MSG( 4, ( "received signature algorithm: 0x%x %s",
+                                    sig_alg,
+                                    mbedtls_ssl_sig_alg_to_str( sig_alg ) ) );
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        if( ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2 &&
+            ( ! ( mbedtls_ssl_sig_alg_is_supported( ssl, sig_alg ) &&
+                  mbedtls_ssl_sig_alg_is_offered( ssl, sig_alg ) ) ) )
+        {
             continue;
+        }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+        MBEDTLS_SSL_DEBUG_MSG( 4, ( "valid signature algorithm: %s",
+                                    mbedtls_ssl_sig_alg_to_str( sig_alg ) ) );
 
         if( common_idx + 1 < MBEDTLS_RECEIVED_SIG_ALGS_SIZE )
         {
@@ -8209,12 +8199,17 @@
 
     for( ; *sig_alg != MBEDTLS_TLS1_3_SIG_NONE; sig_alg++ )
     {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "got signature scheme [%x] %s",
+                                    *sig_alg,
+                                    mbedtls_ssl_sig_alg_to_str( *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 ) );
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "sent signature scheme [%x] %s",
+                                    *sig_alg,
+                                    mbedtls_ssl_sig_alg_to_str( *sig_alg ) ) );
     }
 
     /* Length of supported_signature_algorithms */
diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c
index f516efa..35f11ea 100644
--- a/library/ssl_tls12_client.c
+++ b/library/ssl_tls12_client.c
@@ -2534,6 +2534,7 @@
     size_t sig_alg_len;
 #if defined(MBEDTLS_DEBUG_C)
         unsigned char *sig_alg;
+        unsigned char *dn;
 #endif
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
@@ -2681,6 +2682,43 @@
         return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
+#if defined(MBEDTLS_DEBUG_C)
+    dn = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n - dn_len;
+    for( size_t i = 0, dni_len = 0; i < dn_len; i += 2 + dni_len )
+    {
+        unsigned char *p = dn + i + 2;
+        mbedtls_x509_name name;
+        mbedtls_x509_name *name_cur, *name_prv;
+        size_t asn1_len;
+        char s[MBEDTLS_X509_MAX_DN_NAME_SIZE];
+        memset( &name, 0, sizeof( name ) );
+        dni_len = MBEDTLS_GET_UINT16_BE( dn + i, 0 );
+        if( dni_len > dn_len - i - 2 ||
+            mbedtls_asn1_get_tag( &p, p + dni_len, &asn1_len,
+              MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) != 0 ||
+            mbedtls_x509_get_name( &p, p + asn1_len, &name ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
+            mbedtls_ssl_send_alert_message(
+                ssl,
+                MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
+        }
+        MBEDTLS_SSL_DEBUG_MSG( 3,
+            ( "DN hint: %.*s",
+              mbedtls_x509_dn_gets( s, sizeof(s), &name ), s ) );
+        name_cur = name.next;
+        while( name_cur != NULL )
+        {
+            name_prv = name_cur;
+            name_cur = name_cur->next;
+            mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
+            mbedtls_free( name_prv );
+        }
+    }
+#endif
+
 exit:
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) );
 
diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c
index 7258230..4ab3db5 100644
--- a/library/ssl_tls12_server.c
+++ b/library/ssl_tls12_server.c
@@ -2511,6 +2511,16 @@
          *       `mbedtls_ssl_conf_ca_cb()`, then the
          *       CertificateRequest is currently left empty. */
 
+#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+        if( ssl->handshake->dn_hints != NULL )
+            crt = ssl->handshake->dn_hints;
+        else
+#endif
+        if( ssl->conf->dn_hints != NULL )
+            crt = ssl->conf->dn_hints;
+        else
+#endif
 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
         if( ssl->handshake->sni_ca_chain != NULL )
             crt = ssl->handshake->sni_ca_chain;
diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c
index 893de43..8ec9f90 100644
--- a/library/ssl_tls13_generic.c
+++ b/library/ssl_tls13_generic.c
@@ -256,13 +256,9 @@
 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
     if( sig_alg == MBEDTLS_PK_RSASSA_PSS )
     {
-        const mbedtls_md_info_t* md_info;
         rsassa_pss_options.mgf1_hash_id = md_alg;
-        if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
-        {
-            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-        }
-        rsassa_pss_options.expected_salt_len = mbedtls_md_get_size( md_info );
+
+        rsassa_pss_options.expected_salt_len = PSA_HASH_LENGTH( hash_alg );
         options = (const void*) &rsassa_pss_options;
     }
 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
@@ -854,120 +850,84 @@
 /*
  * STATE HANDLING: Output Certificate Verify
  */
-int mbedtls_ssl_tls13_get_sig_alg_from_pk( mbedtls_ssl_context *ssl,
-                                           mbedtls_pk_context *own_key,
-                                           uint16_t *algorithm )
-{
-    mbedtls_pk_type_t sig = mbedtls_ssl_sig_from_pk( own_key );
-    /* Determine the size of the key */
-    size_t own_key_size = mbedtls_pk_get_bitlen( own_key );
-    *algorithm = MBEDTLS_TLS1_3_SIG_NONE;
-    ((void) own_key_size);
 
-    switch( sig )
+int mbedtls_ssl_tls13_check_sig_alg_cert_key_match( uint16_t sig_alg,
+                                                    mbedtls_pk_context *key )
+{
+    mbedtls_pk_type_t pk_type = mbedtls_ssl_sig_from_pk( key );
+    size_t key_size = mbedtls_pk_get_bitlen( key );
+
+    switch( pk_type )
     {
-#if defined(MBEDTLS_ECDSA_C)
         case MBEDTLS_SSL_SIG_ECDSA:
-            switch( own_key_size )
+            switch( key_size )
             {
                 case 256:
-                    *algorithm = MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256;
-                    return( 0 );
+                    return(
+                        sig_alg == MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256 );
+
                 case 384:
-                    *algorithm = MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384;
-                    return( 0 );
+                    return(
+                        sig_alg == MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384 );
+
                 case 521:
-                    *algorithm = MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512;
-                    return( 0 );
+                    return(
+                        sig_alg == MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512 );
                 default:
-                    MBEDTLS_SSL_DEBUG_MSG( 3,
-                                           ( "unknown key size: %"
-                                             MBEDTLS_PRINTF_SIZET " bits",
-                                             own_key_size ) );
                     break;
             }
             break;
-#endif /* MBEDTLS_ECDSA_C */
 
-#if defined(MBEDTLS_RSA_C)
         case MBEDTLS_SSL_SIG_RSA:
-#if defined(MBEDTLS_PKCS1_V21)
-#if defined(MBEDTLS_SHA256_C)
-            if( own_key_size <= 2048 &&
-                mbedtls_ssl_sig_alg_is_received( ssl,
-                                    MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256 ) )
+            switch( sig_alg )
             {
-                *algorithm = MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256;
-                return( 0 );
-            }
-            else
-#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA384_C)
-            if( own_key_size <= 3072 &&
-                mbedtls_ssl_sig_alg_is_received( ssl,
-                                    MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384 ) )
-            {
-                *algorithm = MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384;
-                return( 0 );
-            }
-            else
-#endif /* MBEDTLS_SHA384_C */
-#if defined(MBEDTLS_SHA512_C)
-            if( own_key_size <= 4096 &&
-                mbedtls_ssl_sig_alg_is_received( ssl,
-                                    MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512 ) )
-            {
-                *algorithm = MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512;
-                return( 0 );
-            }
-            else
-#endif /* MBEDTLS_SHA512_C */
-#endif /* MBEDTLS_PKCS1_V21 */
-#if defined(MBEDTLS_PKCS1_V15)
-#if defined(MBEDTLS_SHA256_C)
-            if( own_key_size <= 2048 &&
-                mbedtls_ssl_sig_alg_is_received( ssl,
-                                    MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256 ) )
-            {
-                *algorithm = MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256;
-                return( 0 );
-            }
-            else
-#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA384_C)
-            if( own_key_size <= 3072 &&
-                mbedtls_ssl_sig_alg_is_received( ssl,
-                                    MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384 ) )
-            {
-                *algorithm = MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384;
-                return( 0 );
-            }
-            else
-#endif /* MBEDTLS_SHA384_C */
-#if defined(MBEDTLS_SHA512_C)
-            if( own_key_size <= 4096 &&
-                mbedtls_ssl_sig_alg_is_received( ssl,
-                                    MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512 ) )
-            {
-                *algorithm = MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512;
-                return( 0 );
-            }
-            else
-#endif /* MBEDTLS_SHA512_C */
-#endif /* MBEDTLS_PKCS1_V15 */
-            {
-                MBEDTLS_SSL_DEBUG_MSG( 3,
-                                       ( "unknown key size: %"
-                                         MBEDTLS_PRINTF_SIZET " bits",
-                                         own_key_size ) );
+                case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:
+                    return( key_size <= 3072 );
+
+                case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384:
+                    return( key_size <= 7680 );
+
+                case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512:
+                    return( 1 );
+
+                default:
+                    break;
             }
             break;
-#endif /* MBEDTLS_RSA_C */
+
         default:
-            MBEDTLS_SSL_DEBUG_MSG( 1,
-                                   ( "unknown signature type : %u", sig ) );
             break;
     }
+
+    return( 0 );
+}
+
+static int ssl_tls13_select_sig_alg_for_certificate_verify(
+                                          mbedtls_ssl_context *ssl,
+                                          mbedtls_pk_context *own_key,
+                                          uint16_t *algorithm )
+{
+    uint16_t *sig_alg = ssl->handshake->received_sig_algs;
+
+    *algorithm = MBEDTLS_TLS1_3_SIG_NONE;
+    for( ; *sig_alg != MBEDTLS_TLS1_3_SIG_NONE ; sig_alg++ )
+    {
+        if( mbedtls_ssl_sig_alg_is_offered( ssl, *sig_alg ) &&
+            mbedtls_ssl_tls13_sig_alg_for_cert_verify_is_supported( *sig_alg ) &&
+            mbedtls_ssl_tls13_check_sig_alg_cert_key_match( *sig_alg, own_key ) )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3,
+                                   ( "select_sig_alg_for_certificate_verify:"
+                                     "selected signature algorithm %s [%04x]",
+                                     mbedtls_ssl_sig_alg_to_str( *sig_alg ),
+                                     *sig_alg ) );
+            *algorithm = *sig_alg;
+            return( 0 );
+        }
+    }
+    MBEDTLS_SSL_DEBUG_MSG( 2,
+                           ( "select_sig_alg_for_certificate_verify:"
+                             "no suitable signature algorithm found" ) );
     return( -1 );
 }
 
@@ -1024,8 +984,9 @@
      *    opaque signature<0..2^16-1>;
      *  } CertificateVerify;
      */
-    ret = mbedtls_ssl_tls13_get_sig_alg_from_pk( ssl, own_key, &algorithm );
-    if( ret != 0 || ! mbedtls_ssl_sig_alg_is_received( ssl, algorithm ) )
+    ret = ssl_tls13_select_sig_alg_for_certificate_verify( ssl, own_key,
+                                                           &algorithm );
+    if( ret != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1,
                     ( "signature algorithm not in received or offered list." ) );
@@ -1038,6 +999,9 @@
         return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "CertificateVerify with %s",
+                                mbedtls_ssl_sig_alg_to_str( algorithm )) );
+
     if( mbedtls_ssl_tls13_get_pk_type_and_md_alg_from_sig_alg(
                                         algorithm, &pk_type, &md_alg ) != 0 )
     {
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index bfb2204..144c70d 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -352,7 +352,6 @@
 {
     mbedtls_ssl_key_cert *key_cert, *key_cert_list;
     const uint16_t *sig_alg = ssl->handshake->received_sig_algs;
-    uint16_t key_sig_alg;
 
 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
     if( ssl->handshake->sni_key_cert != NULL )
@@ -372,7 +371,6 @@
         for( key_cert = key_cert_list; key_cert != NULL;
              key_cert = key_cert->next )
         {
-            int ret;
             MBEDTLS_SSL_DEBUG_CRT( 3, "certificate (chain) candidate",
                                    key_cert->cert );
 
@@ -391,13 +389,21 @@
                 continue;
             }
 
-            ret = mbedtls_ssl_tls13_get_sig_alg_from_pk(
-                    ssl, &key_cert->cert->pk, &key_sig_alg );
-            if( ret != 0 )
-                continue;
-            if( *sig_alg == key_sig_alg )
+            MBEDTLS_SSL_DEBUG_MSG( 3,
+                                   ( "ssl_tls13_pick_key_cert:"
+                                     "check signature algorithm %s [%04x]",
+                                     mbedtls_ssl_sig_alg_to_str( *sig_alg ),
+                                     *sig_alg ) );
+            if( mbedtls_ssl_tls13_check_sig_alg_cert_key_match(
+                                            *sig_alg, &key_cert->cert->pk ) )
             {
                 ssl->handshake->key_cert = key_cert;
+                MBEDTLS_SSL_DEBUG_MSG( 3,
+                                       ( "ssl_tls13_pick_key_cert:"
+                                         "selected signature algorithm"
+                                         " %s [%04x]",
+                                         mbedtls_ssl_sig_alg_to_str( *sig_alg ),
+                                         *sig_alg ) );
                 MBEDTLS_SSL_DEBUG_CRT(
                         3, "selected certificate (chain)",
                         ssl->handshake->key_cert->cert );
@@ -406,6 +412,8 @@
         }
     }
 
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "ssl_tls13_pick_key_cert:"
+                                "no suitable certificate found" ) );
     return( -1 );
 }
 #endif /* MBEDTLS_X509_CRT_PARSE_C &&
@@ -1261,11 +1269,6 @@
         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 );
 }
 
@@ -1295,7 +1298,16 @@
 
     MBEDTLS_SSL_PROC_CHK( ssl_tls13_finalize_write_server_hello( ssl ) );
 
+#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
+    /* The server sends a dummy change_cipher_spec record immediately
+     * after its first handshake message. This may either be after
+     * a ServerHello or a HelloRetryRequest.
+     */
+    mbedtls_ssl_handshake_set_state(
+            ssl, MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO );
+#else
     mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS );
+#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
 
 cleanup:
 
@@ -1360,7 +1372,16 @@
 
     ssl->handshake->hello_retry_request_count++;
 
+#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
+    /* The server sends a dummy change_cipher_spec record immediately
+     * after its first handshake message. This may either be after
+     * a ServerHello or a HelloRetryRequest.
+     */
+    mbedtls_ssl_handshake_set_state(
+            ssl, MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REQUEST );
+#else
     mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_HELLO );
+#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
 
 cleanup:
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello retry request" ) );
@@ -1421,6 +1442,11 @@
     unsigned char *buf;
     size_t buf_len, msg_len;
 
+    mbedtls_ssl_set_outbound_transform( ssl,
+                                        ssl->handshake->transform_handshake );
+    MBEDTLS_SSL_DEBUG_MSG(
+        3, ( "switching to handshake transform for outbound data" ) );
+
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write encrypted extensions" ) );
 
     MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_start_handshake_msg( ssl,
@@ -1748,6 +1774,23 @@
             break;
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
+        /*
+         * Injection of dummy-CCS's for middlebox compatibility
+         */
+#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
+        case MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REQUEST:
+            ret = mbedtls_ssl_tls13_write_change_cipher_spec( ssl );
+            if( ret == 0 )
+                mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_HELLO );
+            break;
+
+        case MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO:
+            ret = mbedtls_ssl_tls13_write_change_cipher_spec( ssl );
+            if( ret == 0 )
+                mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS );
+            break;
+#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
+
         case MBEDTLS_SSL_SERVER_FINISHED:
             ret = ssl_tls13_write_server_finished( ssl );
             break;
diff --git a/library/x509.c b/library/x509.c
index 2e11c7f..249034b 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -131,6 +131,48 @@
     return( 0 );
 }
 
+/*
+ * Convert md type to string
+ */
+static inline const char* md_type_to_string( mbedtls_md_type_t md_alg )
+{
+    switch( md_alg )
+    {
+#if defined(MBEDTLS_MD5_C)
+    case MBEDTLS_MD_MD5:
+        return( "MD5" );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+    case MBEDTLS_MD_SHA1:
+        return( "SHA1" );
+#endif
+#if defined(MBEDTLS_SHA224_C)
+    case MBEDTLS_MD_SHA224:
+        return( "SHA224" );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+    case MBEDTLS_MD_SHA256:
+        return( "SHA256" );
+#endif
+#if defined(MBEDTLS_SHA384_C)
+    case MBEDTLS_MD_SHA384:
+        return( "SHA384" );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+    case MBEDTLS_MD_SHA512:
+        return( "SHA512" );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+    case MBEDTLS_MD_RIPEMD160:
+        return( "RIPEMD160" );
+#endif
+    case MBEDTLS_MD_NONE:
+        return( NULL );
+    default:
+        return( NULL );
+    }
+}
+
 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
 /*
  * HashAlgorithm ::= AlgorithmIdentifier
@@ -741,7 +783,7 @@
 int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t i, n;
+    size_t i, j, n;
     unsigned char c, merge = 0;
     const mbedtls_x509_name *name;
     const char *short_name = NULL;
@@ -775,17 +817,24 @@
             ret = mbedtls_snprintf( p, n, "\?\?=" );
         MBEDTLS_X509_SAFE_SNPRINTF;
 
-        for( i = 0; i < name->val.len; i++ )
+        for( i = 0, j = 0; i < name->val.len; i++, j++ )
         {
-            if( i >= sizeof( s ) - 1 )
-                break;
+            if( j >= sizeof( s ) - 1 )
+                return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
 
             c = name->val.p[i];
+            // Special characters requiring escaping, RFC 1779
+            if( c && strchr( ",=+<>#;\"\\", c ) )
+            {
+                if( j + 1 >= sizeof( s ) - 1 )
+                    return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
+                s[j++] = '\\';
+            }
             if( c < 32 || c >= 127 )
-                 s[i] = '?';
-            else s[i] = c;
+                 s[j] = '?';
+            else s[j] = c;
         }
-        s[i] = '\0';
+        s[j] = '\0';
         ret = mbedtls_snprintf( p, n, "%s", s );
         MBEDTLS_X509_SAFE_SNPRINTF;
 
@@ -855,16 +904,15 @@
     if( pk_alg == MBEDTLS_PK_RSASSA_PSS )
     {
         const mbedtls_pk_rsassa_pss_options *pss_opts;
-        const mbedtls_md_info_t *md_info, *mgf_md_info;
 
         pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts;
 
-        md_info = mbedtls_md_info_from_type( md_alg );
-        mgf_md_info = mbedtls_md_info_from_type( pss_opts->mgf1_hash_id );
+        const char *name = md_type_to_string( md_alg );
+        const char *mgf_name = md_type_to_string( pss_opts->mgf1_hash_id );
 
         ret = mbedtls_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)",
-                              md_info ? mbedtls_md_get_name( md_info ) : "???",
-                              mgf_md_info ? mbedtls_md_get_name( mgf_md_info ) : "???",
+                              name ? name : "???",
+                              mgf_name ? mgf_name : "???",
                               (unsigned int) pss_opts->expected_salt_len );
         MBEDTLS_X509_SAFE_SNPRINTF;
     }
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 97b786a..d6724df 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -1534,7 +1534,19 @@
             if( *p == ',' )
                 *p++ = '\0';
 
-            if( strcmp( q, "ecdsa_secp256r1_sha256" ) == 0 )
+            if( strcmp( q, "rsa_pkcs1_sha256" ) == 0 )
+            {
+                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256;
+            }
+            else if( strcmp( q, "rsa_pkcs1_sha384" ) == 0 )
+            {
+                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384;
+            }
+            else if( strcmp( q, "rsa_pkcs1_sha512" ) == 0 )
+            {
+                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512;
+            }
+            else if( strcmp( q, "ecdsa_secp256r1_sha256" ) == 0 )
             {
                 sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256;
             }
@@ -1558,22 +1570,39 @@
             {
                 sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512;
             }
-            else if( strcmp( q, "rsa_pkcs1_sha256" ) == 0 )
+            else if( strcmp( q, "ed25519" ) == 0 )
             {
-                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256;
+                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_ED25519;
+            }
+            else if( strcmp( q, "ed448" ) == 0 )
+            {
+                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_ED448;
+            }
+            else if( strcmp( q, "rsa_pss_pss_sha256" ) == 0 )
+            {
+                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PSS_PSS_SHA256;
+            }
+            else if( strcmp( q, "rsa_pss_pss_sha384" ) == 0 )
+            {
+                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PSS_PSS_SHA384;
+            }
+            else if( strcmp( q, "rsa_pss_pss_sha512" ) == 0 )
+            {
+                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PSS_PSS_SHA512;
+            }
+            else if( strcmp( q, "rsa_pkcs1_sha1" ) == 0 )
+            {
+                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA1;
+            }
+            else if( strcmp( q, "ecdsa_sha1" ) == 0 )
+            {
+                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_ECDSA_SHA1;
             }
             else
             {
-                mbedtls_printf( "unknown signature algorithm %s\n", q );
-                mbedtls_printf( "supported signature algorithms: " );
-                mbedtls_printf( "ecdsa_secp256r1_sha256 " );
-                mbedtls_printf( "ecdsa_secp384r1_sha384 " );
-                mbedtls_printf( "ecdsa_secp521r1_sha512 " );
-                mbedtls_printf( "rsa_pss_rsae_sha256 " );
-                mbedtls_printf( "rsa_pss_rsae_sha384 " );
-                mbedtls_printf( "rsa_pss_rsae_sha512 " );
-                mbedtls_printf( "rsa_pkcs1_sha256 " );
-                mbedtls_printf( "\n" );
+                ret = -1;
+                mbedtls_printf( "unknown signature algorithm \"%s\"\n", q );
+                mbedtls_print_supported_sig_algs();
                 goto exit;
             }
         }
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 4251817..8e432bd 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -116,6 +116,7 @@
 #define DFL_CID_VALUE_RENEGO    NULL
 #define DFL_AUTH_MODE           -1
 #define DFL_CERT_REQ_CA_LIST    MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED
+#define DFL_CERT_REQ_DN_HINT    0
 #define DFL_MFL_CODE            MBEDTLS_SSL_MAX_FRAG_LEN_NONE
 #define DFL_TRUNC_HMAC          -1
 #define DFL_TICKETS             MBEDTLS_SSL_SESSION_TICKETS_ENABLED
@@ -506,6 +507,7 @@
     "                        options: none, optional, required\n" \
     "    cert_req_ca_list=%%d default: 1 (send ca list)\n"  \
     "                        options: 1 (send ca list), 0 (don't send)\n" \
+    "                                 2 (send conf dn hint), 3 (send hs dn hint)\n" \
     USAGE_IO                                                \
     USAGE_KEY_OPAQUE                                        \
     "\n"                                                    \
@@ -629,6 +631,7 @@
     int allow_sha1;             /* flag for SHA-1 support                   */
     int auth_mode;              /* verify mode for connection               */
     int cert_req_ca_list;       /* should we send the CA list?              */
+    int cert_req_dn_hint;       /* mode to set DN hints for CA list to send */
     unsigned char mfl_code;     /* code for maximum fragment length         */
     int trunc_hmac;             /* accept truncated hmac?                   */
     int tickets;                /* enable / disable session tickets         */
@@ -1597,6 +1600,7 @@
     opt.allow_sha1          = DFL_SHA1;
     opt.auth_mode           = DFL_AUTH_MODE;
     opt.cert_req_ca_list    = DFL_CERT_REQ_CA_LIST;
+    opt.cert_req_dn_hint    = DFL_CERT_REQ_DN_HINT;
     opt.mfl_code            = DFL_MFL_CODE;
     opt.trunc_hmac          = DFL_TRUNC_HMAC;
     opt.tickets             = DFL_TICKETS;
@@ -1923,8 +1927,13 @@
         else if( strcmp( p, "cert_req_ca_list" ) == 0 )
         {
             opt.cert_req_ca_list = atoi( q );
-            if( opt.cert_req_ca_list < 0 || opt.cert_req_ca_list > 1 )
+            if( opt.cert_req_ca_list < 0 || opt.cert_req_ca_list > 3 )
                 goto usage;
+            if( opt.cert_req_ca_list > 1 )
+            {
+                opt.cert_req_dn_hint = opt.cert_req_ca_list;
+                opt.cert_req_ca_list = MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED;
+            }
         }
         else if( strcmp( p, "max_frag_len" ) == 0 )
         {
@@ -2370,7 +2379,19 @@
             if( *p == ',' )
                 *p++ = '\0';
 
-            if( strcmp( q, "ecdsa_secp256r1_sha256" ) == 0 )
+            if( strcmp( q, "rsa_pkcs1_sha256" ) == 0 )
+            {
+                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256;
+            }
+            else if( strcmp( q, "rsa_pkcs1_sha384" ) == 0 )
+            {
+                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384;
+            }
+            else if( strcmp( q, "rsa_pkcs1_sha512" ) == 0 )
+            {
+                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512;
+            }
+            else if( strcmp( q, "ecdsa_secp256r1_sha256" ) == 0 )
             {
                 sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256;
             }
@@ -2394,22 +2415,39 @@
             {
                 sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512;
             }
-            else if( strcmp( q, "rsa_pkcs1_sha256" ) == 0 )
+            else if( strcmp( q, "ed25519" ) == 0 )
             {
-                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256;
+                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_ED25519;
+            }
+            else if( strcmp( q, "ed448" ) == 0 )
+            {
+                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_ED448;
+            }
+            else if( strcmp( q, "rsa_pss_pss_sha256" ) == 0 )
+            {
+                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PSS_PSS_SHA256;
+            }
+            else if( strcmp( q, "rsa_pss_pss_sha384" ) == 0 )
+            {
+                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PSS_PSS_SHA384;
+            }
+            else if( strcmp( q, "rsa_pss_pss_sha512" ) == 0 )
+            {
+                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PSS_PSS_SHA512;
+            }
+            else if( strcmp( q, "rsa_pkcs1_sha1" ) == 0 )
+            {
+                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA1;
+            }
+            else if( strcmp( q, "ecdsa_sha1" ) == 0 )
+            {
+                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_ECDSA_SHA1;
             }
             else
             {
-                mbedtls_printf( "unknown signature algorithm %s\n", q );
-                mbedtls_printf( "supported signature algorithms: " );
-                mbedtls_printf( "ecdsa_secp256r1_sha256 " );
-                mbedtls_printf( "ecdsa_secp384r1_sha384 " );
-                mbedtls_printf( "ecdsa_secp521r1_sha512 " );
-                mbedtls_printf( "rsa_pss_rsae_sha256 " );
-                mbedtls_printf( "rsa_pss_rsae_sha384 " );
-                mbedtls_printf( "rsa_pss_rsae_sha512 " );
-                mbedtls_printf( "rsa_pkcs1_sha256 " );
-                mbedtls_printf( "\n" );
+                ret = -1;
+                mbedtls_printf( "unknown signature algorithm \"%s\"\n", q );
+                mbedtls_print_supported_sig_algs();
                 goto exit;
             }
         }
@@ -2732,6 +2770,16 @@
     if( opt.cert_req_ca_list != DFL_CERT_REQ_CA_LIST )
         mbedtls_ssl_conf_cert_req_ca_list( &conf, opt.cert_req_ca_list );
 
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+    /* exercise setting DN hints for server certificate request
+     * (Intended for use where the client cert expected has been signed by
+     *  a specific CA which is an intermediate in a CA chain, not the root) */
+    if( opt.cert_req_dn_hint == 2 && key_cert_init2 )
+        mbedtls_ssl_conf_dn_hints( &conf, &srvcert2 );
+#endif
+#endif
+
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
     if( opt.hs_to_min != DFL_HS_TO_MIN || opt.hs_to_max != DFL_HS_TO_MAX )
         mbedtls_ssl_conf_handshake_timeout( &conf, opt.hs_to_min, opt.hs_to_max );
@@ -3332,6 +3380,20 @@
     }
 #endif
 
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+    /* exercise setting DN hints for server certificate request
+     * (Intended for use where the client cert expected has been signed by
+     *  a specific CA which is an intermediate in a CA chain, not the root)
+     * (Additionally, the CA choice would typically be influenced by SNI
+     *  if being set per-handshake using mbedtls_ssl_set_hs_dn_hints()) */
+    if( opt.cert_req_dn_hint == 3 && key_cert_init2 )
+        mbedtls_ssl_set_hs_dn_hints( &ssl, &srvcert2 );
+#endif
+#endif
+#endif
+
     mbedtls_printf( " ok\n" );
 
     /*
diff --git a/programs/ssl/ssl_test_common_source.c b/programs/ssl/ssl_test_common_source.c
index 0e66895..ad9dcdd 100644
--- a/programs/ssl/ssl_test_common_source.c
+++ b/programs/ssl/ssl_test_common_source.c
@@ -263,12 +263,32 @@
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_RSA_C)
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+/*
+ *   When GnuTLS/Openssl server is configured in TLS 1.2 mode with a certificate
+ *   declaring an RSA public key and Mbed TLS is configured in hybrid mode, if
+ *   `rsa_pss_rsae_*` algorithms are before `rsa_pkcs1_*` ones in this list then
+ *   the GnuTLS/Openssl server chooses an `rsa_pss_rsae_*` signature algorithm
+ *   for its signature in the key exchange message. As Mbed TLS 1.2 does not
+ *   support them, the handshake fails.
+ */
+#define MBEDTLS_SSL_SIG_ALG( hash ) (( hash << 8 ) | MBEDTLS_SSL_SIG_ECDSA), \
+                                    (( hash << 8 ) | MBEDTLS_SSL_SIG_RSA), \
+                                    ( 0x800 | hash ),
+#else
 #define MBEDTLS_SSL_SIG_ALG( hash ) (( hash << 8 ) | MBEDTLS_SSL_SIG_ECDSA), \
                                     (( hash << 8 ) | MBEDTLS_SSL_SIG_RSA),
+#endif
 #elif defined(MBEDTLS_ECDSA_C)
 #define MBEDTLS_SSL_SIG_ALG( hash ) (( hash << 8 ) | MBEDTLS_SSL_SIG_ECDSA),
 #elif defined(MBEDTLS_RSA_C)
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+/* See above */
+#define MBEDTLS_SSL_SIG_ALG( hash ) (( hash << 8 ) | MBEDTLS_SSL_SIG_RSA), \
+                                    ( 0x800 | hash ),
+#else
 #define MBEDTLS_SSL_SIG_ALG( hash ) (( hash << 8 ) | MBEDTLS_SSL_SIG_RSA),
+#endif
 #else
 #define MBEDTLS_SSL_SIG_ALG( hash )
 #endif
@@ -330,3 +350,25 @@
 #endif /* MBEDTLS_X509_REMOVE_INFO */
 }
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+void mbedtls_print_supported_sig_algs( void )
+{
+    mbedtls_printf( "supported signature algorithms:\n" );
+    mbedtls_printf("\trsa_pkcs1_sha256 ");
+    mbedtls_printf("rsa_pkcs1_sha384 ");
+    mbedtls_printf("rsa_pkcs1_sha512\n");
+    mbedtls_printf("\tecdsa_secp256r1_sha256 ");
+    mbedtls_printf("ecdsa_secp384r1_sha384 ");
+    mbedtls_printf("ecdsa_secp521r1_sha512\n");
+    mbedtls_printf("\trsa_pss_rsae_sha256 ");
+    mbedtls_printf("rsa_pss_rsae_sha384 ");
+    mbedtls_printf("rsa_pss_rsae_sha512\n");
+    mbedtls_printf("\trsa_pss_pss_sha256 ");
+    mbedtls_printf("rsa_pss_pss_sha384 ");
+    mbedtls_printf("rsa_pss_pss_sha512\n");
+    mbedtls_printf("\ted25519 ");
+    mbedtls_printf("ed448 ");
+    mbedtls_printf("rsa_pkcs1_sha1 ");
+    mbedtls_printf("ecdsa_sha1\n");
+    mbedtls_printf( "\n" );
+}
diff --git a/programs/test/selftest.c b/programs/test/selftest.c
index a314bd2..ab337a2 100644
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -84,7 +84,6 @@
     void *empty2 = mbedtls_calloc( 0, 1 );
     void *buffer1 = mbedtls_calloc( 1, 1 );
     void *buffer2 = mbedtls_calloc( 1, 1 );
-    uintptr_t old_buffer1;
 
     if( empty1 == NULL && empty2 == NULL )
     {
@@ -126,7 +125,6 @@
             mbedtls_printf( "  CALLOC(1): passed\n" );
     }
 
-    old_buffer1 = (uintptr_t) buffer1;
     mbedtls_free( buffer1 );
     buffer1 = mbedtls_calloc( 1, 1 );
     if( buffer1 == NULL )
@@ -138,9 +136,7 @@
     else
     {
         if( verbose )
-            mbedtls_printf( "  CALLOC(1 again): passed (%s address)\n",
-                            (uintptr_t) old_buffer1 == (uintptr_t) buffer1 ?
-                            "same" : "different" );
+            mbedtls_printf( "  CALLOC(1 again): passed\n" );
     }
 
     if( verbose )
diff --git a/scripts/abi_check.py b/scripts/abi_check.py
index f11cdf2..c228843 100755
--- a/scripts/abi_check.py
+++ b/scripts/abi_check.py
@@ -1,9 +1,10 @@
 #!/usr/bin/env python3
-"""
-This script compares the interfaces of two versions of Mbed TLS, looking
+"""This script compares the interfaces of two versions of Mbed TLS, looking
 for backward incompatibilities between two different Git revisions within
 an Mbed TLS repository. It must be run from the root of a Git working tree.
 
+### How the script works ###
+
 For the source (API) and runtime (ABI) interface compatibility, this script
 is a small wrapper around the abi-compliance-checker and abi-dumper tools,
 applying them to compare the header and library files.
@@ -20,7 +21,66 @@
 Returns 0 on success, 1 on non-compliance, and 2 if there is an error
 while running the script.
 
-You must run this test from an Mbed TLS root.
+### How to interpret non-compliance ###
+
+This script has relatively common false positives. In many scenarios, it only
+reports a pass if there is a strict textual match between the old version and
+the new version, and it reports problems where there is a sufficient semantic
+match but not a textual match. This section lists some common false positives.
+This is not an exhaustive list: in the end what matters is whether we are
+breaking a backward compatibility goal.
+
+**API**: the goal is that if an application works with the old version of the
+library, it can be recompiled against the new version and will still work.
+This is normally validated by comparing the declarations in `include/*/*.h`.
+A failure is a declaration that has disappeared or that now has a different
+type.
+
+  * It's ok to change or remove macros and functions that are documented as
+    for internal use only or as experimental.
+  * It's ok to rename function or macro parameters as long as the semantics
+    has not changed.
+  * It's ok to change or remove structure fields that are documented as
+    private.
+  * It's ok to add fields to a structure that already had private fields
+    or was documented as extensible.
+
+**ABI**: the goal is that if an application was built against the old version
+of the library, the same binary will work when linked against the new version.
+This is normally validated by comparing the symbols exported by `libmbed*.so`.
+A failure is a symbol that is no longer exported by the same library or that
+now has a different type.
+
+  * All ABI changes are acceptable if the library version is bumped
+    (see `scripts/bump_version.sh`).
+  * ABI changes that concern functions which are declared only inside the
+    library directory, and not in `include/*/*.h`, are acceptable only if
+    the function was only ever used inside the same library (libmbedcrypto,
+    libmbedx509, libmbedtls). As a counter example, if the old version
+    of libmbedtls calls mbedtls_foo() from libmbedcrypto, and the new version
+    of libmbedcrypto no longer has a compatible mbedtls_foo(), this does
+    require a version bump for libmbedcrypto.
+
+**Storage format**: the goal is to check that persistent keys stored by the
+old version can be read by the new version. This is normally validated by
+comparing the `*read*` test cases in `test_suite*storage_format*.data`.
+A failure is a storage read test case that is no longer present with the same
+function name and parameter list.
+
+  * It's ok if the same test data is present, but its presentation has changed,
+    for example if a test function is renamed or has different parameters.
+  * It's ok if redundant tests are removed.
+
+**Generated test coverage**: the goal is to check that automatically
+generated tests have as much coverage as before. This is normally validated
+by comparing the test cases that are automatically generated by a script.
+A failure is a generated test case that is no longer present with the same
+function name and parameter list.
+
+  * It's ok if the same test data is present, but its presentation has changed,
+    for example if a test function is renamed or has different parameters.
+  * It's ok if redundant tests are removed.
+
 """
 
 # Copyright The Mbed TLS Contributors
diff --git a/scripts/config.py b/scripts/config.py
index 356b998..f045f98 100755
--- a/scripts/config.py
+++ b/scripts/config.py
@@ -324,6 +324,9 @@
         return adapter(name, active, section)
     return continuation
 
+DEPRECATED = frozenset([
+    'MBEDTLS_PSA_CRYPTO_SE_C',
+])
 def no_deprecated_adapter(adapter):
     """Modify an adapter to disable deprecated symbols.
 
@@ -334,6 +337,8 @@
     def continuation(name, active, section):
         if name == 'MBEDTLS_DEPRECATED_REMOVED':
             return True
+        if name in DEPRECATED:
+            return False
         if adapter is None:
             return active
         return adapter(name, active, section)
diff --git a/scripts/mbedtls_dev/psa_storage.py b/scripts/mbedtls_dev/psa_storage.py
index 45f0380..a06dce1 100644
--- a/scripts/mbedtls_dev/psa_storage.py
+++ b/scripts/mbedtls_dev/psa_storage.py
@@ -1,4 +1,9 @@
 """Knowledge about the PSA key store as implemented in Mbed TLS.
+
+Note that if you need to make a change that affects how keys are
+stored, this may indicate that the key store is changing in a
+backward-incompatible way! Think carefully about backward compatibility
+before changing how test data is constructed or validated.
 """
 
 # Copyright The Mbed TLS Contributors
@@ -146,6 +151,11 @@
         This is the content of the PSA storage file. When PSA storage is
         implemented over stdio files, this does not include any wrapping made
         by the PSA-storage-over-stdio-file implementation.
+
+        Note that if you need to make a change in this function,
+        this may indicate that the key store is changing in a
+        backward-incompatible way! Think carefully about backward
+        compatibility before making any change here.
         """
         header = self.MAGIC + self.pack('L', self.version)
         if self.version == 0:
diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile
index c0ad9b0..6187d17 100644
--- a/tests/data_files/Makefile
+++ b/tests/data_files/Makefile
@@ -909,6 +909,10 @@
 	$(MBEDTLS_CERT_REQ) output_file=$@ filename=$< subject_name="C=NL,O=PolarSSL,CN=PolarSSL Server 1" md=SHA1 force_ns_cert_type=1
 all_final += server1.req.cert_type_empty
 
+server1.req.commas.sha256: server1.key
+	$(MBEDTLS_CERT_REQ) output_file=$@ filename=$< subject_name="C=NL,O=PolarSSL\, Commas,CN=PolarSSL Server 1" md=SHA256
+all_final += server1.req.commas.sha256
+
 # server2*
 
 server2_pwd_ec = PolarSSLTest
@@ -966,7 +970,9 @@
 	$(MBEDTLS_CERT_WRITE) request_file=server1.req.sha256 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) not_before=20190210144406 not_after=20290210144406 md=SHA1 authority_identifier=0 version=3 output_file=$@
 server1.der: server1.crt
 	$(OPENSSL) x509 -inform PEM -in $< -outform DER -out $@
-all_final += server1.crt server1.noauthid.crt server1.crt.der
+server1.commas.crt: server1.key server1.req.commas.sha256 $(test_ca_crt) $(test_ca_key_file_rsa)
+	$(MBEDTLS_CERT_WRITE) request_file=server1.req.commas.sha256 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) version=1 not_before=20190210144406 not_after=20290210144406 md=SHA1 version=3 output_file=$@
+all_final += server1.crt server1.noauthid.crt server1.crt.der server1.commas.crt
 
 server1.key_usage.crt: server1.key server1.req.sha256 $(test_ca_crt) $(test_ca_key_file_rsa)
 	$(MBEDTLS_CERT_WRITE) request_file=server1.req.sha256 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) version=1 not_before=20190210144406 not_after=20290210144406 md=SHA1 key_usage=digital_signature,non_repudiation,key_encipherment version=3 output_file=$@
diff --git a/tests/data_files/server1.commas.crt b/tests/data_files/server1.commas.crt
new file mode 100644
index 0000000..5acd255
--- /dev/null
+++ b/tests/data_files/server1.commas.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDRzCCAi+gAwIBAgIBATANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER
+MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
+MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjBEMQswCQYDVQQGEwJOTDEZMBcG
+A1UECgwQUG9sYXJTU0wsIENvbW1hczEaMBgGA1UEAwwRUG9sYXJTU0wgU2VydmVy
+IDEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpAh89QGrVVVOL/Tbu
+gmUuFWFeib+46EWQ2+6IFlLT8UNQR5YSWWSHa/0r4Eb5c77dz5LhkVvtZqBviSl5
+RYDQg2rVQUN3Xzl8CQRHgrBXOXDto+wVGR6oMwhHwQVCqf1Mw7Tf3QYfTRBRQGdz
+Ew9A+G2BJV8KsVPGMH4VOaz5Wu5/kp6mBVvnE5eFtSOS2dQkBtUJJYl1B92mGo8/
+CRm+rWUsZOuVm9z+QV4XptpsW2nMAroULBYknErczdD3Umdz8S2gI/1+9DHKLXDK
+iQsE2y6mT3Buns69WIniU1meblqSZeKIPwyUGaPd5eidlRPtKdurcBLcWsprF6tS
+glSxAgMBAAGjTTBLMAkGA1UdEwQCMAAwHQYDVR0OBBYEFB901j8pwXR0RTsFEiw9
+qL1DWQKmMB8GA1UdIwQYMBaAFLRa5KWz3tJS9rnVppUP6z68x/3/MA0GCSqGSIb3
+DQEBBQUAA4IBAQA1Ecg+VVJRmgFF9cnlztnXj4y9QKj8MCf2uZA3nTNe1Deh9l17
+ZNNWdPkXzVzf0IeR3LQRKT+daTzxuOOCSV9OxOcN0dIODBwa97BtNQfuWw2eWC9I
+3UOVXbx8Ga+bXnD8ouatpyEG0FfhLO5YgEP0K9TyyN/nFa9kkB2Kvpy8yWm3w9WG
+WgsOr2fpIExfC2ZFaiu3NVGTpT9fLv8RTatSC1XLA5Sr8NNHia3zCvEJEAlTuFHs
+wm8apIAHlb44bbgW+7UwBIH9r2A21gQFy3v4cTLtlbnaUBbHUJvarK4ru70J+gew
+OO3NZ1ocvnV+qGIcc7LgyNA8pZW5Jbewb/gN
+-----END CERTIFICATE-----
diff --git a/tests/data_files/server1.req.commas.sha256 b/tests/data_files/server1.req.commas.sha256
new file mode 100644
index 0000000..0287a31
--- /dev/null
+++ b/tests/data_files/server1.req.commas.sha256
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICiTCCAXECAQAwRDELMAkGA1UEBhMCTkwxGTAXBgNVBAoMEFBvbGFyU1NMLCBD
+b21tYXMxGjAYBgNVBAMMEVBvbGFyU1NMIFNlcnZlciAxMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/uOhFkNvuiBZS
+0/FDUEeWEllkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFDd185fAkER4Kw
+Vzlw7aPsFRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVfCrFTxjB+FTms
++Vruf5KepgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTrlZvc/kFeF6ba
+bFtpzAK6FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9wbp7OvViJ4lNZ
+nm5akmXiiD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQABoAAwDQYJKoZI
+hvcNAQELBQADggEBAI7ZtRJYX6cMuwVhwXOizPV+WD17wby+273V4R8e9/6QA4nY
+RrSciAse+nWZz9Y6toBzLWr0K/9SCzwBX4OzMvLqu4A1G/wApODCDnbGaUPNUxRt
+6qbg8y7faBWvDGjk4+OpQ0suR/pdbM/L7pImqWRNwYdSPbJumNqIdB/Ewtso0TlA
+QVZ992RPe1LovXpDCfPP2p123L7/UHezNCtu5QmzLsDfQmN/rLhCJ2NZzTsnIdnP
+jp6XYU4kRV2BPDL65k38k8CSVWb6fw9XwPNUiyO3q1Zs6jpGJRYMLj9qTEoRN1np
+RME09CN2siMcgkv8UqDeDJ4Oa9qyXS6VXsDmSNI=
+-----END CERTIFICATE REQUEST-----
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index ca34753..edd5161 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -5296,6 +5296,39 @@
             -c "! mbedtls_ssl_handshake returned" \
             -s "X509 - Certificate verification failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+run_test    "Authentication: send alt conf DN hints in CertificateRequest" \
+            "$P_SRV debug_level=3 auth_mode=optional cert_req_ca_list=2 \
+             crt_file2=data_files/server1.crt \
+             key_file2=data_files/server1.key" \
+            "$P_CLI debug_level=3 auth_mode=optional \
+             crt_file=data_files/server6.crt \
+             key_file=data_files/server6.key" \
+            0 \
+            -c "DN hint: C=NL, O=PolarSSL, CN=PolarSSL Server 1"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+run_test    "Authentication: send alt conf DN hints in CertificateRequest (2)" \
+            "$P_SRV debug_level=3 auth_mode=optional cert_req_ca_list=2 \
+             crt_file2=data_files/server2.crt \
+             key_file2=data_files/server2.key" \
+            "$P_CLI debug_level=3 auth_mode=optional \
+             crt_file=data_files/server6.crt \
+             key_file=data_files/server6.key" \
+            0 \
+            -c "DN hint: C=NL, O=PolarSSL, CN=localhost"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+run_test    "Authentication: send alt hs DN hints in CertificateRequest" \
+            "$P_SRV debug_level=3 auth_mode=optional cert_req_ca_list=3 \
+             crt_file2=data_files/server1.crt \
+             key_file2=data_files/server1.key" \
+            "$P_CLI debug_level=3 auth_mode=optional \
+             crt_file=data_files/server6.crt \
+             key_file=data_files/server6.key" \
+            0 \
+            -c "DN hint: C=NL, O=PolarSSL, CN=PolarSSL Server 1"
+
 # Tests for auth_mode, using CA callback, these are duplicated from the authentication tests
 # When updating these tests, modify the matching authentication tests accordingly
 
@@ -11679,6 +11712,35 @@
 done
 unset TEST_SUITE_NAME
 
+# Test 1.3 compatibility mode
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_disabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+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 m->m both peers do not support middlebox compatibility" \
+            "$P_SRV debug_level=4 force_version=tls13 tickets=0" \
+            "$P_CLI debug_level=4" \
+            0 \
+            -s "Protocol is TLSv1.3" \
+            -c "Protocol is TLSv1.3" \
+            -S "tls13 server state: MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO" \
+            -C "Ignore ChangeCipherSpec in TLS 1.3 compatibility mode"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3 m->m both with middlebox compat support" \
+            "$P_SRV debug_level=4 force_version=tls13 tickets=0" \
+            "$P_CLI debug_level=4" \
+            0 \
+            -s "Protocol is TLSv1.3" \
+            -c "Protocol is TLSv1.3" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO" \
+            -c "Ignore ChangeCipherSpec in TLS 1.3 compatibility mode"
+
 requires_openssl_tls1_3
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
 requires_config_disabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
@@ -11686,10 +11748,11 @@
 requires_config_enabled MBEDTLS_SSL_CLI_C
 run_test    "TLS 1.3 m->O both peers do not support middlebox compatibility" \
             "$O_NEXT_SRV -msg -tls1_3 -no_middlebox -num_tickets 0 -no_resume_ephemeral -no_cache" \
-            "$P_CLI debug_level=3" \
+            "$P_CLI debug_level=4" \
             0 \
             -c "Protocol is TLSv1.3" \
-            -c "HTTP/1.0 200 ok"
+            -C "ChangeCipherSpec invalid in TLS 1.3 without compatibility mode" \
+            -C "Ignore ChangeCipherSpec in TLS 1.3 compatibility mode"
 
 requires_openssl_tls1_3
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -11698,10 +11761,22 @@
 requires_config_enabled MBEDTLS_SSL_CLI_C
 run_test    "TLS 1.3 m->O server with middlebox compat support, not client" \
             "$O_NEXT_SRV -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
-            "$P_CLI debug_level=3" \
+            "$P_CLI debug_level=4" \
             1 \
             -c "ChangeCipherSpec invalid in TLS 1.3 without compatibility mode"
 
+requires_openssl_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3 m->O both with middlebox compat support" \
+            "$O_NEXT_SRV -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
+            "$P_CLI debug_level=4" \
+            0 \
+            -c "Protocol is TLSv1.3" \
+            -c "Ignore ChangeCipherSpec in TLS 1.3 compatibility mode"
+
 requires_gnutls_tls1_3
 requires_gnutls_next_no_ticket
 requires_gnutls_next_disable_tls13_compat
@@ -11711,10 +11786,11 @@
 requires_config_enabled MBEDTLS_SSL_CLI_C
 run_test    "TLS 1.3 m->G both peers do not support middlebox compatibility" \
             "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:%NO_TICKETS:%DISABLE_TLS13_COMPAT_MODE --disable-client-cert" \
-            "$P_CLI debug_level=3" \
+            "$P_CLI debug_level=4" \
             0 \
             -c "Protocol is TLSv1.3" \
-            -c "HTTP/1.0 200 OK"
+            -C "ChangeCipherSpec invalid in TLS 1.3 without compatibility mode" \
+            -C "Ignore ChangeCipherSpec in TLS 1.3 compatibility mode"
 
 requires_gnutls_tls1_3
 requires_gnutls_next_no_ticket
@@ -11724,10 +11800,524 @@
 requires_config_enabled MBEDTLS_SSL_CLI_C
 run_test    "TLS 1.3 m->G server with middlebox compat support, not client" \
             "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:%NO_TICKETS --disable-client-cert" \
-            "$P_CLI debug_level=3" \
+            "$P_CLI debug_level=4" \
             1 \
             -c "ChangeCipherSpec invalid in TLS 1.3 without compatibility mode"
 
+requires_gnutls_tls1_3
+requires_gnutls_next_no_ticket
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3 m->G both with middlebox compat support" \
+            "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:%NO_TICKETS --disable-client-cert" \
+            "$P_CLI debug_level=4" \
+            0 \
+            -c "Protocol is TLSv1.3" \
+            -c "Ignore ChangeCipherSpec in TLS 1.3 compatibility mode"
+
+requires_openssl_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_disabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test    "TLS 1.3 O->m both peers do not support middlebox compatibility" \
+            "$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 -no_middlebox" \
+            0 \
+            -s "Protocol is TLSv1.3" \
+            -S "tls13 server state: MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO" \
+            -C "14 03 03 00 01"
+
+requires_openssl_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test    "TLS 1.3 O->m server with middlebox compat support, not client" \
+            "$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 -no_middlebox" \
+            0 \
+            -s "Protocol is TLSv1.3" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO"
+
+requires_openssl_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test    "TLS 1.3 O->m both with middlebox compat support" \
+            "$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" \
+            0 \
+            -s "Protocol is TLSv1.3" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO" \
+            -c "14 03 03 00 01"
+
+requires_gnutls_tls1_3
+requires_gnutls_next_no_ticket
+requires_gnutls_next_disable_tls13_compat
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_disabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test    "TLS 1.3 G->m both peers do not support middlebox compatibility" \
+            "$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 --priority=NORMAL:%NO_TICKETS:%DISABLE_TLS13_COMPAT_MODE -V" \
+            0 \
+            -s "Protocol is TLSv1.3" \
+            -S "tls13 server state: MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO" \
+            -C "SSL 3.3 ChangeCipherSpec packet received"
+
+requires_gnutls_tls1_3
+requires_gnutls_next_no_ticket
+requires_gnutls_next_disable_tls13_compat
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test    "TLS 1.3 G->m server with middlebox compat support, not client" \
+            "$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 --debug=10 --priority=NORMAL:%NO_TICKETS:%DISABLE_TLS13_COMPAT_MODE -V" \
+            0 \
+            -s "Protocol is TLSv1.3" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO" \
+            -c "SSL 3.3 ChangeCipherSpec packet received" \
+            -c "discarding change cipher spec in TLS1.3"
+
+requires_gnutls_tls1_3
+requires_gnutls_next_no_ticket
+requires_gnutls_next_disable_tls13_compat
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test    "TLS 1.3 G->m both with middlebox compat support" \
+            "$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 --debug=10 --priority=NORMAL:%NO_TICKETS:%DISABLE_TLS13_COMPAT_MODE -V" \
+            0 \
+            -s "Protocol is TLSv1.3" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO" \
+            -c "SSL 3.3 ChangeCipherSpec packet received"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_disabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+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 m->m HRR both peers do not support middlebox compatibility" \
+            "$P_SRV debug_level=4 force_version=tls13 curves=secp384r1 tickets=0" \
+            "$P_CLI debug_level=4 curves=secp256r1,secp384r1" \
+            0 \
+            -s "Protocol is TLSv1.3" \
+            -c "Protocol is TLSv1.3" \
+            -s "tls13 server state: MBEDTLS_SSL_HELLO_RETRY_REQUEST" \
+            -S "tls13 server state: MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REQUEST" \
+            -C "Ignore ChangeCipherSpec in TLS 1.3 compatibility mode"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3 m->m HRR both with middlebox compat support" \
+            "$P_SRV debug_level=4 force_version=tls13 curves=secp384r1 tickets=0" \
+            "$P_CLI debug_level=4 curves=secp256r1,secp384r1" \
+            0 \
+            -s "Protocol is TLSv1.3" \
+            -c "Protocol is TLSv1.3" \
+            -s "tls13 server state: MBEDTLS_SSL_HELLO_RETRY_REQUEST" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REQUEST" \
+            -c "Ignore ChangeCipherSpec in TLS 1.3 compatibility mode"
+
+requires_openssl_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_disabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3 m->O HRR both peers do not support middlebox compatibility" \
+            "$O_NEXT_SRV -msg -tls1_3 -groups P-384 -no_middlebox -num_tickets 0 -no_cache" \
+            "$P_CLI debug_level=4 curves=secp256r1,secp384r1" \
+            0 \
+            -c "Protocol is TLSv1.3" \
+            -c "received HelloRetryRequest message" \
+            -C "ChangeCipherSpec invalid in TLS 1.3 without compatibility mode" \
+            -C "Ignore ChangeCipherSpec in TLS 1.3 compatibility mode"
+
+requires_openssl_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_disabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3 m->O HRR server with middlebox compat support, not client" \
+            "$O_NEXT_SRV -msg -tls1_3 -groups P-384 -num_tickets 0 -no_cache" \
+            "$P_CLI debug_level=4 curves=secp256r1,secp384r1" \
+            1 \
+            -c "received HelloRetryRequest message" \
+            -c "ChangeCipherSpec invalid in TLS 1.3 without compatibility mode"
+
+requires_openssl_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3 m->O HRR both with middlebox compat support" \
+            "$O_NEXT_SRV -msg -tls1_3 -groups P-384 -num_tickets 0 -no_resume_ephemeral -no_cache" \
+            "$P_CLI debug_level=4 curves=secp256r1,secp384r1" \
+            0 \
+            -c "Protocol is TLSv1.3" \
+            -c "Ignore ChangeCipherSpec in TLS 1.3 compatibility mode"
+
+requires_gnutls_tls1_3
+requires_gnutls_next_no_ticket
+requires_gnutls_next_disable_tls13_compat
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_disabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3 m->G HRR both peers do not support middlebox compatibility" \
+            "$G_NEXT_SRV --priority=NORMAL:-GROUP-ALL:+GROUP-SECP384R1:-VERS-ALL:+VERS-TLS1.3:%NO_TICKETS:%DISABLE_TLS13_COMPAT_MODE --disable-client-cert" \
+            "$P_CLI debug_level=4 curves=secp256r1,secp384r1" \
+            0 \
+            -c "Protocol is TLSv1.3" \
+            -c "received HelloRetryRequest message" \
+            -C "ChangeCipherSpec invalid in TLS 1.3 without compatibility mode" \
+            -C "Ignore ChangeCipherSpec in TLS 1.3 compatibility mode"
+
+requires_gnutls_tls1_3
+requires_gnutls_next_no_ticket
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_disabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3 m->G HRR server with middlebox compat support, not client" \
+            "$G_NEXT_SRV --priority=NORMAL:-GROUP-ALL:+GROUP-SECP384R1:-VERS-ALL:+VERS-TLS1.3:%NO_TICKETS --disable-client-cert" \
+            "$P_CLI debug_level=4 curves=secp256r1,secp384r1" \
+            1 \
+            -c "received HelloRetryRequest message" \
+            -c "ChangeCipherSpec invalid in TLS 1.3 without compatibility mode"
+
+requires_gnutls_tls1_3
+requires_gnutls_next_no_ticket
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3 m->G HRR both with middlebox compat support" \
+            "$G_NEXT_SRV --priority=NORMAL:-GROUP-ALL:+GROUP-SECP384R1:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:%NO_TICKETS --disable-client-cert" \
+            "$P_CLI debug_level=4 curves=secp256r1,secp384r1" \
+            0 \
+            -c "Protocol is TLSv1.3" \
+            -c "Ignore ChangeCipherSpec in TLS 1.3 compatibility mode"
+
+requires_openssl_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_disabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test    "TLS 1.3 O->m HRR both peers do not support middlebox compatibility" \
+            "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 curves=secp384r1 tickets=0" \
+            "$O_NEXT_CLI -msg -debug -groups P-256:P-384 -no_middlebox" \
+            0 \
+            -s "Protocol is TLSv1.3" \
+            -S "tls13 server state: MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REQUEST" \
+            -C "14 03 03 00 01"
+
+requires_openssl_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test    "TLS 1.3 O->m HRR server with middlebox compat support, not client" \
+            "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 curves=secp384r1 tickets=0" \
+            "$O_NEXT_CLI -msg -debug -groups P-256:P-384 -no_middlebox" \
+            0 \
+            -s "Protocol is TLSv1.3" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REQUEST" \
+
+requires_openssl_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test    "TLS 1.3 O->m HRR both with middlebox compat support" \
+            "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 curves=secp384r1 tickets=0" \
+            "$O_NEXT_CLI -msg -debug -groups P-256:P-384" \
+            0 \
+            -s "Protocol is TLSv1.3" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REQUEST" \
+            -c "14 03 03 00 01"
+
+requires_gnutls_tls1_3
+requires_gnutls_next_no_ticket
+requires_gnutls_next_disable_tls13_compat
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_disabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test    "TLS 1.3 G->m HRR both peers do not support middlebox compatibility" \
+            "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 curves=secp384r1 tickets=0" \
+            "$G_NEXT_CLI localhost --priority=NORMAL:-GROUP-ALL:+GROUP-SECP256R1:+GROUP-SECP384R1:%NO_TICKETS:%DISABLE_TLS13_COMPAT_MODE -V" \
+            0 \
+            -s "Protocol is TLSv1.3" \
+            -S "tls13 server state: MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REQUEST" \
+            -C "SSL 3.3 ChangeCipherSpec packet received"
+
+requires_gnutls_tls1_3
+requires_gnutls_next_no_ticket
+requires_gnutls_next_disable_tls13_compat
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test    "TLS 1.3 G->m HRR server with middlebox compat support, not client" \
+            "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 curves=secp384r1 tickets=0" \
+            "$G_NEXT_CLI localhost --debug=10 --priority=NORMAL:-GROUP-ALL:+GROUP-SECP256R1:+GROUP-SECP384R1:%NO_TICKETS:%DISABLE_TLS13_COMPAT_MODE -V" \
+            0 \
+            -s "Protocol is TLSv1.3" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REQUEST" \
+            -c "SSL 3.3 ChangeCipherSpec packet received" \
+            -c "discarding change cipher spec in TLS1.3"
+
+requires_gnutls_tls1_3
+requires_gnutls_next_no_ticket
+requires_gnutls_next_disable_tls13_compat
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test    "TLS 1.3 G->m HRR both with middlebox compat support" \
+            "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 curves=secp384r1 tickets=0" \
+            "$G_NEXT_CLI localhost --debug=10 --priority=NORMAL:-GROUP-ALL:+GROUP-SECP256R1:+GROUP-SECP384R1:%NO_TICKETS:%DISABLE_TLS13_COMPAT_MODE -V" \
+            0 \
+            -s "Protocol is TLSv1.3" \
+            -s "tls13 server state: MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REQUEST" \
+            -c "SSL 3.3 ChangeCipherSpec packet received"
+
+requires_openssl_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3: Check signature algorithm order, m->O" \
+            "$O_NEXT_SRV_NO_CERT -cert data_files/server2-sha256.crt -key data_files/server2.key
+                                 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache
+                                 -Verify 10 -sigalgs rsa_pkcs1_sha512:rsa_pss_rsae_sha512:rsa_pss_rsae_sha384:ecdsa_secp256r1_sha256" \
+            "$P_CLI debug_level=4 crt_file=data_files/server2-sha256.crt key_file=data_files/server2.key \
+                    sig_algs=rsa_pkcs1_sha512,rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,ecdsa_secp256r1_sha256" \
+            0 \
+            -c "Protocol is TLSv1.3" \
+            -c "select_sig_alg_for_certificate_verify:selected signature algorithm rsa_pss_rsae_sha512" \
+            -c "HTTP/1.0 200 [Oo][Kk]"
+
+requires_gnutls_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3: Check signature algorithm order, m->G" \
+            "$G_NEXT_SRV_NO_CERT --x509certfile data_files/server2-sha256.crt --x509keyfile data_files/server2.key
+                    -d 4
+                    --priority=NORMAL:-VERS-ALL:-SIGN-ALL:+SIGN-RSA-SHA512:+SIGN-RSA-PSS-RSAE-SHA512:+SIGN-RSA-PSS-RSAE-SHA384:+VERS-TLS1.3:+CIPHER-ALL:%NO_TICKETS " \
+            "$P_CLI debug_level=4 crt_file=data_files/server2-sha256.crt key_file=data_files/server2.key \
+                    sig_algs=rsa_pkcs1_sha512,rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,ecdsa_secp256r1_sha256" \
+            0 \
+            -c "Protocol is TLSv1.3" \
+            -c "select_sig_alg_for_certificate_verify:selected signature algorithm rsa_pss_rsae_sha512" \
+            -c "HTTP/1.0 200 [Oo][Kk]"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3: Check signature algorithm order, m->m" \
+            "$P_SRV debug_level=4 force_version=tls13 auth_mode=required
+                    crt_file2=data_files/server2-sha256.crt key_file2=data_files/server2.key
+                    crt_file=data_files/server5.crt key_file=data_files/server5.key
+                    sig_algs=rsa_pkcs1_sha512,rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,ecdsa_secp256r1_sha256 " \
+            "$P_CLI debug_level=4 crt_file=data_files/server2-sha256.crt key_file=data_files/server2.key \
+                    sig_algs=rsa_pkcs1_sha512,rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,ecdsa_secp256r1_sha256" \
+            0 \
+            -c "Protocol is TLSv1.3" \
+            -c "select_sig_alg_for_certificate_verify:selected signature algorithm rsa_pss_rsae_sha512" \
+            -s "select_sig_alg_for_certificate_verify:selected signature algorithm rsa_pss_rsae_sha512" \
+            -s "ssl_tls13_pick_key_cert:selected signature algorithm rsa_pss_rsae_sha512" \
+            -c "HTTP/1.0 200 [Oo][Kk]"
+
+requires_openssl_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test    "TLS 1.3: Check signature algorithm order, O->m" \
+            "$P_SRV debug_level=4 force_version=tls13 auth_mode=required
+                    crt_file2=data_files/server2-sha256.crt key_file2=data_files/server2.key
+                    crt_file=data_files/server5.crt key_file=data_files/server5.key
+                    sig_algs=rsa_pkcs1_sha512,rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,ecdsa_secp256r1_sha256 " \
+            "$O_NEXT_CLI_NO_CERT -msg -CAfile data_files/test-ca_cat12.crt \
+                                 -cert data_files/server2-sha256.crt -key data_files/server2.key \
+                                 -sigalgs rsa_pkcs1_sha512:rsa_pss_rsae_sha512:rsa_pss_rsae_sha384:ecdsa_secp256r1_sha256"  \
+            0 \
+            -c "TLSv1.3" \
+            -s "select_sig_alg_for_certificate_verify:selected signature algorithm rsa_pss_rsae_sha512" \
+            -s "ssl_tls13_pick_key_cert:selected signature algorithm rsa_pss_rsae_sha512"
+
+requires_gnutls_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test    "TLS 1.3: Check signature algorithm order, G->m" \
+            "$P_SRV debug_level=4 force_version=tls13 auth_mode=required
+                    crt_file2=data_files/server2-sha256.crt key_file2=data_files/server2.key
+                    crt_file=data_files/server5.crt key_file=data_files/server5.key
+                    sig_algs=rsa_pkcs1_sha512,rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,ecdsa_secp256r1_sha256 " \
+            "$G_NEXT_CLI_NO_CERT localhost -d 4 --x509cafile data_files/test-ca_cat12.crt \
+                                 --x509certfile data_files/server2-sha256.crt --x509keyfile data_files/server2.key \
+                                 --priority=NORMAL:-SIGN-ALL:+SIGN-RSA-SHA512:+SIGN-RSA-PSS-RSAE-SHA512:+SIGN-RSA-PSS-RSAE-SHA384"  \
+            0 \
+            -c "Negotiated version: 3.4" \
+            -c "HTTP/1.0 200 [Oo][Kk]" \
+            -s "select_sig_alg_for_certificate_verify:selected signature algorithm rsa_pss_rsae_sha512" \
+            -s "ssl_tls13_pick_key_cert:selected signature algorithm rsa_pss_rsae_sha512"
+
+requires_gnutls_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test    "TLS 1.3: Check server no suitable signature algorithm, G->m" \
+            "$P_SRV debug_level=4 force_version=tls13 auth_mode=required
+                    crt_file2=data_files/server2-sha256.crt key_file2=data_files/server2.key
+                    crt_file=data_files/server5.crt key_file=data_files/server5.key
+                    sig_algs=rsa_pkcs1_sha512,ecdsa_secp256r1_sha256 " \
+            "$G_NEXT_CLI_NO_CERT localhost -d 4 --x509cafile data_files/test-ca_cat12.crt \
+                                 --x509certfile data_files/server2-sha256.crt --x509keyfile data_files/server2.key \
+                                 --priority=NORMAL:-SIGN-ALL:+SIGN-RSA-SHA512:+SIGN-RSA-PSS-RSAE-SHA512:+SIGN-ECDSA-SECP521R1-SHA512"  \
+            1 \
+            -s "ssl_tls13_pick_key_cert:selected signature algorithm rsa_pss_rsae_sha512" \
+            -s "select_sig_alg_for_certificate_verify:no suitable signature algorithm found"
+
+requires_openssl_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test    "TLS 1.3: Check server no suitable signature algorithm, O->m" \
+            "$P_SRV debug_level=4 force_version=tls13 auth_mode=required
+                    crt_file2=data_files/server2-sha256.crt key_file2=data_files/server2.key
+                    crt_file=data_files/server5.crt key_file=data_files/server5.key
+                    sig_algs=rsa_pkcs1_sha512,ecdsa_secp256r1_sha256" \
+            "$O_NEXT_CLI_NO_CERT -msg -CAfile data_files/test-ca_cat12.crt \
+                                 -cert data_files/server2-sha256.crt -key data_files/server2.key \
+                                 -sigalgs rsa_pkcs1_sha512:rsa_pss_rsae_sha512:ecdsa_secp521r1_sha512"  \
+            1 \
+            -s "ssl_tls13_pick_key_cert:selected signature algorithm rsa_pss_rsae_sha512" \
+            -s "select_sig_alg_for_certificate_verify:no suitable signature algorithm found"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3: Check server no suitable signature algorithm, m->m" \
+            "$P_SRV debug_level=4 force_version=tls13 auth_mode=required
+                    crt_file2=data_files/server2-sha256.crt key_file2=data_files/server2.key
+                    crt_file=data_files/server5.crt key_file=data_files/server5.key
+                    sig_algs=rsa_pkcs1_sha512,ecdsa_secp256r1_sha256 " \
+            "$P_CLI allow_sha1=0 debug_level=4 crt_file=data_files/server2-sha256.crt key_file=data_files/server2.key \
+                    sig_algs=rsa_pkcs1_sha512,rsa_pss_rsae_sha512,ecdsa_secp521r1_sha512" \
+            1 \
+            -s "ssl_tls13_pick_key_cert:selected signature algorithm rsa_pss_rsae_sha512" \
+            -s "select_sig_alg_for_certificate_verify:no suitable signature algorithm found"
+
+requires_gnutls_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test    "TLS 1.3: Check server no suitable certificate, G->m" \
+            "$P_SRV debug_level=4 force_version=tls13
+                    crt_file=data_files/server2-sha256.crt key_file=data_files/server2.key
+                    sig_algs=rsa_pkcs1_sha512,rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,ecdsa_secp256r1_sha256 " \
+            "$G_NEXT_CLI_NO_CERT localhost -d 4 --x509cafile data_files/test-ca_cat12.crt \
+                                 --priority=NORMAL:-SIGN-ALL:+SIGN-ECDSA-SECP521R1-SHA512:+SIGN-ECDSA-SECP256R1-SHA256"  \
+            1 \
+            -s "ssl_tls13_pick_key_cert:no suitable certificate found"
+
+requires_openssl_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+run_test    "TLS 1.3: Check server no suitable certificate, O->m" \
+            "$P_SRV debug_level=4 force_version=tls13
+                    crt_file=data_files/server2-sha256.crt key_file=data_files/server2.key
+                    sig_algs=rsa_pkcs1_sha512,rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,ecdsa_secp256r1_sha256 " \
+            "$O_NEXT_CLI_NO_CERT -msg -CAfile data_files/test-ca_cat12.crt \
+                                 -sigalgs ecdsa_secp521r1_sha512:ecdsa_secp256r1_sha256"  \
+            1 \
+            -s "ssl_tls13_pick_key_cert:no suitable certificate found"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3: Check server no suitable certificate, m->m" \
+            "$P_SRV debug_level=4 force_version=tls13
+                    crt_file=data_files/server2-sha256.crt key_file=data_files/server2.key
+                    sig_algs=rsa_pkcs1_sha512,rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,ecdsa_secp256r1_sha256 " \
+            "$P_CLI allow_sha1=0 debug_level=4 \
+                    sig_algs=ecdsa_secp521r1_sha512,ecdsa_secp256r1_sha256" \
+            1 \
+            -s "ssl_tls13_pick_key_cert:no suitable certificate found"
+
+requires_openssl_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3: Check client no signature algorithm, m->O" \
+            "$O_NEXT_SRV_NO_CERT -cert data_files/server2-sha256.crt -key data_files/server2.key
+                                 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache
+                                 -Verify 10 -sigalgs rsa_pkcs1_sha512:rsa_pss_rsae_sha512:rsa_pss_rsae_sha384:ecdsa_secp521r1_sha512" \
+            "$P_CLI debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key \
+                    sig_algs=rsa_pkcs1_sha512,rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,ecdsa_secp256r1_sha256" \
+            1 \
+            -c "select_sig_alg_for_certificate_verify:no suitable signature algorithm found"
+
+requires_gnutls_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3: Check client no signature algorithm, m->G" \
+            "$G_NEXT_SRV_NO_CERT --x509certfile data_files/server2-sha256.crt --x509keyfile data_files/server2.key
+                    -d 4
+                    --priority=NORMAL:-VERS-ALL:-SIGN-ALL:+SIGN-RSA-SHA512:+SIGN-RSA-PSS-RSAE-SHA512:+SIGN-RSA-PSS-RSAE-SHA384:+VERS-TLS1.3:+CIPHER-ALL:%NO_TICKETS " \
+            "$P_CLI debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key \
+                    sig_algs=rsa_pkcs1_sha512,rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,ecdsa_secp256r1_sha256" \
+            1 \
+            -c "select_sig_alg_for_certificate_verify:no suitable signature algorithm found"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_SRV_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+run_test    "TLS 1.3: Check client no signature algorithm, m->m" \
+            "$P_SRV debug_level=4 force_version=tls13 auth_mode=required
+                    crt_file2=data_files/server2-sha256.crt key_file2=data_files/server2.key
+                    crt_file=data_files/server5.crt key_file=data_files/server5.key
+                    sig_algs=rsa_pkcs1_sha512,rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,ecdsa_secp521r1_sha512" \
+            "$P_CLI debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key \
+                    sig_algs=rsa_pkcs1_sha512,rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,ecdsa_secp256r1_sha256" \
+            1 \
+            -c "select_sig_alg_for_certificate_verify:no suitable signature algorithm found"
+
 # Test heap memory usage after handshake
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_MEMORY_DEBUG
diff --git a/tests/suites/test_suite_asn1write.data b/tests/suites/test_suite_asn1write.data
index f844d48..725cbc2 100644
--- a/tests/suites/test_suite_asn1write.data
+++ b/tests/suites/test_suite_asn1write.data
@@ -91,8 +91,11 @@
 ASN.1 Write enum 2147483647
 mbedtls_asn1_write_enum:0x7fffffff:"0A047fffffff"
 
-#ASN.1 Write mpi 0
-#mbedtls_asn1_write_mpi:"00":"020100"
+ASN.1 Write mpi 0 (null)
+mbedtls_asn1_write_mpi:"":"020100"
+
+ASN.1 Write mpi 0 (1 limb)
+mbedtls_asn1_write_mpi:"00":"020100"
 
 ASN.1 Write mpi 1
 mbedtls_asn1_write_mpi:"01":"020101"
@@ -100,11 +103,17 @@
 ASN.1 Write mpi 0x7f
 mbedtls_asn1_write_mpi:"7f":"02017f"
 
-#ASN.1 Write mpi 0x80
-#mbedtls_asn1_write_mpi:"7f":"02020080"
+ASN.1 Write mpi 0x7f with leading 0 limb
+mbedtls_asn1_write_mpi:"00000000000000007f":"02017f"
 
-#ASN.1 Write mpi 0xff
-#mbedtls_asn1_write_mpi:"7f":"020200ff"
+ASN.1 Write mpi 0x80
+mbedtls_asn1_write_mpi:"80":"02020080"
+
+ASN.1 Write mpi 0x80 with leading 0 limb
+mbedtls_asn1_write_mpi:"000000000000000080":"02020080"
+
+ASN.1 Write mpi 0xff
+mbedtls_asn1_write_mpi:"ff":"020200ff"
 
 ASN.1 Write mpi 0x100
 mbedtls_asn1_write_mpi:"0100":"02020100"
@@ -112,17 +121,17 @@
 ASN.1 Write mpi, 127*8-1 bits
 mbedtls_asn1_write_mpi:"7f7b16e05c1537de7c41cef1a0985d6a3ced98aec28e091874cbad6b5e40a5c956258f18861c28bed8ba808259339ee34b2e509c4080149474d5d5b86093f90c475a6443fc87e1a293d4151be625d652f1c32a00a018bba10c8a2ae5b2b0ee4be64e053dce9d07ec7919526c9dfcf2ec9fc3db485caa8e5a68a2cd0a427de8":"027f7f7b16e05c1537de7c41cef1a0985d6a3ced98aec28e091874cbad6b5e40a5c956258f18861c28bed8ba808259339ee34b2e509c4080149474d5d5b86093f90c475a6443fc87e1a293d4151be625d652f1c32a00a018bba10c8a2ae5b2b0ee4be64e053dce9d07ec7919526c9dfcf2ec9fc3db485caa8e5a68a2cd0a427de8"
 
-#ASN.1 Write mpi, 127*8 bits
-#mbedtls_asn1_write_mpi:"e77b16e05c1537de7c41cef1a0985d6a3ced98aec28e091874cbad6b5e40a5c956258f18861c28bed8ba808259339ee34b2e509c4080149474d5d5b86093f90c475a6443fc87e1a293d4151be625d652f1c32a00a018bba10c8a2ae5b2b0ee4be64e053dce9d07ec7919526c9dfcf2ec9fc3db485caa8e5a68a2cd0a427de8":"028180e77b16e05c1537de7c41cef1a0985d6a3ced98aec28e091874cbad6b5e40a5c956258f18861c28bed8ba808259339ee34b2e509c4080149474d5d5b86093f90c475a6443fc87e1a293d4151be625d652f1c32a00a018bba10c8a2ae5b2b0ee4be64e053dce9d07ec7919526c9dfcf2ec9fc3db485caa8e5a68a2cd0a427de8"
+ASN.1 Write mpi, 127*8 bits
+mbedtls_asn1_write_mpi:"e77b16e05c1537de7c41cef1a0985d6a3ced98aec28e091874cbad6b5e40a5c956258f18861c28bed8ba808259339ee34b2e509c4080149474d5d5b86093f90c475a6443fc87e1a293d4151be625d652f1c32a00a018bba10c8a2ae5b2b0ee4be64e053dce9d07ec7919526c9dfcf2ec9fc3db485caa8e5a68a2cd0a427de8":"02818000e77b16e05c1537de7c41cef1a0985d6a3ced98aec28e091874cbad6b5e40a5c956258f18861c28bed8ba808259339ee34b2e509c4080149474d5d5b86093f90c475a6443fc87e1a293d4151be625d652f1c32a00a018bba10c8a2ae5b2b0ee4be64e053dce9d07ec7919526c9dfcf2ec9fc3db485caa8e5a68a2cd0a427de8"
 
 ASN.1 Write mpi, 127*8+1 bits
-mbedtls_asn1_write_mpi:"108446d68934cc1af23c4cd909884d4bd737a1890e12f5ef8bf3d807d72feffa63c0bf2633345f8b8418d144617c871a7a0277ac0150eed4b3db7f9dff21114cd0d7f282400f03c931cb00c367550e374a1ed3762a1801ca714cfc8d5aac69707ca81e0661400ed0014d97cba48f94d835dd681fc3053c51958afbf7583cf49c":"028180108446d68934cc1af23c4cd909884d4bd737a1890e12f5ef8bf3d807d72feffa63c0bf2633345f8b8418d144617c871a7a0277ac0150eed4b3db7f9dff21114cd0d7f282400f03c931cb00c367550e374a1ed3762a1801ca714cfc8d5aac69707ca81e0661400ed0014d97cba48f94d835dd681fc3053c51958afbf7583cf49c"
+mbedtls_asn1_write_mpi:"018446d68934cc1af23c4cd909884d4bd737a1890e12f5ef8bf3d807d72feffa63c0bf2633345f8b8418d144617c871a7a0277ac0150eed4b3db7f9dff21114cd0d7f282400f03c931cb00c367550e374a1ed3762a1801ca714cfc8d5aac69707ca81e0661400ed0014d97cba48f94d835dd681fc3053c51958afbf7583cf49c":"028180018446d68934cc1af23c4cd909884d4bd737a1890e12f5ef8bf3d807d72feffa63c0bf2633345f8b8418d144617c871a7a0277ac0150eed4b3db7f9dff21114cd0d7f282400f03c931cb00c367550e374a1ed3762a1801ca714cfc8d5aac69707ca81e0661400ed0014d97cba48f94d835dd681fc3053c51958afbf7583cf49c"
 
 ASN.1 Write mpi, 255*8-1 bits
 mbedtls_asn1_write_mpi:"7bd1913fcfb652896209ad3e62f5d04a8dfc71eb1698543c52200bd7bbf3c11dd9ff57c299a2f4da172b3d5bd7e29affddf8859be7d50a45537a0df15b17af603d18803fd17134847cba78d83e64bf9fee58364d6124add0541da7bad331cd35fb48186a74bc502ddb967602401c0db02b19e5d38f09e8618fa7f6a1a3f738629baffdc63d9d70d396007d943fd64ae696e5b7e88f2c6d6ec322b461dbddd36efa91d990343b66419cf4832a22dc9ad13021185a1bf007989a50ba3bfd1152b8db899482d3ed498d1b9fae243a3cdae9530d8b29fdb684f70cdc0c9b8527265312603b405e67d59d4b1d654ddc3b7fd5515acb32440dc80903c8474a2c136c":"0281ff7bd1913fcfb652896209ad3e62f5d04a8dfc71eb1698543c52200bd7bbf3c11dd9ff57c299a2f4da172b3d5bd7e29affddf8859be7d50a45537a0df15b17af603d18803fd17134847cba78d83e64bf9fee58364d6124add0541da7bad331cd35fb48186a74bc502ddb967602401c0db02b19e5d38f09e8618fa7f6a1a3f738629baffdc63d9d70d396007d943fd64ae696e5b7e88f2c6d6ec322b461dbddd36efa91d990343b66419cf4832a22dc9ad13021185a1bf007989a50ba3bfd1152b8db899482d3ed498d1b9fae243a3cdae9530d8b29fdb684f70cdc0c9b8527265312603b405e67d59d4b1d654ddc3b7fd5515acb32440dc80903c8474a2c136c"
 
-#ASN.1 Write mpi, 255*8 bits
-#mbedtls_asn1_write_mpi:"fbd1913fcfb652896209ad3e62f5d04a8dfc71eb1698543c52200bd7bbf3c11dd9ff57c299a2f4da172b3d5bd7e29affddf8859be7d50a45537a0df15b17af603d18803fd17134847cba78d83e64bf9fee58364d6124add0541da7bad331cd35fb48186a74bc502ddb967602401c0db02b19e5d38f09e8618fa7f6a1a3f738629baffdc63d9d70d396007d943fd64ae696e5b7e88f2c6d6ec322b461dbddd36efa91d990343b66419cf4832a22dc9ad13021185a1bf007989a50ba3bfd1152b8db899482d3ed498d1b9fae243a3cdae9530d8b29fdb684f70cdc0c9b8527265312603b405e67d59d4b1d654ddc3b7fd5515acb32440dc80903c8474a2c136c":"0282010000fbd1913fcfb652896209ad3e62f5d04a8dfc71eb1698543c52200bd7bbf3c11dd9ff57c299a2f4da172b3d5bd7e29affddf8859be7d50a45537a0df15b17af603d18803fd17134847cba78d83e64bf9fee58364d6124add0541da7bad331cd35fb48186a74bc502ddb967602401c0db02b19e5d38f09e8618fa7f6a1a3f738629baffdc63d9d70d396007d943fd64ae696e5b7e88f2c6d6ec322b461dbddd36efa91d990343b66419cf4832a22dc9ad13021185a1bf007989a50ba3bfd1152b8db899482d3ed498d1b9fae243a3cdae9530d8b29fdb684f70cdc0c9b8527265312603b405e67d59d4b1d654ddc3b7fd5515acb32440dc80903c8474a2c136c"
+ASN.1 Write mpi, 255*8 bits
+mbedtls_asn1_write_mpi:"fbd1913fcfb652896209ad3e62f5d04a8dfc71eb1698543c52200bd7bbf3c11dd9ff57c299a2f4da172b3d5bd7e29affddf8859be7d50a45537a0df15b17af603d18803fd17134847cba78d83e64bf9fee58364d6124add0541da7bad331cd35fb48186a74bc502ddb967602401c0db02b19e5d38f09e8618fa7f6a1a3f738629baffdc63d9d70d396007d943fd64ae696e5b7e88f2c6d6ec322b461dbddd36efa91d990343b66419cf4832a22dc9ad13021185a1bf007989a50ba3bfd1152b8db899482d3ed498d1b9fae243a3cdae9530d8b29fdb684f70cdc0c9b8527265312603b405e67d59d4b1d654ddc3b7fd5515acb32440dc80903c8474a2c136c":"0282010000fbd1913fcfb652896209ad3e62f5d04a8dfc71eb1698543c52200bd7bbf3c11dd9ff57c299a2f4da172b3d5bd7e29affddf8859be7d50a45537a0df15b17af603d18803fd17134847cba78d83e64bf9fee58364d6124add0541da7bad331cd35fb48186a74bc502ddb967602401c0db02b19e5d38f09e8618fa7f6a1a3f738629baffdc63d9d70d396007d943fd64ae696e5b7e88f2c6d6ec322b461dbddd36efa91d990343b66419cf4832a22dc9ad13021185a1bf007989a50ba3bfd1152b8db899482d3ed498d1b9fae243a3cdae9530d8b29fdb684f70cdc0c9b8527265312603b405e67d59d4b1d654ddc3b7fd5515acb32440dc80903c8474a2c136c"
 
 ASN.1 Write mpi, 256*8-1 bits
 mbedtls_asn1_write_mpi:"7bd1913fcfb652896209ad3e62f5d04a8dfc71eb1698543c52200bd7bbf3c11dd9ff57c299a2f4da172b3d5bd7e29affddf8859be7d50a45537a0df15b17af603d18803fd17134847cba78d83e64bf9fee58364d6124add0541da7bad331cd35fb48186a74bc502ddb967602401c0db02b19e5d38f09e8618fa7f6a1a3f738629baffdc63d9d70d396007d943fd64ae696e5b7e88f2c6d6ec322b461dbddd36efa91d990343b66419cf4832a22dc9ad13021185a1bf007989a50ba3bfd1152b8db899482d3ed498d1b9fae243a3cdae9530d8b29fdb684f70cdc0c9b8527265312603b405e67d59d4b1d654ddc3b7fd5515acb32440dc80903c8474a2c136c89":"028201007bd1913fcfb652896209ad3e62f5d04a8dfc71eb1698543c52200bd7bbf3c11dd9ff57c299a2f4da172b3d5bd7e29affddf8859be7d50a45537a0df15b17af603d18803fd17134847cba78d83e64bf9fee58364d6124add0541da7bad331cd35fb48186a74bc502ddb967602401c0db02b19e5d38f09e8618fa7f6a1a3f738629baffdc63d9d70d396007d943fd64ae696e5b7e88f2c6d6ec322b461dbddd36efa91d990343b66419cf4832a22dc9ad13021185a1bf007989a50ba3bfd1152b8db899482d3ed498d1b9fae243a3cdae9530d8b29fdb684f70cdc0c9b8527265312603b405e67d59d4b1d654ddc3b7fd5515acb32440dc80903c8474a2c136c89"
@@ -191,7 +200,7 @@
 mbedtls_asn1_write_string:MBEDTLS_ASN1_OID:"41":"060141"
 
 ASN.1 Write AlgorithmIdentifier, null parameters
-mbedtls_asn1_write_algorithm_identifier:"4f4944":8:"300d06034f4944"
+mbedtls_asn1_write_algorithm_identifier:"4f4944":0:"300706034f49440500"
 
 ASN.1 Write AlgorithmIdentifier, parameters (8 bytes)
 mbedtls_asn1_write_algorithm_identifier:"4f4944":8:"300d06034f4944"
diff --git a/tests/suites/test_suite_asn1write.function b/tests/suites/test_suite_asn1write.function
index 8d5579d..4ed8644 100644
--- a/tests/suites/test_suite_asn1write.function
+++ b/tests/suites/test_suite_asn1write.function
@@ -16,6 +16,8 @@
 int generic_write_start_step( generic_write_data_t *data )
 {
     mbedtls_test_set_step( data->size );
+    mbedtls_free( data->output );
+    data->output = NULL;
     ASSERT_ALLOC( data->output, data->size == 0 ? 1 : data->size );
     data->end = data->output + data->size;
     data->p = data->end;
@@ -45,8 +47,6 @@
     ok = 1;
 
 exit:
-    mbedtls_free( data->output );
-    data->output = NULL;
     return( ok );
 }
 
@@ -63,13 +63,14 @@
     generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
     int ret;
 
-    for( data.size = 0; data.size < expected->len + 1; data.size++ )
+    for( data.size = 0; data.size <= expected->len + 1; data.size++ )
     {
         if( ! generic_write_start_step( &data ) )
             goto exit;
         ret = mbedtls_asn1_write_null( &data.p, data.start );
         if( ! generic_write_finish_step( &data, expected, ret ) )
             goto exit;
+        /* There's no parsing function for NULL. */
     }
 
 exit:
@@ -83,13 +84,21 @@
     generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
     int ret;
 
-    for( data.size = 0; data.size < expected->len + 1; data.size++ )
+    for( data.size = 0; data.size <= expected->len + 1; data.size++ )
     {
         if( ! generic_write_start_step( &data ) )
             goto exit;
         ret = mbedtls_asn1_write_bool( &data.p, data.start, val );
         if( ! generic_write_finish_step( &data, expected, ret ) )
             goto exit;
+#if defined(MBEDTLS_ASN1_PARSE_C)
+        if( ret >= 0 )
+        {
+            int read = 0xdeadbeef;
+            TEST_EQUAL( mbedtls_asn1_get_bool( &data.p, data.end, &read ), 0 );
+            TEST_EQUAL( val, read );
+        }
+#endif /* MBEDTLS_ASN1_PARSE_C */
     }
 
 exit:
@@ -103,13 +112,21 @@
     generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
     int ret;
 
-    for( data.size = 0; data.size < expected->len + 1; data.size++ )
+    for( data.size = 0; data.size <= expected->len + 1; data.size++ )
     {
         if( ! generic_write_start_step( &data ) )
             goto exit;
         ret = mbedtls_asn1_write_int( &data.p, data.start, val );
         if( ! generic_write_finish_step( &data, expected, ret ) )
             goto exit;
+#if defined(MBEDTLS_ASN1_PARSE_C)
+        if( ret >= 0 )
+        {
+            int read = 0xdeadbeef;
+            TEST_EQUAL( mbedtls_asn1_get_int( &data.p, data.end, &read ), 0 );
+            TEST_EQUAL( val, read );
+        }
+#endif /* MBEDTLS_ASN1_PARSE_C */
     }
 
 exit:
@@ -124,13 +141,21 @@
     generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
     int ret;
 
-    for( data.size = 0; data.size < expected->len + 1; data.size++ )
+    for( data.size = 0; data.size <= expected->len + 1; data.size++ )
     {
         if( ! generic_write_start_step( &data ) )
             goto exit;
         ret = mbedtls_asn1_write_enum( &data.p, data.start, val );
         if( ! generic_write_finish_step( &data, expected, ret ) )
             goto exit;
+#if defined(MBEDTLS_ASN1_PARSE_C)
+        if( ret >= 0 )
+        {
+            int read = 0xdeadbeef;
+            TEST_EQUAL( mbedtls_asn1_get_enum( &data.p, data.end, &read ), 0 );
+            TEST_EQUAL( val, read );
+        }
+#endif /* MBEDTLS_ASN1_PARSE_C */
     }
 
 exit:
@@ -142,25 +167,35 @@
 void mbedtls_asn1_write_mpi( data_t *val, data_t *expected )
 {
     generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
-    mbedtls_mpi mpi;
+    mbedtls_mpi mpi, read;
     int ret;
 
     mbedtls_mpi_init( &mpi );
+    mbedtls_mpi_init( &read );
     TEST_ASSERT( mbedtls_mpi_read_binary( &mpi, val->x, val->len ) == 0 );
 
-    for( data.size = 0; data.size < expected->len + 1; data.size++ )
+    for( data.size = 0; data.size <= expected->len + 1; data.size++ )
     {
         if( ! generic_write_start_step( &data ) )
             goto exit;
         ret = mbedtls_asn1_write_mpi( &data.p, data.start, &mpi );
         if( ! generic_write_finish_step( &data, expected, ret ) )
             goto exit;
+#if defined(MBEDTLS_ASN1_PARSE_C)
+        if( ret >= 0 )
+        {
+            TEST_EQUAL( mbedtls_asn1_get_mpi( &data.p, data.end, &read ), 0 );
+            TEST_EQUAL( 0, mbedtls_mpi_cmp_mpi( &mpi, &read ) );
+        }
+#endif /* MBEDTLS_ASN1_PARSE_C */
+        /* Skip some intermediate lengths, they're boring. */
         if( expected->len > 10 && data.size == 8 )
             data.size = expected->len - 2;
     }
 
 exit:
     mbedtls_mpi_free( &mpi );
+    mbedtls_mpi_free( &read );
     mbedtls_free( data.output );
 }
 /* END_CASE */
@@ -171,7 +206,7 @@
     generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
     int ret;
 
-    for( data.size = 0; data.size < expected->len + 1; data.size++ )
+    for( data.size = 0; data.size <= expected->len + 1; data.size++ )
     {
         if( ! generic_write_start_step( &data ) )
             goto exit;
@@ -208,6 +243,8 @@
         }
         if( ! generic_write_finish_step( &data, expected, ret ) )
             goto exit;
+        /* There's no parsing function for octet or character strings. */
+        /* Skip some intermediate lengths, they're boring. */
         if( expected->len > 10 && data.size == 8 )
             data.size = expected->len - 2;
     }
@@ -224,8 +261,11 @@
 {
     generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
     int ret;
+#if defined(MBEDTLS_ASN1_PARSE_C)
+    unsigned char *buf_complete = NULL;
+#endif /* MBEDTLS_ASN1_PARSE_C */
 
-    for( data.size = 0; data.size < expected->len + 1; data.size++ )
+    for( data.size = 0; data.size <= expected->len + 1; data.size++ )
     {
         if( ! generic_write_start_step( &data ) )
             goto exit;
@@ -240,10 +280,69 @@
             ret -= par_len;
         if( ! generic_write_finish_step( &data, expected, ret ) )
             goto exit;
+
+#if defined(MBEDTLS_ASN1_PARSE_C)
+        /* Only do a parse-back test if the parameters aren't too large for
+         * a small-heap environment. The boundary is somewhat arbitrary. */
+        if( ret >= 0 && par_len <= 1234 )
+        {
+            mbedtls_asn1_buf alg = {0, 0, NULL};
+            mbedtls_asn1_buf params = {0, 0, NULL};
+            /* The writing function doesn't write the parameters unless
+             * they're null: it only takes their length as input. But the
+             * parsing function requires the parameters to be present.
+             * Thus make up parameters. */
+            size_t data_len = data.end - data.p;
+            size_t len_complete = data_len + par_len;
+            unsigned char expected_params_tag;
+            size_t expected_params_len;
+            ASSERT_ALLOC( buf_complete, len_complete );
+            unsigned char *end_complete = buf_complete + len_complete;
+            memcpy( buf_complete, data.p, data_len );
+            if( par_len == 0 )
+            {
+                /* mbedtls_asn1_write_algorithm_identifier() wrote a NULL */
+                expected_params_tag = 0x05;
+                expected_params_len = 0;
+            }
+            else if( par_len >= 2 && par_len < 2 + 128 )
+            {
+                /* Write an OCTET STRING with a short length encoding */
+                expected_params_tag = buf_complete[data_len] = 0x04;
+                expected_params_len = par_len - 2;
+                buf_complete[data_len + 1] = (unsigned char) expected_params_len;
+            }
+            else if( par_len >= 4 + 128 && par_len < 3 + 256 * 256 )
+            {
+                /* Write an OCTET STRING with a two-byte length encoding */
+                expected_params_tag = buf_complete[data_len] = 0x04;
+                expected_params_len = par_len - 4;
+                buf_complete[data_len + 1] = 0x82;
+                buf_complete[data_len + 2] = (unsigned char) ( expected_params_len >> 8 );
+                buf_complete[data_len + 3] = (unsigned char) ( expected_params_len );
+            }
+            else
+            {
+                TEST_ASSERT( ! "Bad test data: invalid length of ASN.1 element" );
+            }
+            unsigned char *p = buf_complete;
+            TEST_EQUAL( mbedtls_asn1_get_alg( &p, end_complete,
+                                              &alg, &params ), 0 );
+            TEST_EQUAL( alg.tag, MBEDTLS_ASN1_OID );
+            ASSERT_COMPARE( alg.p, alg.len, oid->x, oid->len );
+            TEST_EQUAL( params.tag, expected_params_tag );
+            TEST_EQUAL( params.len, expected_params_len );
+            mbedtls_free( buf_complete );
+            buf_complete = NULL;
+        }
+#endif /* MBEDTLS_ASN1_PARSE_C */
     }
 
 exit:
     mbedtls_free( data.output );
+#if defined(MBEDTLS_ASN1_PARSE_C)
+    mbedtls_free( buf_complete );
+#endif /* MBEDTLS_ASN1_PARSE_C */
 }
 /* END_CASE */
 
@@ -308,18 +407,63 @@
                    const unsigned char *buf, size_t bits ) =
         ( is_named ? mbedtls_asn1_write_named_bitstring :
           mbedtls_asn1_write_bitstring );
+#if defined(MBEDTLS_ASN1_PARSE_C)
+    unsigned char *masked_bitstring = NULL;
+#endif /* MBEDTLS_ASN1_PARSE_C */
 
-    for( data.size = 0; data.size < expected->len + 1; data.size++ )
+    /* The API expects `bitstring->x` to contain `bits` bits. */
+    size_t byte_length = ( bits + 7 ) / 8;
+    TEST_ASSERT( bitstring->len >= byte_length );
+
+#if defined(MBEDTLS_ASN1_PARSE_C)
+    ASSERT_ALLOC( masked_bitstring, byte_length );
+    if( byte_length != 0 )
+    {
+        memcpy( masked_bitstring, bitstring->x, byte_length );
+        if( bits % 8 != 0 )
+            masked_bitstring[byte_length - 1] &= ~( 0xff >> ( bits % 8 ) );
+    }
+    size_t value_bits = bits;
+    if( is_named )
+    {
+        /* In a named bit string, all trailing 0 bits are removed. */
+        while( byte_length > 0 && masked_bitstring[byte_length - 1] == 0 )
+            --byte_length;
+        value_bits = 8 * byte_length;
+        if( byte_length > 0 )
+        {
+            unsigned char last_byte = masked_bitstring[byte_length - 1];
+            for( unsigned b = 1; b < 0xff && ( last_byte & b ) == 0; b <<= 1 )
+                --value_bits;
+        }
+    }
+#endif /* MBEDTLS_ASN1_PARSE_C */
+
+    for( data.size = 0; data.size <= expected->len + 1; data.size++ )
     {
         if( ! generic_write_start_step( &data ) )
             goto exit;
         ret = ( *func )( &data.p, data.start, bitstring->x, bits );
         if( ! generic_write_finish_step( &data, expected, ret ) )
             goto exit;
+#if defined(MBEDTLS_ASN1_PARSE_C)
+        if( ret >= 0 )
+        {
+            mbedtls_asn1_bitstring read = {0, 0, NULL};
+            TEST_EQUAL( mbedtls_asn1_get_bitstring( &data.p, data.end,
+                                                    &read ), 0 );
+            ASSERT_COMPARE( read.p, read.len,
+                            masked_bitstring, byte_length );
+            TEST_EQUAL( read.unused_bits, 8 * byte_length - value_bits );
+        }
+#endif /* MBEDTLS_ASN1_PARSE_C */
     }
 
 exit:
     mbedtls_free( data.output );
+#if defined(MBEDTLS_ASN1_PARSE_C)
+    mbedtls_free( masked_bitstring );
+#endif /* MBEDTLS_ASN1_PARSE_C */
 }
 /* END_CASE */
 
diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.data b/tests/suites/test_suite_psa_crypto_persistent_key.data
index b250634..6d208e9 100644
--- a/tests/suites/test_suite_psa_crypto_persistent_key.data
+++ b/tests/suites/test_suite_psa_crypto_persistent_key.data
@@ -1,3 +1,8 @@
+# Note that if you need to make a change that affects how keys are
+# stored, this may indicate that the key store is changing in a
+# backward-incompatible way! Think carefully about backward compatibility
+# before changing how test data is constructed or validated.
+
 Format for storage: RSA private key
 format_storage_data_check:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"505341004b455900000000000100000001700004010000000000000700000006620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN
 
diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function
index bd9b9c9..08db34a 100644
--- a/tests/suites/test_suite_psa_crypto_persistent_key.function
+++ b/tests/suites/test_suite_psa_crypto_persistent_key.function
@@ -5,6 +5,11 @@
  * on the the storage format. On the other hand, these tests treat the storage
  * subsystem as a black box, and in particular have no reliance on the
  * internals of the ITS implementation.
+ *
+ * Note that if you need to make a change that affects how files are
+ * stored, this may indicate that the key store is changing in a
+ * backward-incompatible way! Think carefully about backward compatibility
+ * before changing how test data is constructed or validated.
  */
 
 #include <stdint.h>
diff --git a/tests/suites/test_suite_psa_its.function b/tests/suites/test_suite_psa_its.function
index e16c050..12878b5 100644
--- a/tests/suites/test_suite_psa_its.function
+++ b/tests/suites/test_suite_psa_its.function
@@ -3,6 +3,11 @@
 /* This test file is specific to the ITS implementation in PSA Crypto
  * on top of stdio. It expects to know what the stdio name of a file is
  * based on its keystore name.
+ *
+ * Note that if you need to make a change that affects how files are
+ * stored, this may indicate that the key store is changing in a
+ * backward-incompatible way! Think carefully about backward compatibility
+ * before changing how test data is constructed or validated.
  */
 
 #include "../library/psa_crypto_its.h"
diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data
index 91175d7..1b36d32 100644
--- a/tests/suites/test_suite_ssl.data
+++ b/tests/suites/test_suite_ssl.data
@@ -246,7 +246,7 @@
 handshake_version:0:MBEDTLS_SSL_VERSION_TLS1_2:MBEDTLS_SSL_VERSION_TLS1_2:MBEDTLS_SSL_VERSION_TLS1_2:MBEDTLS_SSL_VERSION_TLS1_2:MBEDTLS_SSL_VERSION_TLS1_2
 
 Handshake, tls1_3
-depends_on:MBEDTLS_SSL_PROTO_TLS1_3
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3:!MBEDTLS_SSL_PROTO_TLS1_2
 handshake_version:0:MBEDTLS_SSL_VERSION_TLS1_3:MBEDTLS_SSL_VERSION_TLS1_3:MBEDTLS_SSL_VERSION_TLS1_3:MBEDTLS_SSL_VERSION_TLS1_3:MBEDTLS_SSL_VERSION_TLS1_3
 
 Handshake, ECDHE-RSA-WITH-AES-256-GCM-SHA384
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index f62fba3..eb9e9aa 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -294,6 +294,10 @@
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_SHA512_C:MBEDTLS_RSA_C:!MBEDTLS_X509_REMOVE_INFO
 mbedtls_x509_csr_info:"data_files/server1.req.sha512":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=PolarSSL Server 1\nsigned using  \: RSA with SHA-512\nRSA key size  \: 2048 bits\n"
 
+X509 CSR Information RSA with SHA-256, containing commas
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_SHA256_C:MBEDTLS_RSA_C:MBEDTS_X509_INFO
+mbedtls_x509_csr_info:"data_files/server1.req.commas.sha256":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL\, Commas, CN=PolarSSL Server 1\nsigned using  \: RSA with SHA-256\nRSA key size  \: 2048 bits\n"
+
 X509 CSR Information EC with SHA1
 depends_on:MBEDTLS_ECDSA_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA1_C:!MBEDTLS_X509_REMOVE_INFO
 mbedtls_x509_csr_info:"data_files/server5.req.sha1":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: ECDSA with SHA1\nEC key size   \: 256 bits\n"
@@ -375,6 +379,30 @@
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
 mbedtls_x509_dn_gets:"data_files/server2.crt":"issuer":"C=NL, O=PolarSSL, CN=PolarSSL Test CA"
 
+X509 Get Distinguished Name #5
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
+mbedtls_x509_dn_gets:"data_files/server1.commas.crt":"subject":"C=NL, O=PolarSSL\, Commas, CN=PolarSSL Server 1"
+
+X509 Get Modified DN #1
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
+mbedtls_x509_dn_gets_subject_replace:"data_files/server1.crt":"Modified":"C=NL, O=Modified, CN=PolarSSL Server 1":0
+
+X509 Get Modified DN #2 Name exactly 255 bytes
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
+mbedtls_x509_dn_gets_subject_replace:"data_files/server1.crt":"123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345":"C=NL, O=123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345, CN=PolarSSL Server 1":0
+
+X509 Get Modified DN #3 Name exceeds 255 bytes
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
+mbedtls_x509_dn_gets_subject_replace:"data_files/server1.crt":"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456":"":MBEDTLS_ERR_X509_BUFFER_TOO_SMALL
+
+X509 Get Modified DN #4 Name exactly 255 bytes, with comma requiring escaping
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
+mbedtls_x509_dn_gets_subject_replace:"data_files/server1.crt":"1234567890,1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234":"":MBEDTLS_ERR_X509_BUFFER_TOO_SMALL
+
+X509 Get Modified DN #5 Name exactly 255 bytes, ending with comma requiring escaping
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
+mbedtls_x509_dn_gets_subject_replace:"data_files/server1.crt":"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234,":"":MBEDTLS_ERR_X509_BUFFER_TOO_SMALL
+
 X509 Get Next DN #1 No Multivalue RDNs
 mbedtls_x509_dn_get_next:"C=NL, O=PolarSSL, CN=PolarSSL Server 1":0:"C O CN":3:"C=NL, O=PolarSSL, CN=PolarSSL Server 1"
 
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index a9d7e47..3bb68d9 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -758,6 +758,37 @@
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_X509_REMOVE_INFO */
+void mbedtls_x509_dn_gets_subject_replace( char * crt_file, char * new_subject_ou, char * result_str, int ret )
+{
+    mbedtls_x509_crt   crt;
+    char buf[2000];
+    int res = 0;
+
+    mbedtls_x509_crt_init( &crt );
+    memset( buf, 0, 2000 );
+
+    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
+    crt.subject.next->val.p = (unsigned char *) new_subject_ou;
+    crt.subject.next->val.len = strlen( new_subject_ou );
+
+    res =  mbedtls_x509_dn_gets( buf, 2000, &crt.subject );
+
+    if ( ret != 0 )
+    {
+        TEST_ASSERT( res == ret );
+    }
+    else
+    {
+        TEST_ASSERT( res != -1 );
+        TEST_ASSERT( res != -2 );
+        TEST_ASSERT( strcmp( buf, result_str ) == 0 );
+    }
+exit:
+    mbedtls_x509_crt_free( &crt );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_X509_REMOVE_INFO */
 void mbedtls_x509_dn_gets( char * crt_file, char * entity, char * result_str )
 {
     mbedtls_x509_crt   crt;
@@ -854,7 +885,6 @@
         mbedtls_free( parsed_prv );
     }
 }
-
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
diff --git a/tests/suites/test_suite_x509write.data b/tests/suites/test_suite_x509write.data
index 8d9a11a..91fdd86 100644
--- a/tests/suites/test_suite_x509write.data
+++ b/tests/suites/test_suite_x509write.data
@@ -139,7 +139,7 @@
 x509_crt_check:"data_files/server5.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca2.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=Polarssl Test EC CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA256:0:0:0:0:1:-1:"":2:0:"data_files/test-ca2.crt"
 
 X509 String to Names #1
-mbedtls_x509_string_to_names:"C=NL,O=Offspark\, Inc., OU=PolarSSL":"C=NL, O=Offspark, Inc., OU=PolarSSL":0
+mbedtls_x509_string_to_names:"C=NL,O=Offspark\, Inc., OU=PolarSSL":"C=NL, O=Offspark\, Inc., OU=PolarSSL":0
 
 X509 String to Names #2
 mbedtls_x509_string_to_names:"C=NL, O=Offspark, Inc., OU=PolarSSL":"":MBEDTLS_ERR_X509_UNKNOWN_OID