Merge pull request #5521 from AndrzejKurek/rsa-pss-use-psa

Make RSA-PSS verification use PSA with MBEDTLS_USE_PSA_CRYPTO
diff --git a/ChangeLog.d/PSA-test-suites-NOT-using-UID-0.txt b/ChangeLog.d/PSA-test-suites-NOT-using-UID-0.txt
new file mode 100644
index 0000000..9acbb0a
--- /dev/null
+++ b/ChangeLog.d/PSA-test-suites-NOT-using-UID-0.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Fix unit tests that used 0 as the file UID. This failed on some
+     implementations of PSA ITS. Fixes #3838.
diff --git a/ChangeLog.d/mbedtls_pem_get_der.txt b/ChangeLog.d/mbedtls_pem_get_der.txt
new file mode 100644
index 0000000..b03b058
--- /dev/null
+++ b/ChangeLog.d/mbedtls_pem_get_der.txt
@@ -0,0 +1,2 @@
+Features
+   * Add accessor to get the raw buffer pointer from a PEM context.
diff --git a/ChangeLog.d/mbedtls_ssl_ticket_rotate.txt b/ChangeLog.d/mbedtls_ssl_ticket_rotate.txt
new file mode 100644
index 0000000..b843bfd
--- /dev/null
+++ b/ChangeLog.d/mbedtls_ssl_ticket_rotate.txt
@@ -0,0 +1,2 @@
+Features
+   * Add mbedtls_ssl_ticket_rotate() for external ticket rotation.
diff --git a/ChangeLog.d/tls13_and_use_psa_crypto.txt b/ChangeLog.d/tls13_and_use_psa_crypto.txt
new file mode 100644
index 0000000..6198804
--- /dev/null
+++ b/ChangeLog.d/tls13_and_use_psa_crypto.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * The TLS 1.3 implementation is now compatible with the
+     MBEDTLS_USE_PSA_CRYPTO configuration option.
diff --git a/ChangeLog.d/use-psa-ecdhe-curve.txt b/ChangeLog.d/use-psa-ecdhe-curve.txt
new file mode 100644
index 0000000..cc432bd
--- /dev/null
+++ b/ChangeLog.d/use-psa-ecdhe-curve.txt
@@ -0,0 +1,7 @@
+Bugfix
+   * Fix a bug in (D)TLS curve negotiation: when MBEDTLS_USE_PSA_CRYPTO was
+     enabled and an ECDHE-ECDSA or ECDHE-RSA key exchange was used, the
+     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.
diff --git a/docs/architecture/psa-migration/psa-limitations.md b/docs/architecture/psa-migration/psa-limitations.md
new file mode 100644
index 0000000..a7c4afb
--- /dev/null
+++ b/docs/architecture/psa-migration/psa-limitations.md
@@ -0,0 +1,394 @@
+This document lists current limitations of the PSA Crypto API (as of version
+1.1) that may impact our ability to (1) use it for all crypto operations in
+TLS and X.509 and (2) support isolation of all long-term secrets in TLS (that
+is, goals G1 and G2 in [strategy.md](strategy.md) in the same directory).
+
+This is supposed to be a complete list, based on a exhaustive review of crypto
+operations done in TLS and X.509 code, but of course it's still possible that
+subtle-but-important issues have been missed. The only way to be really sure
+is, of course, to actually do the migration work.
+
+Limitations relevant for G1 (performing crypto operations)
+==========================================================
+
+Restartable ECC operations
+--------------------------
+
+There is currently no support for that in PSA at all. API design, as well as
+implementation, would be non-trivial.
+
+Currently, `MBEDTLS_USE_PSA_CRYPTO` is simply incompatible with
+`MBEDTLS_ECP_RESTARTABLE`.
+
+Things that are in the API but not implemented yet
+--------------------------------------------------
+
+PSA Crypto has an API for FFDH, but it's not implemented in Mbed TLS yet.
+(Regarding FFDH, see the next section as well.) See issue [3261][ffdh] on
+github.
+
+[ffdh]: https://github.com/ARMmbed/mbedtls/issues/3261
+
+PSA Crypto has an experimental API for EC J-PAKE, but it's not implemented in
+Mbed TLS yet. See the [EC J-PAKE follow-up EPIC][ecjp] on github.
+
+[ecjp]: https://github.com/orgs/ARMmbed/projects/18#column-15836385
+
+Arbitrary parameters for FFDH
+-----------------------------
+
+(See also the first paragraph in the previous section.)
+
+Currently, the PSA Crypto API can only perform FFDH with a limited set of
+well-known parameters (some of them defined in the spec, but implementations
+are free to extend that set).
+
+TLS 1.2 (and earlier) on the other hand have the server send explicit
+parameters (P and G) in its ServerKeyExchange message. This has been found to
+be suboptimal for security, as it is prohibitively hard for the client to
+verify the strength of these parameters. This led to the development of RFC
+7919 which allows use of named groups in TLS 1.2 - however as this is only an
+extension, servers can still send custom parameters if they don't support the
+extension.
+
+In TLS 1.3 the situation will be simpler: named groups are the only
+option, so the current PSA Crypto API is a good match for that. (Not
+coincidentally, all the groups used by RFC 7919 and TLS 1.3 are included
+in the PSA specification.)
+
+There are several options here:
+
+1. Implement support for custom FFDH parameters in PSA Crypto: this would pose
+   non-trivial API design problem, but most importantly seems backwards, as
+the crypto community is moving away from custom FFDH parameters.
+2. Drop the DHE-RSA and DHE-PSK key exchanges in TLS 1.2 when moving to PSA.
+3. Implement RFC 7919, support DHE-RSA and DHE-PSK only in conjunction with it
+   when moving to PSA. We can modify our server so that it only selects a DHE
+   ciphersuite if the client offered name FFDH groups; unfortunately
+client-side the only option is to offer named groups and break the handshake
+if the server didn't take on our offer. This is not fully satisfying, but is
+perhaps the least unsatisfying option in terms of result; it's also probably
+the one that requires the most work, but it would deliver value beyond PSA
+migration by implementing RFC 7919.
+
+RSA-PSS parameters
+------------------
+
+RSA-PSS signatures are defined by PKCS#1 v2, re-published as RFC 8017
+(previously RFC 3447).
+
+As standardized, the signature scheme takes several parameters, in addition to
+the hash algorithm potentially used to hash the message being signed:
+- a hash algorithm used for the encoding function
+- a mask generation function
+  - most commonly MGF1, which in turn is parametrized by a hash algorithm
+- a salt length
+- a trailer field - the value is fixed to 0xBC by PKCS#1 v2.1, but was left
+  configurable in the original scheme; 0xBC is used everywhere in pratice.
+
+Both the existing `mbedtls_` API and the PSA API support only MGF1 as the
+generation function (and only 0xBC as the trailer field), but there are
+discrepancies in handling the salt length and which of the various hash
+algorithms can differ from each other.
+
+### API comparison
+
+- RSA:
+  - signature: `mbedtls_rsa_rsassa_pss_sign()`
+    - message hashed externally
+    - encoding hash = MGF1 hash (from context, or argument = message hash)
+    - salt length: always using the maximum legal value
+  - signature: `mbedtls_rsa_rsassa_pss_sign_ext()`
+    - message hashed externally
+    - encoding hash = MGF1 hash (from context, or argument = message hash)
+    - salt length: specified explicitly
+  - verification: `mbedtls_rsassa_pss_verify()`
+    - message hashed externally
+    - encoding hash = MGF1 hash (from context, or argument = message hash)
+    - salt length: any valid length accepted
+  - verification: `mbedtls_rsassa_pss_verify_ext()`
+    - message hashed externally
+    - encoding hash = MGF1 hash from dedicated argument
+    - expected salt length: specified explicitly, can specify "ANY"
+- PK:
+  - signature: not supported
+  - verification: `mbedtls_pk_verify_ext()`
+    - message hashed externally
+    - encoding hash = MGF1 hash, specified explicitly
+    - expected salt length: specified explicitly, can specify "ANY"
+- PSA:
+  - algorithm specification:
+    - hash alg used for message hashing, encoding and MGF1
+    - salt length can be either "standard" (<= hashlen, see note) or "any"
+  - signature generation:
+    - salt length: always <= hashlen (see note) and random salt
+  - verification:
+    - salt length: either <= hashlen (see note), or any depending on algorithm
+
+Note: above, "<= hashlen" means that hashlen is used if possible, but if it
+doesn't fit because the key is too short, then the maximum length that fits is
+used.
+
+The RSA/PK API is in principle more flexible than the PSA Crypto API. The
+following sub-sections study whether and how this matters in practice.
+
+### Use in X.509
+
+RFC 4055 Section 3.1 defines the encoding of RSA-PSS that's used in X.509.
+It allows independently specifying the message hash (also used for encoding
+hash), the MGF (and its hash if MGF1 is used), and the salt length (plus an
+extra parameter "trailer field" that doesn't vary in practice"). These can be
+encoded as part of the key, and of the signature. If both encoding are
+presents, all values must match except possibly for the salt length, where the
+value from the signature parameters is used.
+
+In Mbed TLS, RSA-PSS parameters can be parsed and displayed for various
+objects (certificates, CRLs, CSRs). During parsing, the following properties
+are enforced:
+- the extra "trailer field" parameter must have its default value
+- the mask generation function is MGF1
+- encoding hash = message hashing algorithm (may differ from MGF1 hash)
+
+When it comes to cryptographic operations, only two things are supported:
+- verifying the signature on a certificate from its parent;
+- verifying the signature on a CRL from the issuing CA.
+
+The verification is done using `mbedtls_pk_verify_ext()`.
+
+Note: since X.509 parsing ensures that message hash = encoding hash, and
+`mbedtls_pk_verify_ext()` uses encoding hash = mgf1 hash, it looks like all
+three hash algorithms must be equal, which would be good news as it would
+match a limitation of the PSA API.
+
+It is unclear what parameters people use in practice. It looks like by default
+OpenSSL picks saltlen = keylen - hashlen - 2 (tested with openssl 1.1.1f).
+The `certool` command provided by GnuTLS seems to be picking saltlen = hashlen
+by default (tested with GnuTLS 3.6.13). FIPS 186-4 requires 0 <= saltlen <=
+hashlen.
+
+### Use in TLS
+
+In TLS 1.2 (or lower), RSA-PSS signatures are never used, except via X.509.
+
+In TLS 1.3, RSA-PSS signatures can be used directly in the protocol (in
+addition to indirect use via X.509). It has two sets of three signature
+algorithm identifiers (for SHA-256, SHA-384 and SHA-512), depending of what
+the OID of the public key is (rsaEncryption or RSASSA-PSS).
+
+In both cases, it specifies that:
+- the mask generation function is MGF1
+- all three hashes are equal
+- the length of the salt MUST be equal to the length of the digest algorithm
+
+When signing, the salt length picked by PSA is the one required by TLS 1.3
+(unless the key is unreasonably small).
+
+When verifying signatures, PSA will by default enforce the salt len is the one
+required by TLS 1.3.
+
+### Current testing - X509
+
+All test files use the default trailer field of 0xBC, as enforced by our
+parser. (There's a negative test for that using the
+`x509_parse_rsassa_pss_params` test function and hex data.)
+
+Files with "bad" in the name are expected to be invalid and rejected in tests.
+
+**Test certificates:**
+
+server9-bad-mgfhash.crt (announcing mgf1(sha224), signed with another mgf)
+         Hash Algorithm: sha256
+         Mask Algorithm: mgf1 with sha224
+          Salt Length: 0xDE
+server9-bad-saltlen.crt (announcing saltlen = 0xDE, signed with another len)
+         Hash Algorithm: sha256
+         Mask Algorithm: mgf1 with sha256
+          Salt Length: 0xDE
+server9-badsign.crt (one bit flipped in the signature)
+         Hash Algorithm: sha1 (default)
+         Mask Algorithm: mgf1 with sha1 (default)
+          Salt Length: 0xEA
+server9-defaults.crt
+         Hash Algorithm: sha1 (default)
+         Mask Algorithm: mgf1 with sha1 (default)
+          Salt Length: 0x14 (default)
+server9-sha224.crt
+         Hash Algorithm: sha224
+         Mask Algorithm: mgf1 with sha224
+          Salt Length: 0xE2
+server9-sha256.crt
+         Hash Algorithm: sha256
+         Mask Algorithm: mgf1 with sha256
+          Salt Length: 0xDE
+server9-sha384.crt
+         Hash Algorithm: sha384
+         Mask Algorithm: mgf1 with sha384
+          Salt Length: 0xCE
+server9-sha512.crt
+         Hash Algorithm: sha512
+         Mask Algorithm: mgf1 with sha512
+          Salt Length: 0xBE
+server9-with-ca.crt
+         Hash Algorithm: sha1 (default)
+         Mask Algorithm: mgf1 with sha1 (default)
+          Salt Length: 0xEA
+server9.crt
+         Hash Algorithm: sha1 (default)
+         Mask Algorithm: mgf1 with sha1 (default)
+          Salt Length: 0xEA
+
+These certificates are signed with a 2048-bit key. It appears that they are
+all using saltlen = keylen - hashlen - 2, except for server9-defaults which is
+using saltlen = hashlen.
+
+**Test CRLs:**
+
+crl-rsa-pss-sha1-badsign.pem
+         Hash Algorithm: sha1 (default)
+         Mask Algorithm: mgf1 with sha1 (default)
+          Salt Length: 0xEA
+crl-rsa-pss-sha1.pem
+         Hash Algorithm: sha1 (default)
+         Mask Algorithm: mgf1 with sha1 (default)
+          Salt Length: 0xEA
+crl-rsa-pss-sha224.pem
+         Hash Algorithm: sha224
+         Mask Algorithm: mgf1 with sha224
+          Salt Length: 0xE2
+crl-rsa-pss-sha256.pem
+         Hash Algorithm: sha256
+         Mask Algorithm: mgf1 with sha256
+          Salt Length: 0xDE
+crl-rsa-pss-sha384.pem
+         Hash Algorithm: sha384
+         Mask Algorithm: mgf1 with sha384
+          Salt Length: 0xCE
+crl-rsa-pss-sha512.pem
+         Hash Algorithm: sha512
+         Mask Algorithm: mgf1 with sha512
+          Salt Length: 0xBE
+
+These CRLs are signed with a 2048-bit key. It appears that they are
+all using saltlen = keylen - hashlen - 2.
+
+**Test CSRs:**
+
+server9.req.sha1
+         Hash Algorithm: sha1 (default)
+         Mask Algorithm: mgf1 with sha1 (default)
+          Salt Length: 0x6A
+server9.req.sha224
+         Hash Algorithm: sha224
+         Mask Algorithm: mgf1 with sha224
+          Salt Length: 0x62
+server9.req.sha256
+         Hash Algorithm: sha256
+         Mask Algorithm: mgf1 with sha256
+          Salt Length: 0x5E
+server9.req.sha384
+         Hash Algorithm: sha384
+         Mask Algorithm: mgf1 with sha384
+          Salt Length: 0x4E
+server9.req.sha512
+         Hash Algorithm: sha512
+         Mask Algorithm: mgf1 with sha512
+          Salt Length: 0x3E
+
+These CSRss are signed with a 2048-bit key. It appears that they are
+all using saltlen = keylen - hashlen - 2.
+
+### Possible courses of action
+
+There's no question about what to do with TLS (any version); the only question
+is about X.509 signature verification. Options include:
+
+1. Doing all verifications with `PSA_ALG_RSA_PSS_ANY_SALT` - while this
+   wouldn't cause a concrete security issue, this would be non-compliant.
+2. Doing verifications with `PSA_ALG_RSA_PSS` when we're lucky and the encoded
+   saltlen happens to match hashlen, and falling back to `ANY_SALT` otherwise.
+Same issue as with the previous point, except more contained.
+3. Reject all certificates with saltlen != hashlen. This includes all
+   certificates generate with OpenSSL using the default parameters, so it's
+probably not acceptable.
+4. Request an extension to the PSA Crypto API and use one of the above options
+   in the meantime. Such an extension seems inconvenient and not motivated by
+strong security arguments, so it's unclear whether it would be accepted.
+
+HKDF: Expand not exposed on its own (TLS 1.3)
+---------------------------------------------
+
+The HKDF function uses and Extract-then-Expand approch, that is:
+
+        HKDF(x, ...) = HKDF-Expand(HKDF-Extract(x, ...), ...)
+
+Only the full HKDF function is safe in general, however there are cases when
+one case safely use the individual Extract and Expand; the TLS 1.3 key
+schedule does so. Specifically, looking at the [hierarchy of secrets][13hs]
+is seems that Expand and Extract are always chained, so that this hierarchy
+can be implemented using only the full HKDF. However, looking at the
+derivation of traffic keys (7.3) and the update mechanism (7.2) it appears
+that calls to HKDF-Expand are iterated without any intermediated call to
+HKDF-Extract : that is, the traffic keys are computed as
+
+        HKDF-Expand(HKDF-Expand(HKDF-Extract(...)))
+
+(with possibly more than two Expands in a row with update).
+
+[13hs]: https://datatracker.ietf.org/doc/html/rfc8446#page-93
+
+In the short term (early 2022), we'll work around that by re-implementing HKDF
+in `ssl_tls13_keys.c` based on the `psa_mac_` APIs (for HMAC).
+
+In the long term, it is desirable to extend the PSA API. See
+https://github.com/ARM-software/psa-crypto-api/issues/539
+
+Limitations relevant for G2 (isolation of long-term secrets)
+============================================================
+
+Custom key derivations for mixed-PSK handshake
+----------------------------------------------
+
+Currently, `MBEDTLS_USE_PSA_CRYPTO` enables the new configuration function
+`mbedtls_ssl_conf_psk_opaque()` which allows a PSA-held key to be used for the
+(pure) `PSK` key exchange in TLS 1.2. This requires that the derivation of the
+Master Secret (MS) be done on the PSA side. To support this, an algorithm
+family `PSA_ALG_TLS12_PSK_TO_MS(hash_alg)` was added to PSA Crypto.
+
+If we want to support key isolation for the "mixed PSK" key exchanges:
+DHE-PSK, RSA-PSK, ECDHE-PSK, where the PSK is concatenated with the result of
+a DH key agreement (resp. RSA decryption) to form the pre-master secret (PMS)
+from which the MS is derived. If the value of the PSK is to remain hidden, we
+need the derivation PSK + secondary secret -> MS to be implemented as an
+ad-hoc PSA key derivation algorithm.
+
+Adding this new, TLS-specific, key derivation algorithm to PSA Crypto should
+be no harder than it was to add `PSA_ALG_TLS12_PSK_TO_MS()` but still requires
+an extension to PSA Crypto.
+
+Note: looking at RFCs 4279 and 5489, it appears that the structure of the PMS
+is always the same: 2-byte length of the secondary secret, secondary secret,
+2-byte length of the PSK, PSK. So, a single key derivation algorithm should be
+able to cover the 3 key exchanges DHE-PSK, RSA-PSK and ECDHE-PSK. (That's a
+minor gain: adding 3 algorithms would not be a blocker anyway.)
+
+Note: if later we want to also isolate short-term secret (G3), the "secondary
+secret" (output of DHE/ECDHE key agreement or RSA decryption) could be a
+candidate. This wouldn't be a problem as the PSA key derivation API always
+allows inputs from key slots. (Tangent: the hard part in isolating the result
+of RSA decryption would be still checking that is has the correct format:
+48 bytes, the first two matching the TLS version - note that this is timing
+sensitive.)
+
+HKDF: Expand not exposed on its own (TLS 1.3)
+---------------------------------------------
+
+See the section with the same name in the G1 part above for background.
+
+The work-around mentioned there works well enough just for acceleration, but
+is not sufficient for key isolation or generally proper key management (it
+requires marking keys are usable for HMAC while they should only be used for
+key derivation).
+
+The obvious long-term solution is to make HKDF-Expand available as a new KDF
+(in addition to the full HKDF) in PSA (with appropriate warnings in the
+documentation).
diff --git a/docs/architecture/psa-migration/strategy.md b/docs/architecture/psa-migration/strategy.md
new file mode 100644
index 0000000..205c6cd
--- /dev/null
+++ b/docs/architecture/psa-migration/strategy.md
@@ -0,0 +1,377 @@
+This document explains the strategy that was used so far in starting the
+migration to PSA Crypto and mentions future perspectives and open questions.
+
+Goals
+=====
+
+Several benefits are expected from migrating to PSA Crypto:
+
+G1. Use PSA Crypto drivers when available.
+G2. Allow isolation of long-term secrets (for example, private keys).
+G3. Allow isolation of short-term secrets (for example, TLS session keys).
+G4. Have a clean, unified API for Crypto (retire the legacy API).
+G5. Code size: compile out our implementation when a driver is available.
+
+Currently, some parts of (G1) and (G2) are implemented when
+`MBEDTLS_USE_PSA_CRYPTO` is enabled. For (G2) to take effect, the application
+needs to be changed to use new APIs.
+
+Generally speaking, the numbering above doesn't mean that each goal requires
+the preceding ones to be completed, for example G2-G5 could be done in any
+order; however they all either depend on G1 or are just much more convenient
+if G1 is done before (note that this is not a dependency on G1 being complete,
+it's more like each bit of G2-G5 is helped by some specific bit in G1).
+
+So, a solid intermediate goal would be to complete (G1) when
+`MBEDTLS_USA_PSA_CRYPTO` is enabled - that is, all crypto operations in X.509
+and TLS would be done via the PSA Crypto API.
+
+Compile-time options
+====================
+
+We currently have two compile-time options that are relevant to the migration:
+
+- `MBEDTLS_PSA_CRYPTO_C` - enabled by default, controls the presence of the PSA
+  Crypto APIs.
+- `MBEDTLS_USE_PSA_CRYPTO` - disabled by default (enabled in "full" config),
+  controls usage of PSA Crypto APIs to perform operations in X.509 and TLS
+(G1 above), as well as the availability of some new APIs (G2 above).
+
+The reasons why `MBEDTLS_USE_PSA_CRYPTO` is optional and disabled by default
+are:
+- it's incompatible with `MBEDTLS_ECP_RESTARTABLE`;
+- historical: used to be incompatible
+  `MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER` (fixed early 2022, see
+    <https://github.com/ARMmbed/mbedtls/issues/5259>);
+- it does not work well with `MBEDTLS_PSA_CRYPTO_CONFIG` (could compile with
+  both of them, but then `MBEDTLS_PSA_CRYPTO_CONFIG` won't have the desired
+effect)
+- to avoid a hard/default dependency of TLS, X.509 and PK on
+  `MBEDTLS_PSA_CRYPTO_C`, for backward compatibility reasons:
+  - when `MBEDTLS_PSA_CRYPTO_C` is enabled and used, applications need to call
+    `psa_crypto_init()` before TLS/X.509 uses PSA functions
+  - `MBEDTLS_PSA_CRYPTO_C` has a hard depend on `MBEDTLS_ENTROPY_C ||
+    MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` but it's
+    currently possible to compilte TLS and X.509 without any of the options.
+    Also, we can't just auto-enable `MBEDTLS_ENTROPY_C` as it doesn't build
+    out of the box on all platforms, and even less
+    `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` as it requires a user-provided RNG
+    function.
+
+The downside of this approach is that until we feel ready to make
+`MBDEDTLS_USE_PSA_CRYPTO` non-optional (always enabled), we have to maintain
+two versions of some parts of the code: one using PSA, the other using the
+legacy APIs. However, see next section for strategies that can lower that
+cost. The rest of this section explains the reasons for the
+incompatibilities mentioned above.
+
+In the medium term (writing this in early 2020), we're going to look for ways
+to make `MBEDTLS_USE_PSA_CRYPTO` non-optional (always enabled).
+
+### `MBEDTLS_ECP_RESTARTABLE`
+
+Currently this option controls not only the presence of restartable APIs in
+the crypto library, but also their use in the TLS and X.509 layers. Since PSA
+Crypto does not support restartable operations, there's a clear conflict: the
+TLS and X.509 layers can't both use only PSA APIs and get restartable
+behaviour.
+
+Supporting this in PSA is on our roadmap (it's been requested). But it's way
+below generalizing support for `MBEDTLS_USE_PSA_CRYPTO` for “mainstream” use
+cases on our priority list. So in the medium term `MBEDTLS_ECP_RESTARTABLE` is
+incompatible with `MBEDTLS_USE_PSA_CRYPTO`.
+
+Note: it is possible to make the options compatible at build time simply by
+deciding that when `USE_PSA_CRYPTO` is enabled, PSA APIs are used except if
+restartable behaviour was requested at run-time (in addition to enabling
+`MBEDTLS_ECP_RESTARTABLE` in the build).
+
+### `MBEDTLS_PSA_CRYPTO_CONFIG`
+
+(This section taken from a comment by Gilles.)
+
+X509 and TLS code use `MBEDTLS_xxx` macros to decide whether an algorithm is
+supported. This doesn't make `MBEDTLS_USE_PSA_CRYPTO` incompatible with
+`MBEDTLS_PSA_CRYPTO_CONFIG` per se, but it makes it incompatible with most
+useful uses of `MBEDTLS_PSA_CRYPTO_CONFIG`. The point of
+`MBEDTLS_PSA_CRYPTO_CONFIG` is to be able to build a library with support for
+an algorithm through a PSA driver only, without building the software
+implementation of that algorithm. But then the TLS code would consider the
+algorithm unavailable.
+
+This is tracked in https://github.com/ARMmbed/mbedtls/issues/3674 and
+https://github.com/ARMmbed/mbedtls/issues/3677. But now that I look at it with
+fresh eyes, I don't think the approach we were planning to use would actually
+works. This needs more design effort.
+
+This is something we need to support eventually, and several partners want it.
+I don't know what the priority is for `MBEDTLS_USE_PSA_CRYPTO` between
+improving driver support and covering more of the protocol. It seems to me
+that it'll be less work overall to first implement a good architecture for
+`MBEDTLS_USE_PSA_CRYPTO + MBEDTLS_PSA_CRYPTO_CONFIG` and then extend to more
+protocol features, because implementing that architecture will require changes
+to the existing code and the less code there is at this point the better,
+whereas extending to more protocol features will require the same amount of
+work either way.
+
+### Backward compatibility issues with making it always on
+
+1. Existing applications may not be calling `psa_crypto_init()` before using
+   TLS, X.509 or PK. We can try to work around that by calling (the relevant
+part of) it ourselves under the hood as needed, but that would likely require
+splitting init between the parts that can fail and the parts that can't (see
+https://github.com/ARM-software/psa-crypto-api/pull/536 for that).
+2. It's currently not possible to enable `MBEDTLS_PSA_CRYPTO_C` in
+   configurations that don't have `MBEDTLS_ENTROPY_C`, and we can't just
+auto-enable the latter, as it won't build or work out of the box on all
+platforms. There are two kinds of things we'd need to do if we want to work
+around that:
+   1. Make it possible to enable the parts of PSA Crypto that don't require an
+      RNG (typically, public key operations, symmetric crypto, some key
+management functions (destroy etc)) in configurations that don't have
+`ENTROPY_C`. This requires going through the PSA code base to adjust
+dependencies. Risk: there may be annoying dependencies, some of which may be
+surprising.
+   2. For operations that require an RNG, provide an alternative function
+      accepting an explicit `f_rng` parameter (see #5238), that would be
+available in entropy-less builds. (Then code using those functions still needs
+to have one version using it, for entropy-less builds, and one version using
+the standard function, for driver support in build with entropy.)
+
+See https://github.com/ARMmbed/mbedtls/issues/5156
+
+Taking advantage of the existing abstractions layers - or not
+=============================================================
+
+The Crypto library in Mbed TLS currently has 3 abstraction layers that offer
+algorithm-agnostic APIs for a class of algorithms:
+
+- MD for messages digests aka hashes (including HMAC)
+- Cipher for symmetric ciphers (included AEAD)
+- PK for asymmetric (aka public-key) cryptography (excluding key exchange)
+
+Note: key exchange (FFDH, ECDH) is not covered by an abstraction layer.
+
+These abstraction layers typically provide, in addition to the API for crypto
+operations, types and numerical identifiers for algorithms (for
+example `mbedtls_cipher_mode_t` and its values). The
+current strategy is to keep using those identifiers in most of the code, in
+particular in existing structures and public APIs, even when
+`MBEDTLS_USE_PSA_CRYPTO` is enabled. (This is not an issue for G1, G2, G3
+above, and is only potentially relevant for G4.)
+
+The are multiple strategies that can be used regarding the place of those
+layers in the migration to PSA.
+
+Silently call to PSA from the abstraction layer
+-----------------------------------------------
+
+- Provide a new definition (conditionally on `USE_PSA_CRYPTO`) of wrapper
+  functions in the abstraction layer, that calls PSA instead of the legacy
+crypto API.
+- Upside: changes contained to a single place, no need to change TLS or X.509
+  code anywhere.
+- Downside: tricky to implement if the PSA implementation is currently done on
+  top of that layer (dependency loop).
+
+This strategy is currently (late 2021) used for ECDSA signature
+verification in the PK layer, and could be extended to all operations in the
+PK layer.
+
+This strategy is not very well suited to the Cipher layer, as the PSA
+implementation is currently done on top of that layer.
+
+This strategy will probably be used for some time for the PK layer, while we
+figure out what the future of that layer is: parts of it (parse/write, ECDSA
+signatures in the format that X.509 & TLS want) are not covered by PSA, so
+they will need to keep existing in some way. Also the PK layer is also a good
+place for dispatching to either PSA or `mbedtls_xxx_restartable` while that
+part is not covered by PSA yet.
+
+Replace calls for each operation
+--------------------------------
+
+- For every operation that's done through this layer in TLS or X.509, just
+  replace function call with calls to PSA (conditionally on `USE_PSA_CRYPTO`)
+- Upside: conceptually simple, and if the PSA implementation is currently done
+  on top of that layer, avoids concerns about dependency loops.
+- Upside: opens the door to building TLS/X.509 without that layer, saving some
+  code size.
+- Downside: TLS/X.509 code has to be done for each operation.
+
+This strategy is currently (late 2021) used for the MD layer. (Currently only
+a subset of calling places, but will be extended to all of them.)
+
+In the future (early 2022) we're going to use it for the Cipher layer as well.
+
+Opt-in use of PSA from the abstraction layer
+--------------------------------------------
+
+- Provide a new way to set up a context that causes operations on that context
+  to be done via PSA.
+- Upside: changes mostly contained in one place, TLS/X.509 code only needs to
+  be changed when setting up the context, but not when using it. In
+  particular, no changes to/duplication of existing public APIs that expect a
+  key to be passed as a context of this layer (eg, `mbedtls_pk_context`).
+- Upside: avoids dependency loop when PSA implemented on top of that layer.
+- Downside: when the context is typically set up by the application, requires
+  changes in application code.
+
+This strategy is not useful when no context is used, for example with the
+one-shot function `mbedtls_md()`.
+
+There are two variants of this strategy: one where using the new setup
+function also allows for key isolation (the key is only held by PSA,
+supporting both G1 and G2 in that area), and one without isolation (the key is
+still stored outside of PSA most of the time, supporting only G1).
+
+This strategy, with support for key isolation, is currently (end of 2021) used for ECDSA
+signature generation in the PK layer - see `mbedtls_pk_setup_opaque()`. This
+allows use of PSA-held private ECDSA keys in TLS and X.509 with no change to
+the TLS/X.509 code, but a contained change in the application. If could be
+extended to other private key operations in the PK layer, which is the plan as
+of early 2022.
+
+This strategy, without key isolation, is also currently used in the Cipher
+layer - see `mbedtls_cipher_setup_psa()`. This allows use of PSA for cipher
+operations in TLS with no change to the application code, and a
+contained change in TLS code. (It currently only supports a subset of
+ciphers.) However, we'll move to the "Replace calls for each operation"
+strategy (early 2022), in the hope of being able to build without this layer
+in order to save some code size in the future.
+
+Note: for private key operations in the PK layer, both the "silent" and the
+"opt-in" strategy can apply, and can complement each other, as one provides
+support for key isolation, but at the (unavoidable) code of change in
+application code, while the other requires no application change to get
+support for drivers, but fails to provide isolation support.
+
+Summary
+-------
+
+Strategies currently used with each abstraction layer:
+
+- PK (for G1): silently call PSA
+- PK (for G2): opt-in use of PSA (new key type)
+- Cipher (G1):
+  - late 2021: opt-in use of PSA (new setup function)
+  - early 2022: moving to "replace calls at each call site"
+- MD (G1): replace calls at each call site
+
+Migrating away from the legacy API
+==================================
+
+This section briefly introduces questions and possible plans towards G4,
+mainly as they relate to choices in previous stages.
+
+The role of the PK/Cipher/MD APIs in user migration
+---------------------------------------------------
+
+We're currently taking advantage of the existing PK and Cipher layers in order
+to reduce the number of places where library code needs to be changed. It's
+only natural to consider using the same strategy (with the PK, MD and Cipher
+layers) for facilitating migration of application code.
+
+Note: a necessary first step for that would be to make sure PSA is no longer
+implemented of top of the concerned layers
+
+### Zero-cost compatibility layer?
+
+The most favourable case is if we can have a zero-cost abstraction (no
+runtime, RAM usage or code size penalty), for example just a bunch of
+`#define`s, essentially mapping `mbedtls_` APIs to their `psa_` equivalent.
+
+Unfortunately that's unlikely fully work. For example, the MD layer uses the
+same context type for hashes and HMACs, while the PSA API (rightfully) has
+distinct operation types. Similarly, the Cipher layer uses the same context
+type for unauthenticated and AEAD ciphers, which again the PSA API
+distinguishes.
+
+It is unclear how much value, if any, a zero-cost compatibility layer that's
+incomplete (for example, for MD covering only hashes, or for Cipher covering
+only AEAD) or differs significantly from the existing API (for example,
+introducing new context types) would provide to users.
+
+### Low-cost compatibility layers?
+
+Another possibility is to keep most or all of the existing API for the PK, MD
+and Cipher layers, implemented on top of PSA, aiming for the lowest possible
+cost. For example, `mbedtls_md_context_t` would be defined as a (tagged) union
+of `psa_hash_operation_t` and `psa_mac_operation_t`, then `mbedtls_md_setup()`
+would initialize the correct part, and the rest of the functions be simple
+wrappers around PSA functions. This would vastly reduce the complexity of the
+layers compared to the existing (no need to dispatch through function
+pointers, just call the corresponding PSA API).
+
+Since this would still represent a non-zero cost, not only in terms of code
+size, but also in terms of maintenance (testing, etc.) this would probably
+be a temporary solution: for example keep the compatibility layers in 4.0 (and
+make them optional), but remove them in 5.0.
+
+Again, this provides the most value to users if we can manage to keep the
+existing API unchanged. Their might be conflicts between this goal and that of
+reducing the cost, and judgment calls may need to be made.
+
+Note: when it comes to holding public keys in the PK layer, depending on how
+the rest of the code is structured, it may be worth holding the key data in
+memory controlled by the PK layer as opposed to a PSA key slot, moving it to a
+slot only when needed (see current `ecdsa_verify_wrap` when
+`MBEDTLS_USE_PSA_CRYPTO` is defined)  For example, when parsing a large
+number, N, of X.509 certificates (for example the list of trusted roots), it
+might be undesirable to use N PSA key slots for their public keys as long as
+the certs are loaded. OTOH, this could also be addressed by merging the "X.509
+parsing on-demand" (#2478), and then the public key data would be held as
+bytes in the X.509 CRT structure, and only moved to a PK context / PSA slot
+when it's actually used.
+
+Note: the PK layer actually consists of two relatively distinct parts: crypto
+operations, which will be covered by PSA, and parsing/writing (exporting)
+from/to various formats, which is currently not fully covered by the PSA
+Crypto API.
+
+### Algorithm identifiers and other identifiers
+
+It should be easy to provide the user with a bunch of `#define`s for algorithm
+identifiers, for example `#define MBEDTLS_MD_SHA256 PSA_ALG_SHA_256`; most of
+those would be in the MD, Cipher and PK compatibility layers mentioned above,
+but there might be some in other modules that may be worth considering, for
+example identifiers for elliptic curves.
+
+### Lower layers
+
+Generally speaking, we would retire all of the low-level, non-generic modules,
+such as AES, SHA-256, RSA, DHM, ECDH, ECP, bignum, etc, without providing
+compatibility APIs for them. People would be encouraged to switch to the PSA
+API. (The compatibility implementation of the existing PK, MD, Cipher APIs
+would mostly benefit people who already used those generic APis rather than
+the low-level, alg-specific ones.)
+
+### APIs in TLS and X.509
+
+Public APIs in TLS and X.509 may be affected by the migration in at least two
+ways:
+
+1. APIs that rely on a legacy `mbedtls_` crypto type: for example
+   `mbedtls_ssl_conf_own_cert()` to configure a (certificate and the
+associated) private key. Currently the private key is passed as a
+`mbedtls_pk_context` object, which would probably change to a `psa_key_id_t`.
+Since some users would probably still be using the compatibility PK layer, it
+would need a way to easily extract the PSA key ID from the PK context.
+
+2. APIs the accept list of identifiers: for example
+   `mbedtls_ssl_conf_curves()` taking a list of `mbedtls_ecp_group_id`s. This
+could be changed to accept a list of pairs (`psa_ecc_familiy_t`, size) but we
+should probably take this opportunity to move to a identifier independent from
+the underlying crypto implementation and use TLS-specific identifiers instead
+(based on IANA values or custom enums), as is currently done in the new
+`mbedtls_ssl_conf_groups()` API, see #4859).
+
+Testing
+-------
+
+An question that needs careful consideration when we come around to removing
+the low-level crypto APIs and making PK, MD and Cipher optional compatibility
+layers is to be sure to preserve testing quality. A lot of the existing test
+cases use the low level crypto APIs; we would need to either keep using that
+API for tests, or manually migrated test to the PSA Crypto API. Perhaps a
+combination of both, perhaps evolving gradually over time.
diff --git a/docs/architecture/psa-migration/syms.sh b/docs/architecture/psa-migration/syms.sh
new file mode 100755
index 0000000..5c34b28
--- /dev/null
+++ b/docs/architecture/psa-migration/syms.sh
@@ -0,0 +1,58 @@
+#!/bin/sh
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Purpose
+#
+# Show symbols in the X.509 and TLS libraries that are defined in another
+# libmbedtlsXXX.a library. This is usually done to list Crypto dependencies.
+#
+# Usage:
+# - build the library with debug symbols and the config you're interested in
+#   (default, full minus MBEDTLS_USE_PSA_CRYPTO, full, etc.)
+# - run this script with the name of your config as the only argument
+
+set -eu
+
+# list mbedtls_ symbols of a given type in a static library
+syms() {
+    TYPE="$1"
+    FILE="$2"
+
+    nm "$FILE" | sed -n "s/[0-9a-f ]*${TYPE} \(mbedtls_.*\)/\1/p" | sort -u
+}
+
+# create listings for the given library
+list() {
+    NAME="$1"
+    FILE="library/libmbed${NAME}.a"
+    PREF="${CONFIG}-$NAME"
+
+    syms '[TRrD]' $FILE > ${PREF}-defined
+    syms U $FILE > ${PREF}-unresolved
+
+    diff ${PREF}-defined ${PREF}-unresolved \
+        | sed -n 's/^> //p' > ${PREF}-external
+    sed 's/mbedtls_\([^_]*\).*/\1/' ${PREF}-external \
+        | uniq -c | sort -rn > ${PREF}-modules
+
+    rm ${PREF}-defined ${PREF}-unresolved
+}
+
+CONFIG="${1:-unknown}"
+
+list x509
+list tls
diff --git a/docs/architecture/psa-migration/tasks-g2.md b/docs/architecture/psa-migration/tasks-g2.md
new file mode 100644
index 0000000..72bd377
--- /dev/null
+++ b/docs/architecture/psa-migration/tasks-g2.md
@@ -0,0 +1,80 @@
+This document is temporary; it lists tasks to achieve G2 as described in
+`strategy.md` while the strategy is being reviewed - once that's done,
+corresponding github issues will be created and this document removed.
+
+For all of the tasks here, specific testing (integration and unit test depending
+on the task) is required, see `testing.md`.
+
+RSA Signature operations
+========================
+
+In PK
+-----
+
+### Modify existing `PK_OPAQUE` type to allow for RSA keys
+
+- the following must work and be tested: `mbedtls_pk_get_type()`,
+  `mbedtls_pk_get_name()`, `mbedtls_pk_get_bitlen()`, `mbedtls_pk_get_len()`,
+`mbedtls_pk_can_do()`.
+- most likely adapt `pk_psa_genkey()` in `test_suite_pk.function`.
+- all other function (sign, verify, encrypt, decrypt, check pair, debug) will
+  return `MBEDTLS_ERR_PK_TYPE_MISMATCH` and this will be tested too.
+
+### Modify `mbedtls_pk_wrap_as_opaque()` to work with RSA.
+
+- OK to have policy hardcoded on signing with PKCS1v1.5, or allow more if
+  available at this time
+
+### Modify `mbedtls_pk_write_pubkey_der()` to work with RSA-opaque.
+
+- OK to just test that a generated key (with `pk_psa_genkey()`) can be
+  written, without checking for correctness of the result - this will be
+tested as part of another task
+
+### Make `mbedtls_pk_sign()` work with RSA-opaque.
+
+- testing may extend `pk_psa_sign()` in `test_suite_pk_function` by adding
+  selector for ECDSA/RSA.
+
+In X.509
+--------
+
+### Test using RSA-opaque for CSR generation
+
+- similar to what's already done with ECDSA-opaque
+
+### Test using opaque keys for Certificate generation
+
+- similar to what's done with testing CSR generation
+- should test both RSA and ECDSA as ECDSA is not tested yet
+- might require slight code adaptations, even if unlikely
+
+
+In TLS
+------
+
+### Test using RSA-opaque for TLS client auth
+
+- similar to what's already done with ECDSA-opaque
+
+### Test using RSA-opaque for TLS server auth
+
+- similar to what's already done with ECDSA-opaque
+- key exchanges: ECDHE-RSA and DHE-RSA
+
+RSA decrypt
+===========
+
+### Extend `PK_OPAQUE` to allow RSA decryption (PKCS1 v1.5)
+
+### Test using that in TLS for RSA and RSA-PSK key exchange.
+
+Support opaque PSKs for "mixed-PSK" key exchanges
+=================================================
+
+See `PSA-limitations.md`.
+
+Possible split:
+- one task to extend PSA (see `PSA-limitations.md`)
+- then one task per handshake: DHE-PSK, ECDHE-PSK, RSA-PSK (with tests for
+  each)
diff --git a/docs/architecture/psa-migration/testing.md b/docs/architecture/psa-migration/testing.md
new file mode 100644
index 0000000..70229ce
--- /dev/null
+++ b/docs/architecture/psa-migration/testing.md
@@ -0,0 +1,99 @@
+Testing strategy for `MBEDTLS_USE_PSA_CRYPTO`
+=============================================
+
+This document records the testing strategy used so far in implementing
+`MBEDTLS_USE_PSA_CRYPTO`.
+
+
+General considerations
+----------------------
+
+There needs to be at least one build in `all.sh` that enables
+`MBEDTLS_USE_PSA_CRYPTO` and runs the full battery of tests; currently that's
+ensured by the fact that `scripts/config.py full` enables
+`MBEDTLS_USE_PSA_CRYPTO`. There needs to be at least one build with
+`MBEDTLS_USE_PSA_CRYPTO` disabled (as long as it's optional); currently that's
+ensured by the fact that it's disabled in the default config.
+
+Generally, code review is enough to ensure that PSA APIs are indeed used where
+they should be when `MBEDTLS_USE_PSA_CRYPTO` is enabled.
+
+However, when it comes to TLS, we also have the option of using debug messages
+to confirm which code path is taken. This is generally unnecessary, except when
+a decision is made at run-time about whether to use the PSA or legacy code
+path. For example, for record protection, currently some ciphers are supported
+via PSA while some others aren't, with a run-time fallback. In this case, it's
+good to have a debug message checked by the test case to confirm that the
+right decision was made at run-time, i. e. that we didn't use the fallback for
+ciphers that are supposed to be supported.
+
+
+New APIs meant for application use
+----------------------------------
+
+For example, `mbedtls_pk_setup_opaque()` is meant to be used by applications
+in order to create PK contexts that can then be passed to existing TLS and
+X.509 APIs (which remain unchanged).
+
+In that case, we want:
+
+- unit testing of the new API and directly-related APIs - for example:
+  - in `test_suite_pk` we have a new test function `pk_psa_utils` that exercises
+    `mbedtls_pk_setup_opaque()` and checks that various utility functions
+  (`mbedtls_pk_get_type()` etc.) work and the functions that are expected to
+  fail (`mbedtls_pk_verify()` etc) return the expected error.
+  - in `test_suite_pk` we modified the existing `pk_psa_sign` test function to
+    check that signature generation works as expected
+  - in `test_suite_pkwrite` we should have a new test function checking that
+    exporting (writing out) the public part of the key works as expected and
+    that exporting the private key fails as expected.
+- integration testing of the new API with each existing API which should
+  accepts a context created this way - for example:
+  - in `programs/ssl/ssl_client2` a new option `key_opaque` that causes the
+    new API to be used, and one or more tests in `ssl-opt.sh` using that.
+    (We should have the same server-side.)
+  - in `test_suite_x509write` we have a new test function
+    `x509_csr_check_opaque()` checking integration of the new API with the
+    existing `mbedtls_x509write_csr_set_key()`.
+    (We should have something similar for
+    `mbedtls_x509write_crt_set_issuer_key()`.)
+
+For some APIs, for example with `mbedtls_ssl_conf_psk_opaque()`, testing in
+`test_suite_ssl` was historically not possible, so we only have testing in
+`ssl-opt.sh`.
+
+New APIs meant for internal use
+-------------------------------
+
+For example, `mbedtls_cipher_setup_psa()` is meant to be used by the TLS
+layer, but probably not directly by applications.
+
+In that case, we want:
+
+- unit testing of the new API and directly-related APIs - for example:
+  - in `test_suite_cipher`, the existing test functions `auth_crypt_tv` and
+    `test_vec_crypt` gained a new parameter `use_psa` and corresponding test
+    cases
+- integration testing:
+  - usually already covered by existing tests for higher-level modules:
+    - for example simple use of `mbedtls_cipher_setup_psa()` in TLS is already
+      covered by running the existing TLS tests in a build with
+      `MBEDTLS_USA_PSA_CRYPTO` enabled
+  - however if use of the new API in higher layers involves more logic that
+    use of the old API, specific integrations test may be required
+    - for example, the logic to fall back from `mbedtls_cipher_setup_psa()` to
+      `mbedtls_cipher_setup()` in TLS is tested by `run_test_psa` in
+      `ssl-opt.sh`.
+
+Internal changes
+----------------
+
+For example, use of PSA to compute the TLS 1.2 PRF.
+
+Changes in this category rarely require specific testing, as everything should
+be already be covered by running the existing tests in a build with
+`MBEDTLS_USE_PSA_CRYPTO` enabled; however we need to make sure the existing
+test have sufficient coverage, and improve them if necessary.
+
+However, if additional logic is involved, or there are run-time decisions about
+whether to use the PSA or legacy code paths, specific tests might be in order.
diff --git a/docs/architecture/tls13-support.md b/docs/architecture/tls13-support.md
index 9e9aad3..39e46c4 100644
--- a/docs/architecture/tls13-support.md
+++ b/docs/architecture/tls13-support.md
@@ -120,14 +120,29 @@
   the three first ones in the list above are mandatory (see section 9.1 of the
   specification).
 
-- Supported versions: only TLS 1.3, version negotiation is not supported.
+- Supported versions:
+
+  - TLS 1.2 and TLS 1.3 but version negotiation is not supported.
+
+  - 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.
+
+  - 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.
 
 - Compatibility with existing SSL/TLS build options:
 
   The TLS 1.3 MVP is compatible with all TLS 1.2 configuration options in the
   sense that when enabling the TLS 1.3 MVP in the library there is no need to
-  modify the configuration for TLS 1.2. Mbed TLS SSL/TLS related features are
-  not supported or not applicable to the TLS 1.3 MVP:
+  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.
+
+  Mbed TLS SSL/TLS related features are not supported or not applicable to the
+  TLS 1.3 MVP:
 
   | Mbed TLS configuration option            | Support |
   | ---------------------------------------- | ------- |
diff --git a/docs/use-psa-crypto.md b/docs/use-psa-crypto.md
index 4a78e47..9c97b5d 100644
--- a/docs/use-psa-crypto.md
+++ b/docs/use-psa-crypto.md
@@ -59,10 +59,9 @@
 - `mbedtls_x509write_csr_set_key()` to generate a CSR (certificate signature
   request).
 
-In the TLS and X.509 API, there are two other functions which accept a key or
-keypair as a PK context: `mbedtls_x509write_crt_set_subject_key()` and
-`mbedtls_x509write_crt_set_issuer_key()`. Use of opaque contexts here probably
-works but is so far untested.
+In the TLS and X.509 API, there's one other function which accepts a keypair
+as a PK context: `mbedtls_x509write_crt_set_issuer_key()`. Use of opaque
+contexts here probably works but is so far untested.
 
 ### PSA-held (opaque) keys for TLS pre-shared keys (PSK)
 
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index d7cc7bc..c25ac0a 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -643,7 +643,8 @@
 #error "MBEDTLS_SSL_SRV_C defined, but not all prerequisites"
 #endif
 
-#if defined(MBEDTLS_SSL_TLS_C) && !defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SSL_TLS_C) && \
+    !( defined(MBEDTLS_SSL_PROTO_TLS1_2) || defined(MBEDTLS_SSL_PROTO_TLS1_3) )
 #error "MBEDTLS_SSL_TLS_C defined, but no protocols are active"
 #endif
 
diff --git a/include/mbedtls/pem.h b/include/mbedtls/pem.h
index a2b73f8..c75a124 100644
--- a/include/mbedtls/pem.h
+++ b/include/mbedtls/pem.h
@@ -27,6 +27,11 @@
 
 #include <stddef.h>
 
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
 /**
  * \name PEM Error codes
  * These error codes are returned in case of errors reading the
@@ -96,6 +101,10 @@
  *                  the decrypted text starts with an ASN.1 sequence of
  *                  appropriate length
  *
+ * \note            \c mbedtls_pem_free must be called on PEM context before
+ *                  the PEM context can be reused in another call to
+ *                  \c mbedtls_pem_read_buffer
+ *
  * \return          0 on success, or a specific PEM error code
  */
 int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const char *footer,
@@ -104,6 +113,25 @@
                      size_t pwdlen, size_t *use_len );
 
 /**
+ * \brief       Get the pointer to the decoded binary data in a PEM context.
+ *
+ * \param ctx       PEM context to access.
+ * \param buflen    On success, this will contain the length of the binary data.
+ *                  This must be a valid (non-null) pointer.
+ *
+ * \return          A pointer to the decoded binary data.
+ *
+ * \note            The returned pointer remains valid only until \p ctx is
+                    modified or freed.
+ */
+static inline const unsigned char *mbedtls_pem_get_buffer( mbedtls_pem_context *ctx, size_t *buflen )
+{
+    *buflen = ctx->MBEDTLS_PRIVATE(buflen);
+    return( ctx->MBEDTLS_PRIVATE(buf) );
+}
+
+
+/**
  * \brief       PEM context memory freeing
  *
  * \param ctx   context to be freed
diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h
index c54c035..e38e2e3 100644
--- a/include/mbedtls/psa_util.h
+++ b/include/mbedtls/psa_util.h
@@ -258,85 +258,24 @@
     return( -1 );
 }
 
-#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH 1
+#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH \
+    PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE( PSA_VENDOR_ECC_MAX_CURVE_BITS )
 
-#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
-#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 192 + 7 ) / 8 ) + 1 )
-#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
-#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 192 + 7 ) / 8 ) + 1 )
-#endif
-#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
-
-#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
-#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 224 + 7 ) / 8 ) + 1 )
-#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
-#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 224 + 7 ) / 8 ) + 1 )
-#endif
-#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
-
-#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
-#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 256 + 7 ) / 8 ) + 1 )
-#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
-#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 256 + 7 ) / 8 ) + 1 )
-#endif
-#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
-
-#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
-#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 384 + 7 ) / 8 ) + 1 )
-#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
-#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 384 + 7 ) / 8 ) + 1 )
-#endif
-#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
-
-#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
-#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 521 + 7 ) / 8 ) + 1 )
-#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
-#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 521 + 7 ) / 8 ) + 1 )
-#endif
-#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
-
-#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
-#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 192 + 7 ) / 8 ) + 1 )
-#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
-#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 192 + 7 ) / 8 ) + 1 )
-#endif
-#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
-
-#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
-#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 224 + 7 ) / 8 ) + 1 )
-#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
-#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 224 + 7 ) / 8 ) + 1 )
-#endif
-#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
-
-#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
-#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 256 + 7 ) / 8 ) + 1 )
-#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
-#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 256 + 7 ) / 8 ) + 1 )
-#endif
-#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
-
-#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
-#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 256 + 7 ) / 8 ) + 1 )
-#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
-#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 256 + 7 ) / 8 ) + 1 )
-#endif
-#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
-
-#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
-#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 384 + 7 ) / 8 ) + 1 )
-#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
-#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 384 + 7 ) / 8 ) + 1 )
-#endif
-#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
-
-#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
-#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 512 + 7 ) / 8 ) + 1 )
-#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
-#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 512 + 7 ) / 8 ) + 1 )
-#endif
-#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
-
+/* This function transforms an ECC group identifier from
+ * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
+ * into a PSA ECC group identifier. */
+#if defined(MBEDTLS_ECP_C)
+static inline psa_key_type_t mbedtls_psa_parse_tls_ecc_group(
+    uint16_t tls_ecc_grp_reg_id, size_t *bits )
+{
+    const mbedtls_ecp_curve_info *curve_info =
+        mbedtls_ecp_curve_info_from_tls_id( tls_ecc_grp_reg_id );
+    if( curve_info == NULL )
+        return( 0 );
+    return( PSA_KEY_TYPE_ECC_KEY_PAIR(
+                mbedtls_ecc_group_to_psa( curve_info->grp_id, bits ) ) );
+}
+#endif /* MBEDTLS_ECP_C */
 
 /* Translations for PK layer */
 
@@ -366,63 +305,6 @@
     }
 }
 
-/* Translations for ECC */
-
-/* This function transforms an ECC group identifier from
- * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
- * into a PSA ECC group identifier. */
-#if defined(MBEDTLS_ECP_C)
-static inline psa_key_type_t mbedtls_psa_parse_tls_ecc_group(
-    uint16_t tls_ecc_grp_reg_id, size_t *bits )
-{
-    const mbedtls_ecp_curve_info *curve_info =
-        mbedtls_ecp_curve_info_from_tls_id( tls_ecc_grp_reg_id );
-    if( curve_info == NULL )
-        return( 0 );
-    return( PSA_KEY_TYPE_ECC_KEY_PAIR(
-                mbedtls_ecc_group_to_psa( curve_info->grp_id, bits ) ) );
-}
-#endif /* MBEDTLS_ECP_C */
-
-/* This function takes a buffer holding an EC public key
- * exported through psa_export_public_key(), and converts
- * it into an ECPoint structure to be put into a ClientKeyExchange
- * message in an ECDHE exchange.
- *
- * Both the present and the foreseeable future format of EC public keys
- * used by PSA have the ECPoint structure contained in the exported key
- * as a subbuffer, and the function merely selects this subbuffer instead
- * of making a copy.
- */
-static inline int mbedtls_psa_tls_psa_ec_to_ecpoint( unsigned char *src,
-                                                     size_t srclen,
-                                                     unsigned char **dst,
-                                                     size_t *dstlen )
-{
-    *dst = src;
-    *dstlen = srclen;
-    return( 0 );
-}
-
-/* This function takes a buffer holding an ECPoint structure
- * (as contained in a TLS ServerKeyExchange message for ECDHE
- * exchanges) and converts it into a format that the PSA key
- * agreement API understands.
- */
-static inline int mbedtls_psa_tls_ecpoint_to_psa_ec( unsigned char const *src,
-                                                     size_t srclen,
-                                                     unsigned char *dst,
-                                                     size_t dstlen,
-                                                     size_t *olen )
-{
-    if( srclen > dstlen )
-        return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
-
-    memcpy( dst, src, srclen );
-    *olen = srclen;
-    return( 0 );
-}
-
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 
 /* Expose whatever RNG the PSA subsystem uses to applications using the
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 350ee2c..7e5fb19 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1613,11 +1613,6 @@
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
     /*
-     * PKI layer
-     */
-    int MBEDTLS_PRIVATE(client_auth);                    /*!<  flag for client auth.   */
-
-    /*
      * User settings
      */
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
diff --git a/include/mbedtls/ssl_ticket.h b/include/mbedtls/ssl_ticket.h
index 0f4117d..8559309 100644
--- a/include/mbedtls/ssl_ticket.h
+++ b/include/mbedtls/ssl_ticket.h
@@ -42,12 +42,16 @@
 extern "C" {
 #endif
 
+#define MBEDTLS_SSL_TICKET_MAX_KEY_BYTES 32          /*!< Max supported key length in bytes */
+#define MBEDTLS_SSL_TICKET_KEY_NAME_BYTES 4          /*!< key name length in bytes */
+
 /**
  * \brief   Information for session ticket protection
  */
 typedef struct mbedtls_ssl_ticket_key
 {
-    unsigned char MBEDTLS_PRIVATE(name)[4];          /*!< random key identifier              */
+    unsigned char MBEDTLS_PRIVATE(name)[MBEDTLS_SSL_TICKET_KEY_NAME_BYTES];
+                                                     /*!< random key identifier              */
     uint32_t MBEDTLS_PRIVATE(generation_time);       /*!< key generation timestamp (seconds) */
     mbedtls_cipher_context_t MBEDTLS_PRIVATE(ctx);   /*!< context for auth enc/decryption    */
 }
@@ -98,7 +102,7 @@
  *                  supported. Usually that means a 256-bit key.
  *
  * \note            The lifetime of the keys is twice the lifetime of tickets.
- *                  It is recommended to pick a reasonnable lifetime so as not
+ *                  It is recommended to pick a reasonable lifetime so as not
  *                  to negate the benefits of forward secrecy.
  *
  * \return          0 if successful,
@@ -110,6 +114,43 @@
     uint32_t lifetime );
 
 /**
+ * \brief           Rotate session ticket encryption key to new specified key.
+ *                  Provides for external control of session ticket encryption
+ *                  key rotation, e.g. for synchronization between different
+ *                  machines.  If this function is not used, or if not called
+ *                  before ticket lifetime expires, then a new session ticket
+ *                  encryption key is generated internally in order to avoid
+ *                  unbounded session ticket encryption key lifetimes.
+ *
+ * \param ctx       Context to be set up
+ * \param name      Session ticket encryption key name
+ * \param nlength   Session ticket encryption key name length in bytes
+ * \param k         Session ticket encryption key
+ * \param klength   Session ticket encryption key length in bytes
+ * \param lifetime  Tickets lifetime in seconds
+ *                  Recommended value: 86400 (one day).
+ *
+ * \note            \c name and \c k are recommended to be cryptographically
+ *                  random data.
+ *
+ * \note            \c nlength must match sizeof( ctx->name )
+ *
+ * \note            \c klength must be sufficient for use by cipher specified
+ *                  to \c mbedtls_ssl_ticket_setup
+ *
+ * \note            The lifetime of the keys is twice the lifetime of tickets.
+ *                  It is recommended to pick a reasonable lifetime so as not
+ *                  to negate the benefits of forward secrecy.
+ *
+ * \return          0 if successful,
+ *                  or a specific MBEDTLS_ERR_XXX error code
+ */
+int mbedtls_ssl_ticket_rotate( mbedtls_ssl_ticket_context *ctx,
+    const unsigned char *name, size_t nlength,
+    const unsigned char *k, size_t klength,
+    uint32_t lifetime );
+
+/**
  * \brief           Implementation of the ticket write callback
  *
  * \note            See \c mbedtls_ssl_ticket_write_t for description
diff --git a/library/aes.c b/library/aes.c
index 4afc3c4..d2b05e2 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -971,6 +971,7 @@
                            unsigned char output[16] )
 {
     AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( ctx->rk != NULL );
     AES_VALIDATE_RET( input != NULL );
     AES_VALIDATE_RET( output != NULL );
     AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
diff --git a/library/ecp.c b/library/ecp.c
index 0212069..ba76abb 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -342,6 +342,18 @@
 
 #endif /* MBEDTLS_ECP_RESTARTABLE */
 
+static void mpi_init_many( mbedtls_mpi *arr, size_t size )
+{
+    while( size-- )
+        mbedtls_mpi_init( arr++ );
+}
+
+static void mpi_free_many( mbedtls_mpi *arr, size_t size )
+{
+    while( size-- )
+        mbedtls_mpi_free( arr++ );
+}
+
 /*
  * List of supported curves:
  *  - internal ID
@@ -1093,9 +1105,11 @@
  * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_sub_mpi
  * N->s < 0 is a very fast test, which fails only if N is 0
  */
-#define MOD_SUB( N )                                                    \
-    while( (N).s < 0 && mbedtls_mpi_cmp_int( &(N), 0 ) != 0 )           \
-        MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &(N), &(N), &grp->P ) )
+#define MOD_SUB( N )                                                          \
+    do {                                                                      \
+        while( (N)->s < 0 && mbedtls_mpi_cmp_int( (N), 0 ) != 0 )             \
+            MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( (N), (N), &grp->P ) );      \
+    } while( 0 )
 
 #if ( defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) && \
       !( defined(MBEDTLS_ECP_NO_FALLBACK) && \
@@ -1111,7 +1125,7 @@
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( X, A, B ) );
-    MOD_SUB( *X );
+    MOD_SUB( X );
 cleanup:
     return( ret );
 }
@@ -1122,9 +1136,9 @@
  * We known P, N and the result are positive, so sub_abs is correct, and
  * a bit faster.
  */
-#define MOD_ADD( N )                                                    \
-    while( mbedtls_mpi_cmp_mpi( &(N), &grp->P ) >= 0 )                  \
-        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &(N), &(N), &grp->P ) )
+#define MOD_ADD( N )                                                   \
+    while( mbedtls_mpi_cmp_mpi( (N), &grp->P ) >= 0 )                  \
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( (N), (N), &grp->P ) )
 
 static inline int mbedtls_mpi_add_mod( const mbedtls_ecp_group *grp,
                                        mbedtls_mpi *X,
@@ -1133,11 +1147,40 @@
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, A, B ) );
-    MOD_ADD( *X );
+    MOD_ADD( X );
 cleanup:
     return( ret );
 }
 
+static inline int mbedtls_mpi_mul_int_mod( const mbedtls_ecp_group *grp,
+                                           mbedtls_mpi *X,
+                                           const mbedtls_mpi *A,
+                                           mbedtls_mpi_uint c )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( X, A, c ) );
+    MOD_ADD( X );
+cleanup:
+    return( ret );
+}
+
+static inline int mbedtls_mpi_sub_int_mod( const mbedtls_ecp_group *grp,
+                                           mbedtls_mpi *X,
+                                           const mbedtls_mpi *A,
+                                           mbedtls_mpi_uint c )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( X, A, c ) );
+    MOD_SUB( X );
+cleanup:
+    return( ret );
+}
+
+#define MPI_ECP_SUB_INT( X, A, c )             \
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int_mod( grp, X, A, c ) )
+
 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) && \
     !( defined(MBEDTLS_ECP_NO_FALLBACK) && \
        defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) && \
@@ -1148,12 +1191,77 @@
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( X, count ) );
-    MOD_ADD( *X );
+    MOD_ADD( X );
 cleanup:
     return( ret );
 }
 #endif /* All functions referencing mbedtls_mpi_shift_l_mod() are alt-implemented without fallback */
 
+/*
+ * Macro wrappers around ECP modular arithmetic
+ *
+ * Currently, these wrappers are defined via the bignum module.
+ */
+
+#define MPI_ECP_ADD( X, A, B )                                                  \
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, X, A, B ) )
+
+#define MPI_ECP_SUB( X, A, B )                                                  \
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, X, A, B ) )
+
+#define MPI_ECP_MUL( X, A, B )                                                  \
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, X, A, B ) )
+
+#define MPI_ECP_SQR( X, A )                                                     \
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, X, A, A ) )
+
+#define MPI_ECP_MUL_INT( X, A, c )                                              \
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int_mod( grp, X, A, c ) )
+
+#define MPI_ECP_INV( dst, src )                                                 \
+    MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( (dst), (src), &grp->P ) )
+
+#define MPI_ECP_MOV( X, A )                                                     \
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) )
+
+#define MPI_ECP_SHIFT_L( X, count )                                             \
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, X, count ) )
+
+#define MPI_ECP_LSET( X, c )                                                    \
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, c ) )
+
+#define MPI_ECP_CMP_INT( X, c )                                                 \
+    mbedtls_mpi_cmp_int( X, c )
+
+#define MPI_ECP_CMP( X, Y )                                                     \
+    mbedtls_mpi_cmp_mpi( X, Y )
+
+/* Needs f_rng, p_rng to be defined. */
+#define MPI_ECP_RAND( X )                                                       \
+    MBEDTLS_MPI_CHK( mbedtls_mpi_random( (X), 2, &grp->P, f_rng, p_rng ) )
+
+/* Conditional negation
+ * Needs grp and a temporary MPI tmp to be defined. */
+#define MPI_ECP_COND_NEG( X, cond )                                        \
+    do                                                                     \
+    {                                                                      \
+        unsigned char nonzero = mbedtls_mpi_cmp_int( (X), 0 ) != 0;        \
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &tmp, &grp->P, (X) ) );      \
+        MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( (X), &tmp,          \
+                                                       nonzero & cond ) ); \
+    } while( 0 )
+
+#define MPI_ECP_NEG( X ) MPI_ECP_COND_NEG( (X), 1 )
+
+#define MPI_ECP_VALID( X )                      \
+    ( (X)->p != NULL )
+
+#define MPI_ECP_COND_ASSIGN( X, Y, cond )       \
+    MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( (X), (Y), (cond) ) )
+
+#define MPI_ECP_COND_SWAP( X, Y, cond )       \
+    MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( (X), (Y), (cond) ) )
+
 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
 /*
  * For curves in short Weierstrass form, we do all the internal operations in
@@ -1169,7 +1277,7 @@
  */
 static int ecp_normalize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt )
 {
-    if( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 )
+    if( MPI_ECP_CMP_INT( &pt->Z, 0 ) == 0 )
         return( 0 );
 
 #if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT)
@@ -1181,30 +1289,20 @@
     return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
 #else
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    mbedtls_mpi Zi, ZZi;
-    mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi );
+    mbedtls_mpi T;
+    mbedtls_mpi_init( &T );
 
-    /*
-     * X = X / Z^2  mod p
-     */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &Zi,      &pt->Z,     &grp->P ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &ZZi,     &Zi,        &Zi     ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->X,   &pt->X,     &ZZi    ) );
+    MPI_ECP_INV( &T,       &pt->Z );          /* T   <-          1 / Z   */
+    MPI_ECP_MUL( &pt->Y,   &pt->Y,     &T );  /* Y'  <- Y*T    = Y / Z   */
+    MPI_ECP_SQR( &T,       &T             );  /* T   <- T^2    = 1 / Z^2 */
+    MPI_ECP_MUL( &pt->X,   &pt->X,     &T );  /* X   <- X  * T = X / Z^2 */
+    MPI_ECP_MUL( &pt->Y,   &pt->Y,     &T );  /* Y'' <- Y' * T = Y / Z^3 */
 
-    /*
-     * Y = Y / Z^3  mod p
-     */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Y,   &pt->Y,     &ZZi    ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Y,   &pt->Y,     &Zi     ) );
-
-    /*
-     * Z = 1
-     */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
+    MPI_ECP_LSET( &pt->Z, 1 );
 
 cleanup:
 
-    mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi );
+    mbedtls_mpi_free( &T );
 
     return( ret );
 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) */
@@ -1237,52 +1335,58 @@
 #else
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t i;
-    mbedtls_mpi *c, u, Zi, ZZi;
+    mbedtls_mpi *c, t;
 
     if( ( c = mbedtls_calloc( T_size, sizeof( mbedtls_mpi ) ) ) == NULL )
         return( MBEDTLS_ERR_ECP_ALLOC_FAILED );
 
-    for( i = 0; i < T_size; i++ )
-        mbedtls_mpi_init( &c[i] );
+    mbedtls_mpi_init( &t );
 
-    mbedtls_mpi_init( &u ); mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi );
-
+    mpi_init_many( c, T_size );
     /*
-     * c[i] = Z_0 * ... * Z_i
+     * c[i] = Z_0 * ... * Z_i,   i = 0,..,n := T_size-1
      */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &c[0], &T[0]->Z ) );
+    MPI_ECP_MOV( &c[0], &T[0]->Z );
     for( i = 1; i < T_size; i++ )
     {
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &c[i], &c[i-1], &T[i]->Z ) );
+        MPI_ECP_MUL( &c[i], &c[i-1], &T[i]->Z );
     }
 
     /*
-     * u = 1 / (Z_0 * ... * Z_n) mod P
+     * c[n] = 1 / (Z_0 * ... * Z_n) mod P
      */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &u, &c[T_size-1], &grp->P ) );
+    MPI_ECP_INV( &c[T_size-1], &c[T_size-1] );
 
     for( i = T_size - 1; ; i-- )
     {
-        /*
-         * Zi = 1 / Z_i mod p
-         * u = 1 / (Z_0 * ... * Z_i) mod P
+        /* At the start of iteration i (note that i decrements), we have
+         * - c[j] = Z_0 * .... * Z_j        for j  < i,
+         * - c[j] = 1 / (Z_0 * .... * Z_j)  for j == i,
+         *
+         * This is maintained via
+         * - c[i-1] <- c[i] * Z_i
+         *
+         * We also derive 1/Z_i = c[i] * c[i-1] for i>0 and use that
+         * to do the actual normalization. For i==0, we already have
+         * c[0] = 1 / Z_0.
          */
-        if( i == 0 ) {
-            MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Zi, &u ) );
+
+        if( i > 0 )
+        {
+            /* Compute 1/Z_i and establish invariant for the next iteration. */
+            MPI_ECP_MUL( &t,      &c[i], &c[i-1]  );
+            MPI_ECP_MUL( &c[i-1], &c[i], &T[i]->Z );
         }
         else
         {
-            MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &Zi, &u, &c[i-1]  ) );
-            MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &u,  &u, &T[i]->Z ) );
+            MPI_ECP_MOV( &t, &c[0] );
         }
 
-        /*
-         * proceed as in normalize()
-         */
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &ZZi,     &Zi,      &Zi  ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T[i]->X, &T[i]->X, &ZZi ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T[i]->Y, &T[i]->Y, &ZZi ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T[i]->Y, &T[i]->Y, &Zi  ) );
+        /* Now t holds 1 / Z_i; normalize as in ecp_normalize_jac() */
+        MPI_ECP_MUL( &T[i]->Y, &T[i]->Y, &t );
+        MPI_ECP_SQR( &t,       &t           );
+        MPI_ECP_MUL( &T[i]->X, &T[i]->X, &t );
+        MPI_ECP_MUL( &T[i]->Y, &T[i]->Y, &t );
 
         /*
          * Post-precessing: reclaim some memory by shrinking coordinates
@@ -1292,7 +1396,8 @@
          */
         MBEDTLS_MPI_CHK( mbedtls_mpi_shrink( &T[i]->X, grp->P.n ) );
         MBEDTLS_MPI_CHK( mbedtls_mpi_shrink( &T[i]->Y, grp->P.n ) );
-        mbedtls_mpi_free( &T[i]->Z );
+
+        MPI_ECP_LSET( &T[i]->Z, 1 );
 
         if( i == 0 )
             break;
@@ -1300,9 +1405,8 @@
 
 cleanup:
 
-    mbedtls_mpi_free( &u ); mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi );
-    for( i = 0; i < T_size; i++ )
-        mbedtls_mpi_free( &c[i] );
+    mbedtls_mpi_free( &t );
+    mpi_free_many( c, T_size );
     mbedtls_free( c );
 
     return( ret );
@@ -1318,19 +1422,13 @@
                             unsigned char inv )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    unsigned char nonzero;
-    mbedtls_mpi mQY;
+    mbedtls_mpi tmp;
+    mbedtls_mpi_init( &tmp );
 
-    mbedtls_mpi_init( &mQY );
-
-    /* Use the fact that -Q.Y mod P = P - Q.Y unless Q.Y == 0 */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &mQY, &grp->P, &Q->Y ) );
-    nonzero = mbedtls_mpi_cmp_int( &Q->Y, 0 ) != 0;
-    MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &Q->Y, &mQY, inv & nonzero ) );
+    MPI_ECP_COND_NEG( &Q->Y, inv );
 
 cleanup:
-    mbedtls_mpi_free( &mQY );
-
+    mbedtls_mpi_free( &tmp );
     return( ret );
 }
 
@@ -1349,7 +1447,8 @@
  *             3M + 6S + 1a     otherwise
  */
 static int ecp_double_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
-                           const mbedtls_ecp_point *P )
+                           const mbedtls_ecp_point *P,
+                           mbedtls_mpi tmp[4] )
 {
 #if defined(MBEDTLS_SELF_TEST)
     dbl_count++;
@@ -1364,67 +1463,64 @@
     return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
 #else
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    mbedtls_mpi M, S, T, U;
-
-    mbedtls_mpi_init( &M ); mbedtls_mpi_init( &S ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &U );
 
     /* Special case for A = -3 */
     if( grp->A.p == NULL )
     {
-        /* M = 3(X + Z^2)(X - Z^2) */
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S,  &P->Z,  &P->Z   ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &T,  &P->X,  &S      ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &U,  &P->X,  &S      ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S,  &T,     &U      ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M,  &S,     3       ) ); MOD_ADD( M );
+        /* tmp[0] <- M = 3(X + Z^2)(X - Z^2) */
+        MPI_ECP_SQR(     &tmp[1],  &P->Z                );
+        MPI_ECP_ADD(     &tmp[2],  &P->X,  &tmp[1]      );
+        MPI_ECP_SUB(     &tmp[3],  &P->X,  &tmp[1]      );
+        MPI_ECP_MUL(     &tmp[1],  &tmp[2],     &tmp[3] );
+        MPI_ECP_MUL_INT( &tmp[0],  &tmp[1],     3       );
     }
     else
     {
-        /* M = 3.X^2 */
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S,  &P->X,  &P->X   ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M,  &S,     3       ) ); MOD_ADD( M );
+        /* tmp[0] <- M = 3.X^2 + A.Z^4 */
+        MPI_ECP_SQR(     &tmp[1],  &P->X  );
+        MPI_ECP_MUL_INT( &tmp[0],  &tmp[1],  3 );
 
         /* Optimize away for "koblitz" curves with A = 0 */
-        if( mbedtls_mpi_cmp_int( &grp->A, 0 ) != 0 )
+        if( MPI_ECP_CMP_INT( &grp->A, 0 ) != 0 )
         {
             /* M += A.Z^4 */
-            MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S,  &P->Z,  &P->Z   ) );
-            MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T,  &S,     &S      ) );
-            MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S,  &T,     &grp->A ) );
-            MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &M,  &M,     &S      ) );
+            MPI_ECP_SQR( &tmp[1],  &P->Z                );
+            MPI_ECP_SQR( &tmp[2],  &tmp[1]              );
+            MPI_ECP_MUL( &tmp[1],  &tmp[2],     &grp->A );
+            MPI_ECP_ADD( &tmp[0],  &tmp[0],     &tmp[1] );
         }
     }
 
-    /* S = 4.X.Y^2 */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T,  &P->Y,  &P->Y   ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &T,  1               ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S,  &P->X,  &T      ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &S,  1               ) );
+    /* tmp[1] <- S = 4.X.Y^2 */
+    MPI_ECP_SQR(     &tmp[2],  &P->Y     );
+    MPI_ECP_SHIFT_L( &tmp[2],  1         );
+    MPI_ECP_MUL(     &tmp[1],  &P->X, &tmp[2] );
+    MPI_ECP_SHIFT_L( &tmp[1],  1         );
 
-    /* U = 8.Y^4 */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &U,  &T,     &T      ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &U,  1               ) );
+    /* tmp[3] <- U = 8.Y^4 */
+    MPI_ECP_SQR(     &tmp[3],  &tmp[2] );
+    MPI_ECP_SHIFT_L( &tmp[3],  1       );
 
-    /* T = M^2 - 2.S */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T,  &M,     &M      ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T,  &T,     &S      ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T,  &T,     &S      ) );
+    /* tmp[2] <- T = M^2 - 2.S */
+    MPI_ECP_SQR( &tmp[2],  &tmp[0]     );
+    MPI_ECP_SUB( &tmp[2],  &tmp[2], &tmp[1] );
+    MPI_ECP_SUB( &tmp[2],  &tmp[2], &tmp[1] );
 
-    /* S = M(S - T) - U */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &S,  &S,     &T      ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S,  &S,     &M      ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &S,  &S,     &U      ) );
+    /* tmp[1] <- S = M(S - T) - U */
+    MPI_ECP_SUB( &tmp[1],  &tmp[1],     &tmp[2] );
+    MPI_ECP_MUL( &tmp[1],  &tmp[1],     &tmp[0] );
+    MPI_ECP_SUB( &tmp[1],  &tmp[1],     &tmp[3] );
 
-    /* U = 2.Y.Z */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &U,  &P->Y,  &P->Z   ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &U,  1               ) );
+    /* tmp[3] <- U = 2.Y.Z */
+    MPI_ECP_MUL(     &tmp[3],  &P->Y,  &P->Z   );
+    MPI_ECP_SHIFT_L( &tmp[3],  1               );
 
-    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &T ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &S ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Z, &U ) );
+    /* Store results */
+    MPI_ECP_MOV( &R->X, &tmp[2] );
+    MPI_ECP_MOV( &R->Y, &tmp[1] );
+    MPI_ECP_MOV( &R->Z, &tmp[3] );
 
 cleanup:
-    mbedtls_mpi_free( &M ); mbedtls_mpi_free( &S ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &U );
 
     return( ret );
 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) */
@@ -1436,6 +1532,10 @@
  * The coordinates of Q must be normalized (= affine),
  * but those of P don't need to. R is not normalized.
  *
+ * P,Q,R may alias, but only at the level of EC points: they must be either
+ * equal as pointers, or disjoint (including the coordinate data buffers).
+ * Fine-grained aliasing at the level of coordinates is not supported.
+ *
  * Special cases: (1) P or Q is zero, (2) R is zero, (3) P == Q.
  * None of these cases can happen as intermediate step in ecp_mul_comb():
  * - at each step, P, Q and R are multiples of the base point, the factor
@@ -1444,12 +1544,11 @@
  *   due to the choice of precomputed points in the modified comb method.
  * So branches for these cases do not leak secret information.
  *
- * We accept Q->Z being unset (saving memory in tables) as meaning 1.
- *
  * Cost: 1A := 8M + 3S
  */
 static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
-                          const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q )
+                          const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q,
+                          mbedtls_mpi tmp[4] )
 {
 #if defined(MBEDTLS_SELF_TEST)
     add_count++;
@@ -1464,39 +1563,45 @@
     return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
 #else
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    mbedtls_mpi T1, T2, T3, T4, X, Y, Z;
+
+    /* NOTE: Aliasing between input and output is allowed, so one has to make
+     *       sure that at the point X,Y,Z are written, {P,Q}->{X,Y,Z} are no
+     *       longer read from. */
+    mbedtls_mpi * const X = &R->X;
+    mbedtls_mpi * const Y = &R->Y;
+    mbedtls_mpi * const Z = &R->Z;
+
+    if( !MPI_ECP_VALID( &Q->Z ) )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
 
     /*
      * Trivial cases: P == 0 or Q == 0 (case 1)
      */
-    if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 )
+    if( MPI_ECP_CMP_INT( &P->Z, 0 ) == 0 )
         return( mbedtls_ecp_copy( R, Q ) );
 
-    if( Q->Z.p != NULL && mbedtls_mpi_cmp_int( &Q->Z, 0 ) == 0 )
+    if( MPI_ECP_CMP_INT( &Q->Z, 0 ) == 0 )
         return( mbedtls_ecp_copy( R, P ) );
 
     /*
      * Make sure Q coordinates are normalized
      */
-    if( Q->Z.p != NULL && mbedtls_mpi_cmp_int( &Q->Z, 1 ) != 0 )
+    if( MPI_ECP_CMP_INT( &Q->Z, 1 ) != 0 )
         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
 
-    mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); mbedtls_mpi_init( &T3 ); mbedtls_mpi_init( &T4 );
-    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
-
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T1,  &P->Z,  &P->Z ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T2,  &T1,    &P->Z ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T1,  &T1,    &Q->X ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T2,  &T2,    &Q->Y ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T1,  &T1,    &P->X ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T2,  &T2,    &P->Y ) );
+    MPI_ECP_SQR( &tmp[0], &P->Z         );
+    MPI_ECP_MUL( &tmp[1], &tmp[0], &P->Z );
+    MPI_ECP_MUL( &tmp[0], &tmp[0], &Q->X );
+    MPI_ECP_MUL( &tmp[1], &tmp[1], &Q->Y );
+    MPI_ECP_SUB( &tmp[0], &tmp[0], &P->X );
+    MPI_ECP_SUB( &tmp[1], &tmp[1], &P->Y );
 
     /* Special cases (2) and (3) */
-    if( mbedtls_mpi_cmp_int( &T1, 0 ) == 0 )
+    if( MPI_ECP_CMP_INT( &tmp[0], 0 ) == 0 )
     {
-        if( mbedtls_mpi_cmp_int( &T2, 0 ) == 0 )
+        if( MPI_ECP_CMP_INT( &tmp[1], 0 ) == 0 )
         {
-            ret = ecp_double_jac( grp, R, P );
+            ret = ecp_double_jac( grp, R, P, tmp );
             goto cleanup;
         }
         else
@@ -1506,29 +1611,27 @@
         }
     }
 
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &Z,   &P->Z,  &T1   ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T3,  &T1,    &T1   ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T4,  &T3,    &T1   ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T3,  &T3,    &P->X ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T1, &T3 ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &T1,  1     ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &X,   &T2,    &T2   ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &X,   &X,     &T1   ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &X,   &X,     &T4   ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T3,  &T3,    &X    ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T3,  &T3,    &T2   ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T4,  &T4,    &P->Y ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &Y,   &T3,    &T4   ) );
+    /* {P,Q}->Z no longer used, so OK to write to Z even if there's aliasing. */
+    MPI_ECP_MUL( Z,        &P->Z,    &tmp[0] );
+    MPI_ECP_SQR( &tmp[2],  &tmp[0]           );
+    MPI_ECP_MUL( &tmp[3],  &tmp[2],  &tmp[0] );
+    MPI_ECP_MUL( &tmp[2],  &tmp[2],  &P->X   );
 
-    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &X ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &Y ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Z, &Z ) );
+    MPI_ECP_MOV( &tmp[0], &tmp[2] );
+    MPI_ECP_SHIFT_L( &tmp[0], 1 );
+
+    /* {P,Q}->X no longer used, so OK to write to X even if there's aliasing. */
+    MPI_ECP_SQR( X,        &tmp[1]           );
+    MPI_ECP_SUB( X,        X,        &tmp[0] );
+    MPI_ECP_SUB( X,        X,        &tmp[3] );
+    MPI_ECP_SUB( &tmp[2],  &tmp[2],  X       );
+    MPI_ECP_MUL( &tmp[2],  &tmp[2],  &tmp[1] );
+    MPI_ECP_MUL( &tmp[3],  &tmp[3],  &P->Y   );
+    /* {P,Q}->Y no longer used, so OK to write to Y even if there's aliasing. */
+    MPI_ECP_SUB( Y,     &tmp[2],     &tmp[3] );
 
 cleanup:
 
-    mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 ); mbedtls_mpi_free( &T3 ); mbedtls_mpi_free( &T4 );
-    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
-
     return( ret );
 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_ADD_MIXED_ALT) */
 }
@@ -1552,26 +1655,28 @@
     return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
 #else
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    mbedtls_mpi l, ll;
+    mbedtls_mpi l;
 
-    mbedtls_mpi_init( &l ); mbedtls_mpi_init( &ll );
+    mbedtls_mpi_init( &l );
 
     /* Generate l such that 1 < l < p */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_random( &l, 2, &grp->P, f_rng, p_rng ) );
+    MPI_ECP_RAND( &l );
 
-    /* Z = l * Z */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Z,   &pt->Z,     &l  ) );
+    /* Z' = l * Z */
+    MPI_ECP_MUL( &pt->Z,   &pt->Z,     &l );
 
-    /* X = l^2 * X */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &ll,      &l,         &l  ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->X,   &pt->X,     &ll ) );
+    /* Y' = l * Y */
+    MPI_ECP_MUL( &pt->Y,   &pt->Y,     &l );
 
-    /* Y = l^3 * Y */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &ll,      &ll,        &l  ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Y,   &pt->Y,     &ll ) );
+    /* X' = l^2 * X */
+    MPI_ECP_SQR( &l,       &l             );
+    MPI_ECP_MUL( &pt->X,   &pt->X,     &l );
+
+    /* Y'' = l^2 * Y' = l^3 * Y */
+    MPI_ECP_MUL( &pt->Y,   &pt->Y,     &l );
 
 cleanup:
-    mbedtls_mpi_free( &l ); mbedtls_mpi_free( &ll );
+    mbedtls_mpi_free( &l );
 
     if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
         ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
@@ -1714,6 +1819,10 @@
     const unsigned char T_size = 1U << ( w - 1 );
     mbedtls_ecp_point *cur, *TT[COMB_MAX_PRE - 1];
 
+    mbedtls_mpi tmp[4];
+
+    mpi_init_many( tmp, sizeof( tmp ) / sizeof( mbedtls_mpi ) );
+
 #if defined(MBEDTLS_ECP_RESTARTABLE)
     if( rs_ctx != NULL && rs_ctx->rsm != NULL )
     {
@@ -1764,7 +1873,7 @@
         if( j % d == 0 )
             MBEDTLS_MPI_CHK( mbedtls_ecp_copy( cur, T + ( i >> 1 ) ) );
 
-        MBEDTLS_MPI_CHK( ecp_double_jac( grp, cur, cur ) );
+        MBEDTLS_MPI_CHK( ecp_double_jac( grp, cur, cur, tmp ) );
     }
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
@@ -1774,8 +1883,11 @@
 norm_dbl:
 #endif
     /*
-     * Normalize current elements in T. As T has holes,
-     * use an auxiliary array of pointers to elements in T.
+     * Normalize current elements in T to allow them to be used in
+     * ecp_add_mixed() below, which requires one normalized input.
+     *
+     * As T has holes, use an auxiliary array of pointers to elements in T.
+     *
      */
     j = 0;
     for( i = 1; i < T_size; i <<= 1 )
@@ -1801,7 +1913,7 @@
     {
         j = i;
         while( j-- )
-            MBEDTLS_MPI_CHK( ecp_add_mixed( grp, &T[i + j], &T[j], &T[i] ) );
+            MBEDTLS_MPI_CHK( ecp_add_mixed( grp, &T[i + j], &T[j], &T[i], tmp ) );
     }
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
@@ -1822,7 +1934,18 @@
 
     MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, j ) );
 
+    /* Free Z coordinate (=1 after normalization) to save RAM.
+     * This makes T[i] invalid as mbedtls_ecp_points, but this is OK
+     * since from this point onwards, they are only accessed indirectly
+     * via the getter function ecp_select_comb() which does set the
+     * target's Z coordinate to 1. */
+    for( i = 0; i < T_size; i++ )
+        mbedtls_mpi_free( &T[i].Z );
+
 cleanup:
+
+    mpi_free_many( tmp, sizeof( tmp ) / sizeof( mbedtls_mpi ) );
+
 #if defined(MBEDTLS_ECP_RESTARTABLE)
     if( rs_ctx != NULL && rs_ctx->rsm != NULL &&
         ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
@@ -1853,13 +1976,15 @@
     /* Read the whole table to thwart cache-based timing attacks */
     for( j = 0; j < T_size; j++ )
     {
-        MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &R->X, &T[j].X, j == ii ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &R->Y, &T[j].Y, j == ii ) );
+        MPI_ECP_COND_ASSIGN( &R->X, &T[j].X, j == ii );
+        MPI_ECP_COND_ASSIGN( &R->Y, &T[j].Y, j == ii );
     }
 
     /* Safely invert result if i is "negative" */
     MBEDTLS_MPI_CHK( ecp_safe_invert_jac( grp, R, i >> 7 ) );
 
+    MPI_ECP_LSET( &R->Z, 1 );
+
 cleanup:
     return( ret );
 }
@@ -1879,9 +2004,11 @@
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     mbedtls_ecp_point Txi;
+    mbedtls_mpi tmp[4];
     size_t i;
 
     mbedtls_ecp_point_init( &Txi );
+    mpi_init_many( tmp, sizeof( tmp ) / sizeof( mbedtls_mpi ) );
 
 #if !defined(MBEDTLS_ECP_RESTARTABLE)
     (void) rs_ctx;
@@ -1907,7 +2034,6 @@
         /* Start with a non-zero point and randomize its coordinates */
         i = d;
         MBEDTLS_MPI_CHK( ecp_select_comb( grp, R, T, T_size, x[i] ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 1 ) );
         if( f_rng != 0 )
             MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, R, f_rng, p_rng ) );
     }
@@ -1917,14 +2043,15 @@
         MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_DBL + MBEDTLS_ECP_OPS_ADD );
         --i;
 
-        MBEDTLS_MPI_CHK( ecp_double_jac( grp, R, R ) );
+        MBEDTLS_MPI_CHK( ecp_double_jac( grp, R, R, tmp ) );
         MBEDTLS_MPI_CHK( ecp_select_comb( grp, &Txi, T, T_size, x[i] ) );
-        MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, R, &Txi ) );
+        MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, R, &Txi, tmp ) );
     }
 
 cleanup:
 
     mbedtls_ecp_point_free( &Txi );
+    mpi_free_many( tmp, sizeof( tmp ) / sizeof( mbedtls_mpi ) );
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
     if( rs_ctx != NULL && rs_ctx->rsm != NULL &&
@@ -2127,8 +2254,8 @@
 
     /* Is P the base point ? */
 #if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
-    p_eq_g = ( mbedtls_mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 &&
-               mbedtls_mpi_cmp_mpi( &P->X, &grp->G.X ) == 0 );
+    p_eq_g = ( MPI_ECP_CMP( &P->Y, &grp->G.Y ) == 0 &&
+               MPI_ECP_CMP( &P->X, &grp->G.X ) == 0 );
 #else
     p_eq_g = 0;
 #endif
@@ -2258,9 +2385,9 @@
     return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
 #else
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &P->Z, &P->Z, &grp->P ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &P->X, &P->X, &P->Z ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) );
+    MPI_ECP_INV( &P->Z, &P->Z );
+    MPI_ECP_MUL( &P->X, &P->X, &P->Z );
+    MPI_ECP_LSET( &P->Z, 1 );
 
 cleanup:
     return( ret );
@@ -2291,10 +2418,10 @@
     mbedtls_mpi_init( &l );
 
     /* Generate l such that 1 < l < p */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_random( &l, 2, &grp->P, f_rng, p_rng ) );
+    MPI_ECP_RAND( &l );
 
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &P->X, &P->X, &l ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &P->Z, &P->Z, &l ) );
+    MPI_ECP_MUL( &P->X, &P->X, &l );
+    MPI_ECP_MUL( &P->Z, &P->Z, &l );
 
 cleanup:
     mbedtls_mpi_free( &l );
@@ -2323,7 +2450,8 @@
 static int ecp_double_add_mxz( const mbedtls_ecp_group *grp,
                                mbedtls_ecp_point *R, mbedtls_ecp_point *S,
                                const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q,
-                               const mbedtls_mpi *d )
+                               const mbedtls_mpi *d,
+                               mbedtls_mpi T[4] )
 {
 #if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT)
     if( mbedtls_internal_ecp_grp_capable( grp ) )
@@ -2334,35 +2462,27 @@
     return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
 #else
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    mbedtls_mpi A, AA, B, BB, E, C, D, DA, CB;
 
-    mbedtls_mpi_init( &A ); mbedtls_mpi_init( &AA ); mbedtls_mpi_init( &B );
-    mbedtls_mpi_init( &BB ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &C );
-    mbedtls_mpi_init( &D ); mbedtls_mpi_init( &DA ); mbedtls_mpi_init( &CB );
-
-    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &A,    &P->X,   &P->Z ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &AA,   &A,      &A    ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &B,    &P->X,   &P->Z ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &BB,   &B,      &B    ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &E,    &AA,     &BB   ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &C,    &Q->X,   &Q->Z ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &D,    &Q->X,   &Q->Z ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &DA,   &D,      &A    ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &CB,   &C,      &B    ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &S->X, &DA,     &CB   ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S->X, &S->X,   &S->X ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &S->Z, &DA,     &CB   ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S->Z, &S->Z,   &S->Z ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S->Z, d,       &S->Z ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &R->X, &AA,     &BB   ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &R->Z, &grp->A, &E    ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &R->Z, &BB,     &R->Z ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &R->Z, &E,      &R->Z ) );
+    MPI_ECP_ADD( &T[0], &P->X,   &P->Z ); /* Pp := PX + PZ                    */
+    MPI_ECP_SUB( &T[1], &P->X,   &P->Z ); /* Pm := PX - PZ                    */
+    MPI_ECP_ADD( &T[2], &Q->X,   &Q->Z ); /* Qp := QX + XZ                    */
+    MPI_ECP_SUB( &T[3], &Q->X,   &Q->Z ); /* Qm := QX - QZ                    */
+    MPI_ECP_MUL( &T[3], &T[3],   &T[0] ); /* Qm * Pp                          */
+    MPI_ECP_MUL( &T[2], &T[2],   &T[1] ); /* Qp * Pm                          */
+    MPI_ECP_SQR( &T[0], &T[0]          ); /* Pp^2                             */
+    MPI_ECP_SQR( &T[1], &T[1]          ); /* Pm^2                             */
+    MPI_ECP_MUL( &R->X, &T[0],   &T[1] ); /* Pp^2 * Pm^2                      */
+    MPI_ECP_SUB( &T[0], &T[0],   &T[1] ); /* Pp^2 - Pm^2                      */
+    MPI_ECP_MUL( &R->Z, &grp->A, &T[0] ); /* A * (Pp^2 - Pm^2)                */
+    MPI_ECP_ADD( &R->Z, &T[1],   &R->Z ); /* [ A * (Pp^2-Pm^2) ] + Pm^2       */
+    MPI_ECP_ADD( &S->X, &T[3],   &T[2] ); /* Qm*Pp + Qp*Pm                    */
+    MPI_ECP_SQR( &S->X, &S->X          ); /* (Qm*Pp + Qp*Pm)^2                */
+    MPI_ECP_SUB( &S->Z, &T[3],   &T[2] ); /* Qm*Pp - Qp*Pm                    */
+    MPI_ECP_SQR( &S->Z, &S->Z          ); /* (Qm*Pp - Qp*Pm)^2                */
+    MPI_ECP_MUL( &S->Z, d,       &S->Z ); /* d * ( Qm*Pp - Qp*Pm )^2          */
+    MPI_ECP_MUL( &R->Z, &T[0],   &R->Z ); /* [A*(Pp^2-Pm^2)+Pm^2]*(Pp^2-Pm^2) */
 
 cleanup:
-    mbedtls_mpi_free( &A ); mbedtls_mpi_free( &AA ); mbedtls_mpi_free( &B );
-    mbedtls_mpi_free( &BB ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &C );
-    mbedtls_mpi_free( &D ); mbedtls_mpi_free( &DA ); mbedtls_mpi_free( &CB );
 
     return( ret );
 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) */
@@ -2382,22 +2502,25 @@
     unsigned char b;
     mbedtls_ecp_point RP;
     mbedtls_mpi PX;
+    mbedtls_mpi tmp[4];
     mbedtls_ecp_point_init( &RP ); mbedtls_mpi_init( &PX );
 
+    mpi_init_many( tmp, sizeof( tmp ) / sizeof( mbedtls_mpi ) );
+
     if( f_rng == NULL )
         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
 
     /* Save PX and read from P before writing to R, in case P == R */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &PX, &P->X ) );
+    MPI_ECP_MOV( &PX, &P->X );
     MBEDTLS_MPI_CHK( mbedtls_ecp_copy( &RP, P ) );
 
     /* Set R to zero in modified x/z coordinates */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->X, 1 ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 0 ) );
+    MPI_ECP_LSET( &R->X, 1 );
+    MPI_ECP_LSET( &R->Z, 0 );
     mbedtls_mpi_free( &R->Y );
 
     /* RP.X might be sligtly larger than P, so reduce it */
-    MOD_ADD( RP.X );
+    MOD_ADD( &RP.X );
 
     /* Randomize coordinates of the starting point */
     MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, &RP, f_rng, p_rng ) );
@@ -2414,11 +2537,11 @@
          *  else   double_add( R, RP, R, RP )
          * but using safe conditional swaps to avoid leaks
          */
-        MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->X, &RP.X, b ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) );
-        MBEDTLS_MPI_CHK( ecp_double_add_mxz( grp, R, &RP, R, &RP, &PX ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->X, &RP.X, b ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) );
+        MPI_ECP_COND_SWAP( &R->X, &RP.X, b );
+        MPI_ECP_COND_SWAP( &R->Z, &RP.Z, b );
+        MBEDTLS_MPI_CHK( ecp_double_add_mxz( grp, R, &RP, R, &RP, &PX, tmp ) );
+        MPI_ECP_COND_SWAP( &R->X, &RP.X, b );
+        MPI_ECP_COND_SWAP( &R->Z, &RP.Z, b );
     }
 
     /*
@@ -2438,6 +2561,7 @@
 cleanup:
     mbedtls_ecp_point_free( &RP ); mbedtls_mpi_free( &PX );
 
+    mpi_free_many( tmp, sizeof( tmp ) / sizeof( mbedtls_mpi ) );
     return( ret );
 }
 
@@ -2566,23 +2690,23 @@
      * YY = Y^2
      * RHS = X (X^2 + A) + B = X^3 + A X + B
      */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &YY,  &pt->Y,   &pt->Y  ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &RHS, &pt->X,   &pt->X  ) );
+    MPI_ECP_SQR( &YY,  &pt->Y );
+    MPI_ECP_SQR( &RHS, &pt->X );
 
     /* Special case for A = -3 */
     if( grp->A.p == NULL )
     {
-        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &RHS, &RHS, 3       ) );  MOD_SUB( RHS );
+        MPI_ECP_SUB_INT( &RHS, &RHS, 3 );
     }
     else
     {
-        MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &RHS, &RHS, &grp->A ) );
+        MPI_ECP_ADD( &RHS, &RHS, &grp->A );
     }
 
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &RHS, &RHS,     &pt->X  ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &RHS, &RHS,     &grp->B ) );
+    MPI_ECP_MUL( &RHS, &RHS, &pt->X  );
+    MPI_ECP_ADD( &RHS, &RHS, &grp->B );
 
-    if( mbedtls_mpi_cmp_mpi( &YY, &RHS ) != 0 )
+    if( MPI_ECP_CMP( &YY, &RHS ) != 0 )
         ret = MBEDTLS_ERR_ECP_INVALID_KEY;
 
 cleanup:
@@ -2605,6 +2729,8 @@
                                       mbedtls_ecp_restart_ctx *rs_ctx )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    mbedtls_mpi tmp;
+    mbedtls_mpi_init( &tmp );
 
     if( mbedtls_mpi_cmp_int( m, 0 ) == 0 )
     {
@@ -2617,8 +2743,7 @@
     else if( mbedtls_mpi_cmp_int( m, -1 ) == 0 )
     {
         MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) );
-        if( mbedtls_mpi_cmp_int( &R->Y, 0 ) != 0 )
-            MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &R->Y, &grp->P, &R->Y ) );
+        MPI_ECP_NEG( &R->Y );
     }
     else
     {
@@ -2627,6 +2752,8 @@
     }
 
 cleanup:
+    mbedtls_mpi_free( &tmp );
+
     return( ret );
 }
 
@@ -2644,6 +2771,7 @@
     mbedtls_ecp_point mP;
     mbedtls_ecp_point *pmP = &mP;
     mbedtls_ecp_point *pR = R;
+    mbedtls_mpi tmp[4];
 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
     char is_grp_capable = 0;
 #endif
@@ -2658,6 +2786,7 @@
         return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
 
     mbedtls_ecp_point_init( &mP );
+    mpi_init_many( tmp, sizeof( tmp ) / sizeof( mbedtls_mpi ) );
 
     ECP_RS_ENTER( ma );
 
@@ -2699,7 +2828,7 @@
 add:
 #endif
     MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_ADD );
-    MBEDTLS_MPI_CHK( ecp_add_mixed( grp, pR, pmP, pR ) );
+    MBEDTLS_MPI_CHK( ecp_add_mixed( grp, pR, pmP, pR, tmp ) );
 #if defined(MBEDTLS_ECP_RESTARTABLE)
     if( rs_ctx != NULL && rs_ctx->ma != NULL )
         rs_ctx->ma->state = ecp_rsma_norm;
@@ -2715,6 +2844,9 @@
 #endif
 
 cleanup:
+
+    mpi_free_many( tmp, sizeof( tmp ) / sizeof( mbedtls_mpi ) );
+
 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
     if( is_grp_capable )
         mbedtls_internal_ecp_free( grp );
diff --git a/library/psa_its_file.c b/library/psa_its_file.c
index c4782cd..f058720 100644
--- a/library/psa_its_file.c
+++ b/library/psa_its_file.c
@@ -184,6 +184,11 @@
                           const void *p_data,
                           psa_storage_create_flags_t create_flags )
 {
+    if( uid == 0 )
+    {
+        return( PSA_ERROR_INVALID_HANDLE );
+    }
+
     psa_status_t status = PSA_ERROR_STORAGE_FAILURE;
     char filename[PSA_ITS_STORAGE_FILENAME_LENGTH];
     FILE *stream = NULL;
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index e411b70..2f29ede 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -19,7 +19,7 @@
 
 #include "common.h"
 
-#if defined(MBEDTLS_SSL_CLI_C)
+#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_PROTO_TLS1_2)
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
@@ -90,76 +90,6 @@
 
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
 
-#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
-int mbedtls_ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
-                                    unsigned char *buf,
-                                    const unsigned char *end,
-                                    size_t *olen )
-{
-    unsigned char *p = buf;
-    size_t hostname_len;
-
-    *olen = 0;
-
-    if( ssl->hostname == NULL )
-        return( 0 );
-
-    MBEDTLS_SSL_DEBUG_MSG( 3,
-        ( "client hello, adding server name extension: %s",
-          ssl->hostname ) );
-
-    hostname_len = strlen( ssl->hostname );
-
-    MBEDTLS_SSL_CHK_BUF_PTR( p, end, hostname_len + 9 );
-
-    /*
-     * Sect. 3, RFC 6066 (TLS Extensions Definitions)
-     *
-     * In order to provide any of the server names, clients MAY include an
-     * extension of type "server_name" in the (extended) client hello. The
-     * "extension_data" field of this extension SHALL contain
-     * "ServerNameList" where:
-     *
-     * struct {
-     *     NameType name_type;
-     *     select (name_type) {
-     *         case host_name: HostName;
-     *     } name;
-     * } ServerName;
-     *
-     * enum {
-     *     host_name(0), (255)
-     * } NameType;
-     *
-     * opaque HostName<1..2^16-1>;
-     *
-     * struct {
-     *     ServerName server_name_list<1..2^16-1>
-     * } ServerNameList;
-     *
-     */
-    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SERVERNAME, p, 0 );
-    p += 2;
-
-    MBEDTLS_PUT_UINT16_BE( hostname_len + 5, p, 0 );
-    p += 2;
-
-    MBEDTLS_PUT_UINT16_BE( hostname_len + 3, p, 0 );
-    p += 2;
-
-    *p++ = MBEDTLS_BYTE_0( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME );
-
-    MBEDTLS_PUT_UINT16_BE( hostname_len, p, 0 );
-    p += 2;
-
-    memcpy( p, ssl->hostname, hostname_len );
-
-    *olen = hostname_len + 9;
-
-    return( 0 );
-}
-#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
-
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
 static int ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
                                         unsigned char *buf,
@@ -1028,8 +958,7 @@
     ext_len += olen;
 #endif
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
-    defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
     if( ( ret = mbedtls_ssl_write_sig_alg_ext( ssl, p + 2 + ext_len,
                                                end, &olen ) ) != 0 )
     {
@@ -1037,7 +966,7 @@
         return( ret );
     }
     ext_len += olen;
-#endif
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -2334,12 +2263,7 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) );
 
-#if defined(MBEDTLS_ECP_C)
     if( mbedtls_ssl_check_curve( ssl, grp_id ) != 0 )
-#else
-    if( ssl->handshake->ecdh_ctx.grp.nbits < 163 ||
-        ssl->handshake->ecdh_ctx.grp.nbits > 521 )
-#endif
         return( -1 );
 
     MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
@@ -2366,9 +2290,16 @@
     mbedtls_ssl_handshake_params *handshake = ssl->handshake;
 
     /*
-     * Parse ECC group
+     * struct {
+     *     ECParameters curve_params;
+     *     ECPoint      public;
+     * } ServerECDHParams;
+     *
+     *  1       curve_type (must be "named_curve")
+     *  2..3    NamedCurve
+     *  4       ECPoint.len
+     *  5+      ECPoint contents
      */
-
     if( end - *p < 4 )
         return( MBEDTLS_ERR_SSL_DECODE_ERROR );
 
@@ -2381,6 +2312,15 @@
     tls_id <<= 8;
     tls_id |= *(*p)++;
 
+    /* Check it's a curve we offered */
+    if( mbedtls_ssl_check_curve_tls_id( ssl, tls_id ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2,
+            ( "bad server key exchange message (ECDHE curve): %u",
+              (unsigned) tls_id ) );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
+    }
+
     /* Convert EC group to PSA key type. */
     if( ( handshake->ecdh_psa_type =
           mbedtls_psa_parse_tls_ecc_group( tls_id, &ecdh_bits ) ) == 0 )
@@ -2391,24 +2331,18 @@
         return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     handshake->ecdh_bits = (uint16_t) ecdh_bits;
 
-    /*
-     * Put peer's ECDH public key in the format understood by PSA.
-     */
-
+    /* Keep a copy of the peer's public key */
     ecpoint_len = *(*p)++;
     if( (size_t)( end - *p ) < ecpoint_len )
         return( MBEDTLS_ERR_SSL_DECODE_ERROR );
 
-    if( mbedtls_psa_tls_ecpoint_to_psa_ec(
-                                    *p, ecpoint_len,
-                                    handshake->ecdh_psa_peerkey,
-                                    sizeof( handshake->ecdh_psa_peerkey ),
-                                    &handshake->ecdh_psa_peerkey_len ) != 0 )
-    {
-        return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
-    }
+    if( ecpoint_len > sizeof( handshake->ecdh_psa_peerkey ) )
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
 
+    memcpy( handshake->ecdh_psa_peerkey, *p, ecpoint_len );
+    handshake->ecdh_psa_peerkey_len = ecpoint_len;
     *p += ecpoint_len;
+
     return( 0 );
 }
 #endif /* MBEDTLS_USE_PSA_CRYPTO &&
@@ -2568,13 +2502,11 @@
         return( ret );
     }
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
     if( len_bytes == 2 )
     {
         MBEDTLS_PUT_UINT16_BE( *olen, ssl->out_msg, offset );
         *olen += 2;
     }
-#endif
 
 #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
     /* We don't need the peer's public key anymore. Free it. */
@@ -2585,7 +2517,6 @@
 #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
           MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
@@ -2650,7 +2581,6 @@
 #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
           MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
           MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
@@ -2935,7 +2865,6 @@
         /*
          * Handle the digitally-signed structure
          */
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
         if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
         {
             if( ssl_parse_signature_algorithm( ssl, &p, end,
@@ -2963,7 +2892,6 @@
             }
         }
         else
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
@@ -3000,7 +2928,6 @@
         /*
          * Compute the hash that has been signed
          */
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
         if( md_alg != MBEDTLS_MD_NONE )
         {
             ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen,
@@ -3010,7 +2937,6 @@
                 return( ret );
         }
         else
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
@@ -3137,12 +3063,13 @@
     }
 
     ssl->state++;
-    ssl->client_auth = ( ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST );
+    ssl->handshake->client_auth =
+                    ( ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST );
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "got %s certificate request",
-                        ssl->client_auth ? "a" : "no" ) );
+                        ssl->handshake->client_auth ? "a" : "no" ) );
 
-    if( ssl->client_auth == 0 )
+    if( ssl->handshake->client_auth == 0 )
     {
         /* Current message is probably the ServerHelloDone */
         ssl->keep_current_message = 1;
@@ -3205,7 +3132,6 @@
     }
 
     /* supported_signature_algorithms */
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
     if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
     {
         size_t sig_alg_len =
@@ -3251,7 +3177,6 @@
 
         n += 2 + sig_alg_len;
     }
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
     /* certificate_authorities */
     dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] <<  8 )
@@ -3372,11 +3297,6 @@
 
         mbedtls_ssl_handshake_params *handshake = ssl->handshake;
 
-        unsigned char own_pubkey[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
-        size_t own_pubkey_len;
-        unsigned char *own_pubkey_ecpoint;
-        size_t own_pubkey_ecpoint_len;
-
         header_len = 4;
 
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "Perform PSA-based ECDH computation." ) );
@@ -3404,27 +3324,22 @@
         if( status != PSA_SUCCESS )
             return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
 
-        /* Export the public part of the ECDH private key from PSA
-         * and convert it to ECPoint format used in ClientKeyExchange. */
+        /* Export the public part of the ECDH private key from PSA.
+         * The export format is an ECPoint structure as expected by TLS,
+         * but we just need to add a length byte before that. */
+        unsigned char *own_pubkey = ssl->out_msg + header_len + 1;
+        unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+        size_t own_pubkey_max_len = (size_t)( end - own_pubkey );
+        size_t own_pubkey_len;
+
         status = psa_export_public_key( handshake->ecdh_psa_privkey,
-                                        own_pubkey, sizeof( own_pubkey ),
+                                        own_pubkey, own_pubkey_max_len,
                                         &own_pubkey_len );
         if( status != PSA_SUCCESS )
             return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
 
-        if( mbedtls_psa_tls_psa_ec_to_ecpoint( own_pubkey,
-                                               own_pubkey_len,
-                                               &own_pubkey_ecpoint,
-                                               &own_pubkey_ecpoint_len ) != 0 )
-        {
-            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
-        }
-
-        /* Copy ECPoint structure to outgoing message buffer. */
-        ssl->out_msg[header_len] = (unsigned char) own_pubkey_ecpoint_len;
-        memcpy( ssl->out_msg + header_len + 1,
-                own_pubkey_ecpoint, own_pubkey_ecpoint_len );
-        content_len = own_pubkey_ecpoint_len + 1;
+        ssl->out_msg[header_len] = (unsigned char) own_pubkey_len;
+        content_len = own_pubkey_len + 1;
 
         /* The ECDH secret is the premaster secret used for key derivation. */
 
@@ -3794,7 +3709,8 @@
         return( 0 );
     }
 
-    if( ssl->client_auth == 0 || mbedtls_ssl_own_cert( ssl ) == NULL )
+    if( ssl->handshake->client_auth == 0 ||
+        mbedtls_ssl_own_cert( ssl ) == NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
         ssl->state++;
@@ -3819,7 +3735,6 @@
 
     ssl->handshake->calc_verify( ssl, hash, &hashlen );
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
     if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
     {
         /*
@@ -3855,7 +3770,6 @@
         offset = 2;
     }
     else
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
@@ -4139,4 +4053,5 @@
 
     return( ret );
 }
-#endif /* MBEDTLS_SSL_CLI_C */
+
+#endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_PROTO_TLS1_2 */
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 6af9964..0656439 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -79,7 +79,9 @@
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 #define MBEDTLS_SSL_MIN_MINOR_VERSION           MBEDTLS_SSL_MINOR_VERSION_3
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+#elif defined(MBEDTLS_SSL_PROTO_TLS1_3)
+#define MBEDTLS_SSL_MIN_MINOR_VERSION           MBEDTLS_SSL_MINOR_VERSION_4
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
 
 #define MBEDTLS_SSL_MIN_VALID_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_3
 #define MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION MBEDTLS_SSL_MAJOR_VERSION_3
@@ -87,7 +89,9 @@
 /* Determine maximum supported version */
 #define MBEDTLS_SSL_MAX_MAJOR_VERSION           MBEDTLS_SSL_MAJOR_VERSION_3
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+#define MBEDTLS_SSL_MAX_MINOR_VERSION           MBEDTLS_SSL_MINOR_VERSION_4
+#elif defined(MBEDTLS_SSL_PROTO_TLS1_2)
 #define MBEDTLS_SSL_MAX_MINOR_VERSION           MBEDTLS_SSL_MINOR_VERSION_3
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
@@ -267,6 +271,8 @@
 /* Maximum size in bytes of list in supported elliptic curve ext., RFC 4492 */
 #define MBEDTLS_SSL_MAX_CURVE_LIST_LEN         65535
 
+#define MBEDTLS_RECEIVED_SIG_ALGS_SIZE         20
+
 /*
  * Check that we obey the standard's message size bounds
  */
@@ -601,6 +607,11 @@
     mbedtls_ssl_sig_hash_set_t hash_algs;             /*!<  Set of suitable sig-hash pairs */
 #endif
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
+    defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+    uint16_t received_sig_algs[MBEDTLS_RECEIVED_SIG_ALGS_SIZE];
+#endif
+
 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
     const uint16_t *group_list;
     const uint16_t *sig_algs;
@@ -741,7 +752,6 @@
     /*
      * Checksum contexts
      */
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 #if defined(MBEDTLS_SHA256_C)
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_hash_operation_t fin_sha256_psa;
@@ -756,7 +766,6 @@
     mbedtls_sha512_context fin_sha512;
 #endif
 #endif
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
     uint16_t offered_group_id; /* The NamedGroup value for the group
@@ -768,6 +777,12 @@
                                 * but can be overwritten by the HRR. */
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
 
+#if defined(MBEDTLS_SSL_CLI_C)
+    uint8_t client_auth;       /*!< used to check if CertificateRequest has been
+                                    received from server side. If CertificateRequest
+                                    has been received, Certificate and CertificateVerify
+                                    should be sent to server */
+#endif /* MBEDTLS_SSL_CLI_C */
     /*
      * State-local variables used during the processing
      * of a specific handshake state.
@@ -811,6 +826,11 @@
                                              represents an extension and defined
                                              as \c MBEDTLS_SSL_EXT_XXX */
 
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+    unsigned char certificate_request_context_len;
+    unsigned char *certificate_request_context;
+#endif
+
     union
     {
         unsigned char early    [MBEDTLS_TLS1_3_MD_MAX_SIZE];
@@ -1120,7 +1140,10 @@
 int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl );
 
 void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl );
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl );
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2  */
 
 int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl );
 int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl );
@@ -1296,6 +1319,7 @@
 unsigned char mbedtls_ssl_hash_from_md_alg( int md );
 int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md );
 
+int mbedtls_ssl_check_curve_tls_id( const mbedtls_ssl_context *ssl, uint16_t tls_id );
 #if defined(MBEDTLS_ECP_C)
 int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id );
 #endif
@@ -1751,6 +1775,12 @@
 int mbedtls_ssl_write_sig_alg_ext( mbedtls_ssl_context *ssl, unsigned char *buf,
                                    const unsigned char *end, size_t *out_len );
 
+/*
+ * Parse TLS 1.3 Signature Algorithm extension
+ */
+int mbedtls_ssl_tls13_parse_sig_alg_ext( mbedtls_ssl_context *ssl,
+                                         const unsigned char *buf,
+                                         const unsigned char *end );
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
 /* Get handshake transcript */
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 522e59e..e9febfd 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -19,7 +19,7 @@
 
 #include "common.h"
 
-#if defined(MBEDTLS_SSL_SRV_C)
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_TLS1_2)
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
@@ -224,8 +224,7 @@
     return( 0 );
 }
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
-    defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
 
 /*
  * Status of the implementation of signature-algorithms extension:
@@ -313,8 +312,7 @@
 
     return( 0 );
 }
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
-          MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -1054,8 +1052,7 @@
 {
     const mbedtls_ssl_ciphersuite_t *suite_info;
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
-    defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
     mbedtls_pk_type_t sig_type;
 #endif
 
@@ -1115,8 +1112,7 @@
     }
 #endif
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
-    defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
     /* If the ciphersuite requires signing, check whether
      * a suitable hash algorithm is present. */
     if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
@@ -1131,8 +1127,7 @@
         }
     }
 
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
-          MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
     /*
@@ -1178,11 +1173,9 @@
     /* If there is no signature-algorithm extension present,
      * we need to fall back to the default values for allowed
      * signature-hash pairs. */
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
-    defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
     int sig_hash_alg_ext_present = 0;
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
-          MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) );
 
@@ -1670,8 +1663,7 @@
                     return( ret );
                 break;
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
-    defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
             case MBEDTLS_TLS_EXT_SIG_ALG:
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
 
@@ -1681,8 +1673,7 @@
 
                 sig_hash_alg_ext_present = 1;
                 break;
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
-          MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -1794,8 +1785,7 @@
             ext += 4 + ext_size;
         }
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
-    defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
 
     /*
      * Try to fall back to default hash SHA1 if the client
@@ -1815,8 +1805,7 @@
                                              md_default );
     }
 
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
-          MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
     /*
      * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
@@ -1956,7 +1945,6 @@
 
     /* Debugging-only output for testsuite */
 #if defined(MBEDTLS_DEBUG_C)                         && \
-    defined(MBEDTLS_SSL_PROTO_TLS1_2)                && \
     defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
     if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
     {
@@ -2794,7 +2782,7 @@
     p += ct_len;
 
     sa_len = 0;
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+
     /*
      * Add signature_algorithms for verify (TLS 1.2)
      *
@@ -2834,7 +2822,6 @@
         sa_len += 2;
         p += sa_len;
     }
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
     /*
      * DistinguishedName certificate_authorities<0..2^16-1>;
@@ -3167,7 +3154,6 @@
 
         mbedtls_md_type_t md_alg;
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
         mbedtls_pk_type_t sig_alg =
             mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
         if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
@@ -3189,14 +3175,12 @@
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
         }
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
         MBEDTLS_SSL_DEBUG_MSG( 3, ( "pick hash algorithm %u for signing", (unsigned) md_alg ) );
 
         /*
          * 2.2: Compute the hash to be signed
          */
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
         if( md_alg != MBEDTLS_MD_NONE )
         {
             ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen,
@@ -3207,7 +3191,6 @@
                 return( ret );
         }
         else
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
             return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
@@ -3218,7 +3201,6 @@
         /*
          * 2.3: Compute and add the signature
          */
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
         if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
         {
             /*
@@ -3242,7 +3224,6 @@
             ssl->out_msg[ssl->out_msglen++] =
                 mbedtls_ssl_sig_from_pk_alg( sig_alg );
         }
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
 #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
         if( ssl->conf->f_async_sign_start != NULL )
@@ -3522,7 +3503,6 @@
     /*
      * Prepare to decrypt the premaster using own private RSA key
      */
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
     if ( p + 2 > end ) {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
         return( MBEDTLS_ERR_SSL_DECODE_ERROR );
@@ -3533,7 +3513,6 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
         return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
-#endif
 
     if( p + len != end )
     {
@@ -4063,9 +4042,7 @@
     unsigned char hash[48];
     unsigned char *hash_start = hash;
     size_t hashlen;
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
     mbedtls_pk_type_t pk_alg;
-#endif
     mbedtls_md_type_t md_alg;
     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
         ssl->handshake->ciphersuite_info;
@@ -4133,7 +4110,6 @@
      *     opaque signature<0..2^16-1>;
      *  } DigitallySigned;
      */
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
     if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
     {
         if( i + 2 > ssl->in_hslen )
@@ -4187,7 +4163,6 @@
         i++;
     }
     else
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
@@ -4406,4 +4381,4 @@
     conf->respect_cli_pref = order;
 }
 
-#endif /* MBEDTLS_SSL_SRV_C */
+#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_PROTO_TLS1_2 */
diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c
index e998111..b04e184 100644
--- a/library/ssl_ticket.c
+++ b/library/ssl_ticket.c
@@ -48,9 +48,9 @@
 #endif
 }
 
-#define MAX_KEY_BYTES 32    /* 256 bits */
+#define MAX_KEY_BYTES           MBEDTLS_SSL_TICKET_MAX_KEY_BYTES
 
-#define TICKET_KEY_NAME_BYTES    4
+#define TICKET_KEY_NAME_BYTES   MBEDTLS_SSL_TICKET_KEY_NAME_BYTES
 #define TICKET_IV_BYTES         12
 #define TICKET_CRYPT_LEN_BYTES   2
 #define TICKET_AUTH_TAG_BYTES   16
@@ -122,6 +122,35 @@
 }
 
 /*
+ * Rotate active session ticket encryption key
+ */
+int mbedtls_ssl_ticket_rotate( mbedtls_ssl_ticket_context *ctx,
+    const unsigned char *name, size_t nlength,
+    const unsigned char *k, size_t klength,
+    uint32_t lifetime )
+{
+    const unsigned char idx = 1 - ctx->active;
+    mbedtls_ssl_ticket_key * const key = ctx->keys + idx;
+    const int bitlen = mbedtls_cipher_get_key_bitlen( &key->ctx );
+    int ret;
+    if( nlength < TICKET_KEY_NAME_BYTES || klength * 8 < (size_t)bitlen )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    /* With GCM and CCM, same context can encrypt & decrypt */
+    ret = mbedtls_cipher_setkey( &key->ctx, k, bitlen, MBEDTLS_ENCRYPT );
+    if( ret != 0 )
+        return( ret );
+
+    ctx->active = idx;
+    ctx->ticket_lifetime = lifetime;
+    memcpy( key->name, name, TICKET_KEY_NAME_BYTES );
+#if defined(MBEDTLS_HAVE_TIME)
+    key->generation_time = (uint32_t) mbedtls_time( NULL );
+#endif
+    return 0;
+}
+
+/*
  * Setup context for actual use
  */
 int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx,
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 099bd55..e80adb1 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -334,306 +334,73 @@
 #endif /* MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH */
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
 
-static psa_status_t setup_psa_key_derivation( psa_key_derivation_operation_t* derivation,
-                                              mbedtls_svc_key_id_t key,
-                                              psa_algorithm_t alg,
-                                              const unsigned char* seed, size_t seed_length,
-                                              const unsigned char* label, size_t label_length,
-                                              size_t capacity )
-{
-    psa_status_t status;
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+typedef int (*tls_prf_fn)( const unsigned char *secret, size_t slen,
+                           const char *label,
+                           const unsigned char *random, size_t rlen,
+                           unsigned char *dstbuf, size_t dlen );
 
-    status = psa_key_derivation_setup( derivation, alg );
-    if( status != PSA_SUCCESS )
-        return( status );
+static tls_prf_fn ssl_tls12prf_from_cs( int ciphersuite_id );
 
-    if( PSA_ALG_IS_TLS12_PRF( alg ) || PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
-    {
-        status = psa_key_derivation_input_bytes( derivation,
-                                                 PSA_KEY_DERIVATION_INPUT_SEED,
-                                                 seed, seed_length );
-        if( status != PSA_SUCCESS )
-            return( status );
+#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
 
-        if( mbedtls_svc_key_id_is_null( key ) )
-        {
-            status = psa_key_derivation_input_bytes(
-                derivation, PSA_KEY_DERIVATION_INPUT_SECRET,
-                NULL, 0 );
-        }
-        else
-        {
-            status = psa_key_derivation_input_key(
-                derivation, PSA_KEY_DERIVATION_INPUT_SECRET, key );
-        }
-        if( status != PSA_SUCCESS )
-            return( status );
+/* Type for the TLS PRF */
+typedef int ssl_tls_prf_t(const unsigned char *, size_t, const char *,
+                          const unsigned char *, size_t,
+                          unsigned char *, size_t);
 
-        status = psa_key_derivation_input_bytes( derivation,
-                                                 PSA_KEY_DERIVATION_INPUT_LABEL,
-                                                 label, label_length );
-        if( status != PSA_SUCCESS )
-            return( status );
-    }
-    else
-    {
-        return( PSA_ERROR_NOT_SUPPORTED );
-    }
+static int ssl_tls12_populate_transform( mbedtls_ssl_transform *transform,
+                                   int ciphersuite,
+                                   const unsigned char master[48],
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) && \
+    defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+                                   int encrypt_then_mac,
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC &&
+          MBEDTLS_SSL_SOME_SUITES_USE_MAC */
+                                   ssl_tls_prf_t tls_prf,
+                                   const unsigned char randbytes[64],
+                                   int minor_ver,
+                                   unsigned endpoint,
+                                   const mbedtls_ssl_context *ssl );
 
-    status = psa_key_derivation_set_capacity( derivation, capacity );
-    if( status != PSA_SUCCESS )
-        return( status );
-
-    return( PSA_SUCCESS );
-}
-
-static int tls_prf_generic( mbedtls_md_type_t md_type,
-                            const unsigned char *secret, size_t slen,
-                            const char *label,
-                            const unsigned char *random, size_t rlen,
-                            unsigned char *dstbuf, size_t dlen )
-{
-    psa_status_t status;
-    psa_algorithm_t alg;
-    mbedtls_svc_key_id_t master_key = MBEDTLS_SVC_KEY_ID_INIT;
-    psa_key_derivation_operation_t derivation =
-        PSA_KEY_DERIVATION_OPERATION_INIT;
-
-    if( md_type == MBEDTLS_MD_SHA384 )
-        alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384);
-    else
-        alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256);
-
-    /* Normally a "secret" should be long enough to be impossible to
-     * find by brute force, and in particular should not be empty. But
-     * this PRF is also used to derive an IV, in particular in EAP-TLS,
-     * and for this use case it makes sense to have a 0-length "secret".
-     * Since the key API doesn't allow importing a key of length 0,
-     * keep master_key=0, which setup_psa_key_derivation() understands
-     * to mean a 0-length "secret" input. */
-    if( slen != 0 )
-    {
-        psa_key_attributes_t key_attributes = psa_key_attributes_init();
-        psa_set_key_usage_flags( &key_attributes, PSA_KEY_USAGE_DERIVE );
-        psa_set_key_algorithm( &key_attributes, alg );
-        psa_set_key_type( &key_attributes, PSA_KEY_TYPE_DERIVE );
-
-        status = psa_import_key( &key_attributes, secret, slen, &master_key );
-        if( status != PSA_SUCCESS )
-            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
-    }
-
-    status = setup_psa_key_derivation( &derivation,
-                                       master_key, alg,
-                                       random, rlen,
-                                       (unsigned char const *) label,
-                                       (size_t) strlen( label ),
-                                       dlen );
-    if( status != PSA_SUCCESS )
-    {
-        psa_key_derivation_abort( &derivation );
-        psa_destroy_key( master_key );
-        return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
-    }
-
-    status = psa_key_derivation_output_bytes( &derivation, dstbuf, dlen );
-    if( status != PSA_SUCCESS )
-    {
-        psa_key_derivation_abort( &derivation );
-        psa_destroy_key( master_key );
-        return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
-    }
-
-    status = psa_key_derivation_abort( &derivation );
-    if( status != PSA_SUCCESS )
-    {
-        psa_destroy_key( master_key );
-        return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
-    }
-
-    if( ! mbedtls_svc_key_id_is_null( master_key ) )
-        status = psa_destroy_key( master_key );
-    if( status != PSA_SUCCESS )
-        return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
-
-    return( 0 );
-}
-
-#else /* MBEDTLS_USE_PSA_CRYPTO */
-
-static int tls_prf_generic( mbedtls_md_type_t md_type,
-                            const unsigned char *secret, size_t slen,
-                            const char *label,
-                            const unsigned char *random, size_t rlen,
-                            unsigned char *dstbuf, size_t dlen )
-{
-    size_t nb;
-    size_t i, j, k, md_len;
-    unsigned char *tmp;
-    size_t tmp_len = 0;
-    unsigned char h_i[MBEDTLS_MD_MAX_SIZE];
-    const mbedtls_md_info_t *md_info;
-    mbedtls_md_context_t md_ctx;
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-
-    mbedtls_md_init( &md_ctx );
-
-    if( ( md_info = mbedtls_md_info_from_type( md_type ) ) == NULL )
-        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-
-    md_len = mbedtls_md_get_size( md_info );
-
-    tmp_len = md_len + strlen( label ) + rlen;
-    tmp = mbedtls_calloc( 1, tmp_len );
-    if( tmp == NULL )
-    {
-        ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
-        goto exit;
-    }
-
-    nb = strlen( label );
-    memcpy( tmp + md_len, label, nb );
-    memcpy( tmp + md_len + nb, random, rlen );
-    nb += rlen;
-
-    /*
-     * Compute P_<hash>(secret, label + random)[0..dlen]
-     */
-    if ( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
-        goto exit;
-
-    ret = mbedtls_md_hmac_starts( &md_ctx, secret, slen );
-    if( ret != 0 )
-        goto exit;
-    ret = mbedtls_md_hmac_update( &md_ctx, tmp + md_len, nb );
-    if( ret != 0 )
-        goto exit;
-    ret = mbedtls_md_hmac_finish( &md_ctx, tmp );
-    if( ret != 0 )
-        goto exit;
-
-    for( i = 0; i < dlen; i += md_len )
-    {
-        ret = mbedtls_md_hmac_reset ( &md_ctx );
-        if( ret != 0 )
-            goto exit;
-        ret = mbedtls_md_hmac_update( &md_ctx, tmp, md_len + nb );
-        if( ret != 0 )
-            goto exit;
-        ret = mbedtls_md_hmac_finish( &md_ctx, h_i );
-        if( ret != 0 )
-            goto exit;
-
-        ret = mbedtls_md_hmac_reset ( &md_ctx );
-        if( ret != 0 )
-            goto exit;
-        ret = mbedtls_md_hmac_update( &md_ctx, tmp, md_len );
-        if( ret != 0 )
-            goto exit;
-        ret = mbedtls_md_hmac_finish( &md_ctx, tmp );
-        if( ret != 0 )
-            goto exit;
-
-        k = ( i + md_len > dlen ) ? dlen % md_len : md_len;
-
-        for( j = 0; j < k; j++ )
-            dstbuf[i + j]  = h_i[j];
-    }
-
-exit:
-    mbedtls_md_free( &md_ctx );
-
-    mbedtls_platform_zeroize( tmp, tmp_len );
-    mbedtls_platform_zeroize( h_i, sizeof( h_i ) );
-
-    mbedtls_free( tmp );
-
-    return( ret );
-}
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
 #if defined(MBEDTLS_SHA256_C)
 static int tls_prf_sha256( const unsigned char *secret, size_t slen,
                            const char *label,
                            const unsigned char *random, size_t rlen,
-                           unsigned char *dstbuf, size_t dlen )
-{
-    return( tls_prf_generic( MBEDTLS_MD_SHA256, secret, slen,
-                             label, random, rlen, dstbuf, dlen ) );
-}
+                           unsigned char *dstbuf, size_t dlen );
+static void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *,unsigned char*, size_t * );
+static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *,unsigned char *, int );
+
 #endif /* MBEDTLS_SHA256_C */
 
 #if defined(MBEDTLS_SHA384_C)
 static int tls_prf_sha384( const unsigned char *secret, size_t slen,
                            const char *label,
                            const unsigned char *random, size_t rlen,
-                           unsigned char *dstbuf, size_t dlen )
-{
-    return( tls_prf_generic( MBEDTLS_MD_SHA384, secret, slen,
-                             label, random, rlen, dstbuf, dlen ) );
-}
+                           unsigned char *dstbuf, size_t dlen );
+
+static void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *, unsigned char*, size_t * );
+static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char *, int );
 #endif /* MBEDTLS_SHA384_C */
+
+static size_t ssl_session_save_tls12( const mbedtls_ssl_session *session,
+                                      unsigned char *buf,
+                                      size_t buf_len );
+static int ssl_session_load_tls12( mbedtls_ssl_session *session,
+                                   const unsigned char *buf,
+                                   size_t len );
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
 static void ssl_update_checksum_start( mbedtls_ssl_context *, const unsigned char *, size_t );
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 #if defined(MBEDTLS_SHA256_C)
 static void ssl_update_checksum_sha256( mbedtls_ssl_context *, const unsigned char *, size_t );
-static void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *,unsigned char*, size_t * );
-static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *,unsigned char *, int );
-#endif
+#endif /* MBEDTLS_SHA256_C */
 
 #if defined(MBEDTLS_SHA384_C)
 static void ssl_update_checksum_sha384( mbedtls_ssl_context *, const unsigned char *, size_t );
-static void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *, unsigned char*, size_t * );
-static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char *, int );
-#endif
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-
-#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) && \
-    defined(MBEDTLS_USE_PSA_CRYPTO)
-static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl )
-{
-    if( ssl->conf->f_psk != NULL )
-    {
-        /* If we've used a callback to select the PSK,
-         * the static configuration is irrelevant. */
-        if( ! mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) )
-            return( 1 );
-
-        return( 0 );
-    }
-
-    if( ! mbedtls_svc_key_id_is_null( ssl->conf->psk_opaque ) )
-        return( 1 );
-
-    return( 0 );
-}
-#endif /* MBEDTLS_USE_PSA_CRYPTO &&
-          MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
-
-static mbedtls_tls_prf_types tls_prf_get_type( mbedtls_ssl_tls_prf_cb *tls_prf )
-{
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#if defined(MBEDTLS_SHA384_C)
-    if( tls_prf == tls_prf_sha384 )
-    {
-        return( MBEDTLS_SSL_TLS_PRF_SHA384 );
-    }
-    else
-#endif
-#if defined(MBEDTLS_SHA256_C)
-    if( tls_prf == tls_prf_sha256 )
-    {
-        return( MBEDTLS_SSL_TLS_PRF_SHA256 );
-    }
-    else
-#endif
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-    return( MBEDTLS_SSL_TLS_PRF_NONE );
-}
+#endif /* MBEDTLS_SHA384_C */
 
 int  mbedtls_ssl_tls_prf( const mbedtls_tls_prf_types prf,
                           const unsigned char *secret, size_t slen,
@@ -664,961 +431,6 @@
     return( tls_prf( secret, slen, label, random, rlen, dstbuf, dlen ) );
 }
 
-/* Type for the TLS PRF */
-typedef int ssl_tls_prf_t(const unsigned char *, size_t, const char *,
-                          const unsigned char *, size_t,
-                          unsigned char *, size_t);
-
-/*
- * Populate a transform structure with session keys and all the other
- * necessary information.
- *
- * Parameters:
- * - [in/out]: transform: structure to populate
- *      [in] must be just initialised with mbedtls_ssl_transform_init()
- *      [out] fully populated, ready for use by mbedtls_ssl_{en,de}crypt_buf()
- * - [in] ciphersuite
- * - [in] master
- * - [in] encrypt_then_mac
- * - [in] compression
- * - [in] tls_prf: pointer to PRF to use for key derivation
- * - [in] randbytes: buffer holding ServerHello.random + ClientHello.random
- * - [in] minor_ver: SSL/TLS minor version
- * - [in] endpoint: client or server
- * - [in] ssl: used for:
- *        - ssl->conf->{f,p}_export_keys
- *      [in] optionally used for:
- *        - MBEDTLS_DEBUG_C: ssl->conf->{f,p}_dbg
- */
-static int ssl_tls12_populate_transform( mbedtls_ssl_transform *transform,
-                                   int ciphersuite,
-                                   const unsigned char master[48],
-#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) && \
-    defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
-                                   int encrypt_then_mac,
-#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC &&
-          MBEDTLS_SSL_SOME_SUITES_USE_MAC */
-                                   ssl_tls_prf_t tls_prf,
-                                   const unsigned char randbytes[64],
-                                   int minor_ver,
-                                   unsigned endpoint,
-                                   const mbedtls_ssl_context *ssl )
-{
-    int ret = 0;
-    unsigned char keyblk[256];
-    unsigned char *key1;
-    unsigned char *key2;
-    unsigned char *mac_enc;
-    unsigned char *mac_dec;
-    size_t mac_key_len = 0;
-    size_t iv_copy_len;
-    size_t keylen;
-    const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
-    const mbedtls_cipher_info_t *cipher_info;
-    const mbedtls_md_info_t *md_info;
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-    psa_key_type_t key_type;
-    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    psa_algorithm_t alg;
-    size_t key_bits;
-    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
-#endif
-
-#if !defined(MBEDTLS_DEBUG_C) && \
-    !defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
-    if( ssl->f_export_keys == NULL )
-    {
-        ssl = NULL; /* make sure we don't use it except for these cases */
-        (void) ssl;
-    }
-#endif
-
-    /*
-     * Some data just needs copying into the structure
-     */
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \
-    defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
-    transform->encrypt_then_mac = encrypt_then_mac;
-#endif
-    transform->minor_ver = minor_ver;
-
-#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
-    memcpy( transform->randbytes, randbytes, sizeof( transform->randbytes ) );
-#endif
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
-    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 )
-    {
-        /* At the moment, we keep TLS <= 1.2 and TLS 1.3 transform
-         * generation separate. This should never happen. */
-        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-    }
-#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
-
-    /*
-     * Get various info structures
-     */
-    ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuite );
-    if( ciphersuite_info == NULL )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %d not found",
-                                    ciphersuite ) );
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-    }
-
-    cipher_info = mbedtls_cipher_info_from_type( ciphersuite_info->cipher );
-    if( cipher_info == NULL )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher info for %u not found",
-                                    ciphersuite_info->cipher ) );
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-    }
-
-    md_info = mbedtls_md_info_from_type( ciphersuite_info->mac );
-    if( md_info == NULL )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_md info for %u not found",
-                            (unsigned) ciphersuite_info->mac ) );
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-    }
-
-#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
-    /* Copy own and peer's CID if the use of the CID
-     * extension has been negotiated. */
-    if( ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_ENABLED )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 3, ( "Copy CIDs into SSL transform" ) );
-
-        transform->in_cid_len = ssl->own_cid_len;
-        memcpy( transform->in_cid, ssl->own_cid, ssl->own_cid_len );
-        MBEDTLS_SSL_DEBUG_BUF( 3, "Incoming CID", transform->in_cid,
-                               transform->in_cid_len );
-
-        transform->out_cid_len = ssl->handshake->peer_cid_len;
-        memcpy( transform->out_cid, ssl->handshake->peer_cid,
-                ssl->handshake->peer_cid_len );
-        MBEDTLS_SSL_DEBUG_BUF( 3, "Outgoing CID", transform->out_cid,
-                               transform->out_cid_len );
-    }
-#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
-
-    /*
-     * Compute key block using the PRF
-     */
-    ret = tls_prf( master, 48, "key expansion", randbytes, 64, keyblk, 256 );
-    if( ret != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
-        return( ret );
-    }
-
-    MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite = %s",
-                           mbedtls_ssl_get_ciphersuite_name( ciphersuite ) ) );
-    MBEDTLS_SSL_DEBUG_BUF( 3, "master secret", master, 48 );
-    MBEDTLS_SSL_DEBUG_BUF( 4, "random bytes", randbytes, 64 );
-    MBEDTLS_SSL_DEBUG_BUF( 4, "key block", keyblk, 256 );
-
-    /*
-     * Determine the appropriate key, IV and MAC length.
-     */
-
-    keylen = mbedtls_cipher_info_get_key_bitlen( cipher_info ) / 8;
-
-#if defined(MBEDTLS_GCM_C) ||                           \
-    defined(MBEDTLS_CCM_C) ||                           \
-    defined(MBEDTLS_CHACHAPOLY_C)
-    if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_GCM ||
-        mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CCM ||
-        mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CHACHAPOLY )
-    {
-        size_t explicit_ivlen;
-
-        transform->maclen = 0;
-        mac_key_len = 0;
-        transform->taglen =
-            ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
-
-        /* All modes haves 96-bit IVs, but the length of the static parts vary
-         * with mode and version:
-         * - For GCM and CCM in TLS 1.2, there's a static IV of 4 Bytes
-         *   (to be concatenated with a dynamically chosen IV of 8 Bytes)
-         * - For ChaChaPoly in TLS 1.2, and all modes in TLS 1.3, there's
-         *   a static IV of 12 Bytes (to be XOR'ed with the 8 Byte record
-         *   sequence number).
-         */
-        transform->ivlen = 12;
-        if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CHACHAPOLY )
-            transform->fixed_ivlen = 12;
-        else
-            transform->fixed_ivlen = 4;
-
-        /* Minimum length of encrypted record */
-        explicit_ivlen = transform->ivlen - transform->fixed_ivlen;
-        transform->minlen = explicit_ivlen + transform->taglen;
-    }
-    else
-#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */
-#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
-    if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_STREAM ||
-        mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CBC )
-    {
-        /* Initialize HMAC contexts */
-        if( ( ret = mbedtls_md_setup( &transform->md_ctx_enc, md_info, 1 ) ) != 0 ||
-            ( ret = mbedtls_md_setup( &transform->md_ctx_dec, md_info, 1 ) ) != 0 )
-        {
-            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
-            goto end;
-        }
-
-        /* Get MAC length */
-        mac_key_len = mbedtls_md_get_size( md_info );
-        transform->maclen = mac_key_len;
-
-        /* IV length */
-        transform->ivlen = cipher_info->iv_size;
-
-        /* Minimum length */
-        if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_STREAM )
-            transform->minlen = transform->maclen;
-        else
-        {
-            /*
-             * GenericBlockCipher:
-             * 1. if EtM is in use: one block plus MAC
-             *    otherwise: * first multiple of blocklen greater than maclen
-             * 2. IV
-             */
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
-            if( encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
-            {
-                transform->minlen = transform->maclen
-                                  + cipher_info->block_size;
-            }
-            else
-#endif
-            {
-                transform->minlen = transform->maclen
-                                  + cipher_info->block_size
-                                  - transform->maclen % cipher_info->block_size;
-            }
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-            if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
-            {
-                transform->minlen += transform->ivlen;
-            }
-            else
-#endif
-            {
-                MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
-                ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
-                goto end;
-            }
-        }
-    }
-    else
-#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
-        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-    }
-
-    MBEDTLS_SSL_DEBUG_MSG( 3, ( "keylen: %u, minlen: %u, ivlen: %u, maclen: %u",
-                                (unsigned) keylen,
-                                (unsigned) transform->minlen,
-                                (unsigned) transform->ivlen,
-                                (unsigned) transform->maclen ) );
-
-    /*
-     * Finally setup the cipher contexts, IVs and MAC secrets.
-     */
-#if defined(MBEDTLS_SSL_CLI_C)
-    if( endpoint == MBEDTLS_SSL_IS_CLIENT )
-    {
-        key1 = keyblk + mac_key_len * 2;
-        key2 = keyblk + mac_key_len * 2 + keylen;
-
-        mac_enc = keyblk;
-        mac_dec = keyblk + mac_key_len;
-
-        /*
-         * This is not used in TLS v1.1.
-         */
-        iv_copy_len = ( transform->fixed_ivlen ) ?
-                            transform->fixed_ivlen : transform->ivlen;
-        memcpy( transform->iv_enc, key2 + keylen,  iv_copy_len );
-        memcpy( transform->iv_dec, key2 + keylen + iv_copy_len,
-                iv_copy_len );
-    }
-    else
-#endif /* MBEDTLS_SSL_CLI_C */
-#if defined(MBEDTLS_SSL_SRV_C)
-    if( endpoint == MBEDTLS_SSL_IS_SERVER )
-    {
-        key1 = keyblk + mac_key_len * 2 + keylen;
-        key2 = keyblk + mac_key_len * 2;
-
-        mac_enc = keyblk + mac_key_len;
-        mac_dec = keyblk;
-
-        /*
-         * This is not used in TLS v1.1.
-         */
-        iv_copy_len = ( transform->fixed_ivlen ) ?
-                            transform->fixed_ivlen : transform->ivlen;
-        memcpy( transform->iv_dec, key1 + keylen,  iv_copy_len );
-        memcpy( transform->iv_enc, key1 + keylen + iv_copy_len,
-                iv_copy_len );
-    }
-    else
-#endif /* MBEDTLS_SSL_SRV_C */
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
-        ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
-        goto end;
-    }
-
-#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-    /* For HMAC-based ciphersuites, initialize the HMAC transforms.
-       For AEAD-based ciphersuites, there is nothing to do here. */
-    if( mac_key_len != 0 )
-    {
-        ret = mbedtls_md_hmac_starts( &transform->md_ctx_enc, mac_enc, mac_key_len );
-        if( ret != 0 )
-            goto end;
-        ret = mbedtls_md_hmac_starts( &transform->md_ctx_dec, mac_dec, mac_key_len );
-        if( ret != 0 )
-            goto end;
-    }
-#endif
-#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
-
-    ((void) mac_dec);
-    ((void) mac_enc);
-
-    if( ssl != NULL && ssl->f_export_keys != NULL )
-    {
-        ssl->f_export_keys( ssl->p_export_keys,
-                            MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET,
-                            master, 48,
-                            randbytes + 32,
-                            randbytes,
-                            tls_prf_get_type( tls_prf ) );
-    }
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-    if( ( status = mbedtls_ssl_cipher_to_psa( cipher_info->type,
-                                 transform->taglen,
-                                 &alg,
-                                 &key_type,
-                                 &key_bits ) ) != PSA_SUCCESS )
-    {
-        ret = psa_ssl_status_to_mbedtls( status );
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_cipher_to_psa", ret );
-        goto end;
-    }
-
-    transform->psa_alg = alg;
-
-    if ( alg != MBEDTLS_SSL_NULL_CIPHER )
-    {
-        psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
-        psa_set_key_algorithm( &attributes, alg );
-        psa_set_key_type( &attributes, key_type );
-
-        if( ( status = psa_import_key( &attributes,
-                                key1,
-                                PSA_BITS_TO_BYTES( key_bits ),
-                                &transform->psa_key_enc ) ) != PSA_SUCCESS )
-        {
-            MBEDTLS_SSL_DEBUG_RET( 3, "psa_import_key", (int)status );
-            ret = psa_ssl_status_to_mbedtls( status );
-            MBEDTLS_SSL_DEBUG_RET( 1, "psa_import_key", ret );
-            goto end;
-        }
-
-        psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
-
-        if( ( status = psa_import_key( &attributes,
-                                key2,
-                                PSA_BITS_TO_BYTES( key_bits ),
-                                &transform->psa_key_dec ) ) != PSA_SUCCESS )
-        {
-            ret = psa_ssl_status_to_mbedtls( status );
-            MBEDTLS_SSL_DEBUG_RET( 1, "psa_import_key", ret );
-            goto end;
-        }
-    }
-#else
-    if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc,
-                                 cipher_info ) ) != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
-        goto end;
-    }
-
-    if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_dec,
-                                 cipher_info ) ) != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
-        goto end;
-    }
-
-    if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_enc, key1,
-                               (int) mbedtls_cipher_info_get_key_bitlen( cipher_info ),
-                               MBEDTLS_ENCRYPT ) ) != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
-        goto end;
-    }
-
-    if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_dec, key2,
-                               (int) mbedtls_cipher_info_get_key_bitlen( cipher_info ),
-                               MBEDTLS_DECRYPT ) ) != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
-        goto end;
-    }
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-    if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CBC )
-    {
-        if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_enc,
-                                             MBEDTLS_PADDING_NONE ) ) != 0 )
-        {
-            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret );
-            goto end;
-        }
-
-        if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_dec,
-                                             MBEDTLS_PADDING_NONE ) ) != 0 )
-        {
-            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret );
-            goto end;
-        }
-    }
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
-end:
-    mbedtls_platform_zeroize( keyblk, sizeof( keyblk ) );
-    return( ret );
-}
-
-/*
- * Set appropriate PRF function and other SSL / TLS1.2 functions
- *
- * Inputs:
- * - SSL/TLS minor version
- * - hash associated with the ciphersuite (only used by TLS 1.2)
- *
- * Outputs:
- * - the tls_prf, calc_verify and calc_finished members of handshake structure
- */
-static int ssl_set_handshake_prfs( mbedtls_ssl_handshake_params *handshake,
-                                   int minor_ver,
-                                   mbedtls_md_type_t hash )
-{
-#if !defined(MBEDTLS_SSL_PROTO_TLS1_2) || !defined(MBEDTLS_SHA384_C)
-    (void) hash;
-#endif
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#if defined(MBEDTLS_SHA384_C)
-    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
-        hash == MBEDTLS_MD_SHA384 )
-    {
-        handshake->tls_prf = tls_prf_sha384;
-        handshake->calc_verify = ssl_calc_verify_tls_sha384;
-        handshake->calc_finished = ssl_calc_finished_tls_sha384;
-    }
-    else
-#endif
-#if defined(MBEDTLS_SHA256_C)
-    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
-    {
-        handshake->tls_prf = tls_prf_sha256;
-        handshake->calc_verify = ssl_calc_verify_tls_sha256;
-        handshake->calc_finished = ssl_calc_finished_tls_sha256;
-    }
-    else
-#endif
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-    {
-        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-    }
-
-    return( 0 );
-}
-
-/*
- * Compute master secret if needed
- *
- * Parameters:
- * [in/out] handshake
- *          [in] resume, premaster, extended_ms, calc_verify, tls_prf
- *               (PSA-PSK) ciphersuite_info, psk_opaque
- *          [out] premaster (cleared)
- * [out] master
- * [in] ssl: optionally used for debugging, EMS and PSA-PSK
- *      debug: conf->f_dbg, conf->p_dbg
- *      EMS: passed to calc_verify (debug + session_negotiate)
- *      PSA-PSA: minor_ver, conf
- */
-static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake,
-                               unsigned char *master,
-                               const mbedtls_ssl_context *ssl )
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-
-    /* cf. RFC 5246, Section 8.1:
-     * "The master secret is always exactly 48 bytes in length." */
-    size_t const master_secret_len = 48;
-
-#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
-    unsigned char session_hash[48];
-#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
-
-    /* The label for the KDF used for key expansion.
-     * This is either "master secret" or "extended master secret"
-     * depending on whether the Extended Master Secret extension
-     * is used. */
-    char const *lbl = "master secret";
-
-    /* The salt for the KDF used for key expansion.
-     * - If the Extended Master Secret extension is not used,
-     *   this is ClientHello.Random + ServerHello.Random
-     *   (see Sect. 8.1 in RFC 5246).
-     * - If the Extended Master Secret extension is used,
-     *   this is the transcript of the handshake so far.
-     *   (see Sect. 4 in RFC 7627). */
-    unsigned char const *salt = handshake->randbytes;
-    size_t salt_len = 64;
-
-#if !defined(MBEDTLS_DEBUG_C) &&                    \
-    !defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \
-    !(defined(MBEDTLS_USE_PSA_CRYPTO) &&            \
-      defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED))
-    ssl = NULL; /* make sure we don't use it except for those cases */
-    (void) ssl;
-#endif
-
-    if( handshake->resume != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) );
-        return( 0 );
-    }
-
-#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
-    if( handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED )
-    {
-        lbl  = "extended master secret";
-        salt = session_hash;
-        handshake->calc_verify( ssl, session_hash, &salt_len );
-
-        MBEDTLS_SSL_DEBUG_BUF( 3, "session hash for extended master secret",
-                                  session_hash, salt_len );
-    }
-#endif /* MBEDTLS_SSL_EXTENDED_MS_ENABLED */
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO) &&          \
-    defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
-    if( handshake->ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK &&
-        ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
-        ssl_use_opaque_psk( ssl ) == 1 )
-    {
-        /* Perform PSK-to-MS expansion in a single step. */
-        psa_status_t status;
-        psa_algorithm_t alg;
-        mbedtls_svc_key_id_t psk;
-        psa_key_derivation_operation_t derivation =
-            PSA_KEY_DERIVATION_OPERATION_INIT;
-        mbedtls_md_type_t hash_alg = handshake->ciphersuite_info->mac;
-
-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "perform PSA-based PSK-to-MS expansion" ) );
-
-        psk = mbedtls_ssl_get_opaque_psk( ssl );
-
-        if( hash_alg == MBEDTLS_MD_SHA384 )
-            alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384);
-        else
-            alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256);
-
-        status = setup_psa_key_derivation( &derivation, psk, alg,
-                                           salt, salt_len,
-                                           (unsigned char const *) lbl,
-                                           (size_t) strlen( lbl ),
-                                           master_secret_len );
-        if( status != PSA_SUCCESS )
-        {
-            psa_key_derivation_abort( &derivation );
-            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
-        }
-
-        status = psa_key_derivation_output_bytes( &derivation,
-                                                  master,
-                                                  master_secret_len );
-        if( status != PSA_SUCCESS )
-        {
-            psa_key_derivation_abort( &derivation );
-            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
-        }
-
-        status = psa_key_derivation_abort( &derivation );
-        if( status != PSA_SUCCESS )
-            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
-    }
-    else
-#endif
-    {
-        ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
-                                  lbl, salt, salt_len,
-                                  master,
-                                  master_secret_len );
-        if( ret != 0 )
-        {
-            MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
-            return( ret );
-        }
-
-        MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret",
-                               handshake->premaster,
-                               handshake->pmslen );
-
-        mbedtls_platform_zeroize( handshake->premaster,
-                                  sizeof(handshake->premaster) );
-    }
-
-    return( 0 );
-}
-
-int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    const mbedtls_ssl_ciphersuite_t * const ciphersuite_info =
-        ssl->handshake->ciphersuite_info;
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) );
-
-    /* Set PRF, calc_verify and calc_finished function pointers */
-    ret = ssl_set_handshake_prfs( ssl->handshake,
-                                  ssl->minor_ver,
-                                  ciphersuite_info->mac );
-    if( ret != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_set_handshake_prfs", ret );
-        return( ret );
-    }
-
-    /* Compute master secret if needed */
-    ret = ssl_compute_master( ssl->handshake,
-                              ssl->session_negotiate->master,
-                              ssl );
-    if( ret != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compute_master", ret );
-        return( ret );
-    }
-
-    /* Swap the client and server random values:
-     * - MS derivation wanted client+server (RFC 5246 8.1)
-     * - key derivation wants server+client (RFC 5246 6.3) */
-    {
-        unsigned char tmp[64];
-        memcpy( tmp, ssl->handshake->randbytes, 64 );
-        memcpy( ssl->handshake->randbytes, tmp + 32, 32 );
-        memcpy( ssl->handshake->randbytes + 32, tmp, 32 );
-        mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
-    }
-
-    /* Populate transform structure */
-    ret = ssl_tls12_populate_transform( ssl->transform_negotiate,
-                                        ssl->session_negotiate->ciphersuite,
-                                        ssl->session_negotiate->master,
-#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) && \
-    defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
-                                        ssl->session_negotiate->encrypt_then_mac,
-#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC &&
-          MBEDTLS_SSL_SOME_SUITES_USE_MAC */
-                                        ssl->handshake->tls_prf,
-                                        ssl->handshake->randbytes,
-                                        ssl->minor_ver,
-                                        ssl->conf->endpoint,
-                                        ssl );
-    if( ret != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls12_populate_transform", ret );
-        return( ret );
-    }
-
-    /* We no longer need Server/ClientHello.random values */
-    mbedtls_platform_zeroize( ssl->handshake->randbytes,
-                      sizeof( ssl->handshake->randbytes ) );
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= derive keys" ) );
-
-    return( 0 );
-}
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#if defined(MBEDTLS_SHA256_C)
-void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *ssl,
-                                 unsigned char *hash,
-                                 size_t *hlen )
-{
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-    size_t hash_size;
-    psa_status_t status;
-    psa_hash_operation_t sha256_psa = psa_hash_operation_init();
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> PSA calc verify sha256" ) );
-    status = psa_hash_clone( &ssl->handshake->fin_sha256_psa, &sha256_psa );
-    if( status != PSA_SUCCESS )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
-        return;
-    }
-
-    status = psa_hash_finish( &sha256_psa, hash, 32, &hash_size );
-    if( status != PSA_SUCCESS )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
-        return;
-    }
-
-    *hlen = 32;
-    MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated verify result", hash, *hlen );
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= PSA calc verify" ) );
-#else
-    mbedtls_sha256_context sha256;
-
-    mbedtls_sha256_init( &sha256 );
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha256" ) );
-
-    mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
-    mbedtls_sha256_finish( &sha256, hash );
-
-    *hlen = 32;
-
-    MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen );
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
-
-    mbedtls_sha256_free( &sha256 );
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-    return;
-}
-#endif /* MBEDTLS_SHA256_C */
-
-#if defined(MBEDTLS_SHA384_C)
-void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *ssl,
-                                 unsigned char *hash,
-                                 size_t *hlen )
-{
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-    size_t hash_size;
-    psa_status_t status;
-    psa_hash_operation_t sha384_psa = psa_hash_operation_init();
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> PSA calc verify sha384" ) );
-    status = psa_hash_clone( &ssl->handshake->fin_sha384_psa, &sha384_psa );
-    if( status != PSA_SUCCESS )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
-        return;
-    }
-
-    status = psa_hash_finish( &sha384_psa, hash, 48, &hash_size );
-    if( status != PSA_SUCCESS )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
-        return;
-    }
-
-    *hlen = 48;
-    MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated verify result", hash, *hlen );
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= PSA calc verify" ) );
-#else
-    mbedtls_sha512_context sha512;
-
-    mbedtls_sha512_init( &sha512 );
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha384" ) );
-
-    mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
-    mbedtls_sha512_finish( &sha512, hash );
-
-    *hlen = 48;
-
-    MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen );
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
-
-    mbedtls_sha512_free( &sha512 );
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-    return;
-}
-#endif /* MBEDTLS_SHA384_C */
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-
-#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
-int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex )
-{
-    unsigned char *p = ssl->handshake->premaster;
-    unsigned char *end = p + sizeof( ssl->handshake->premaster );
-    const unsigned char *psk = NULL;
-    size_t psk_len = 0;
-
-    if( mbedtls_ssl_get_psk( ssl, &psk, &psk_len )
-            == MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED )
-    {
-        /*
-         * This should never happen because the existence of a PSK is always
-         * checked before calling this function
-         */
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
-        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-    }
-
-    /*
-     * PMS = struct {
-     *     opaque other_secret<0..2^16-1>;
-     *     opaque psk<0..2^16-1>;
-     * };
-     * with "other_secret" depending on the particular key exchange
-     */
-#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
-    if( key_ex == MBEDTLS_KEY_EXCHANGE_PSK )
-    {
-        if( end - p < 2 )
-            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-        MBEDTLS_PUT_UINT16_BE( psk_len, p, 0 );
-        p += 2;
-
-        if( end < p || (size_t)( end - p ) < psk_len )
-            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-        memset( p, 0, psk_len );
-        p += psk_len;
-    }
-    else
-#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
-    if( key_ex == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
-    {
-        /*
-         * other_secret already set by the ClientKeyExchange message,
-         * and is 48 bytes long
-         */
-        if( end - p < 2 )
-            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-        *p++ = 0;
-        *p++ = 48;
-        p += 48;
-    }
-    else
-#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
-    if( key_ex == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
-    {
-        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-        size_t len;
-
-        /* Write length only when we know the actual value */
-        if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
-                                      p + 2, end - ( p + 2 ), &len,
-                                      ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
-        {
-            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
-            return( ret );
-        }
-        MBEDTLS_PUT_UINT16_BE( len, p, 0 );
-        p += 2 + len;
-
-        MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K  );
-    }
-    else
-#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
-    if( key_ex == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
-    {
-        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-        size_t zlen;
-
-        if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &zlen,
-                                       p + 2, end - ( p + 2 ),
-                                       ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
-        {
-            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
-            return( ret );
-        }
-
-        MBEDTLS_PUT_UINT16_BE( zlen, p, 0 );
-        p += 2 + zlen;
-
-        MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
-                                MBEDTLS_DEBUG_ECDH_Z );
-    }
-    else
-#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
-        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-    }
-
-    /* opaque psk<0..2^16-1>; */
-    if( end - p < 2 )
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-    MBEDTLS_PUT_UINT16_BE( psk_len, p, 0 );
-    p += 2;
-
-    if( end < p || (size_t)( end - p ) < psk_len )
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-    memcpy( p, psk, psk_len );
-    p += psk_len;
-
-    ssl->handshake->pmslen = p - ssl->handshake->premaster;
-
-    return( 0 );
-}
-#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
-
-#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
-static int ssl_write_hello_request( mbedtls_ssl_context *ssl );
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-int mbedtls_ssl_resend_hello_request( mbedtls_ssl_context *ssl )
-{
-    /* If renegotiation is not enforced, retransmit until we would reach max
-     * timeout if we were using the usual handshake doubling scheme */
-    if( ssl->conf->renego_max_records < 0 )
-    {
-        uint32_t ratio = ssl->conf->hs_timeout_max / ssl->conf->hs_timeout_min + 1;
-        unsigned char doublings = 1;
-
-        while( ratio != 0 )
-        {
-            ++doublings;
-            ratio >>= 1;
-        }
-
-        if( ++ssl->renego_records_seen > doublings )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 2, ( "no longer retransmitting hello request" ) );
-            return( 0 );
-        }
-    }
-
-    return( ssl_write_hello_request( ssl ) );
-}
-#endif
-#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
-
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 static void ssl_clear_peer_cert( mbedtls_ssl_session *session )
 {
@@ -1642,803 +454,11 @@
 }
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
-/*
- * Handshake functions
- */
-#if !defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
-/* No certificate support -> dummy functions */
-int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
-{
-    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
-        ssl->handshake->ciphersuite_info;
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
-
-    if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
-        ssl->state++;
-        return( 0 );
-    }
-
-    MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
-    return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-}
-
-int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
-{
-    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
-        ssl->handshake->ciphersuite_info;
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
-
-    if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
-        ssl->state++;
-        return( 0 );
-    }
-
-    MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
-    return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-}
-
-#else /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
-/* Some certificate support -> implement write and parse */
-
-int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
-{
-    int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
-    size_t i, n;
-    const mbedtls_x509_crt *crt;
-    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
-        ssl->handshake->ciphersuite_info;
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
-
-    if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
-        ssl->state++;
-        return( 0 );
-    }
-
-#if defined(MBEDTLS_SSL_CLI_C)
-    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
-    {
-        if( ssl->client_auth == 0 )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
-            ssl->state++;
-            return( 0 );
-        }
-    }
-#endif /* MBEDTLS_SSL_CLI_C */
-#if defined(MBEDTLS_SSL_SRV_C)
-    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
-    {
-        if( mbedtls_ssl_own_cert( ssl ) == NULL )
-        {
-            /* Should never happen because we shouldn't have picked the
-             * ciphersuite if we don't have a certificate. */
-            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-        }
-    }
-#endif
-
-    MBEDTLS_SSL_DEBUG_CRT( 3, "own certificate", mbedtls_ssl_own_cert( ssl ) );
-
-    /*
-     *     0  .  0    handshake type
-     *     1  .  3    handshake length
-     *     4  .  6    length of all certs
-     *     7  .  9    length of cert. 1
-     *    10  . n-1   peer certificate
-     *     n  . n+2   length of cert. 2
-     *    n+3 . ...   upper level cert, etc.
-     */
-    i = 7;
-    crt = mbedtls_ssl_own_cert( ssl );
-
-    while( crt != NULL )
-    {
-        n = crt->raw.len;
-        if( n > MBEDTLS_SSL_OUT_CONTENT_LEN - 3 - i )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate too large, %" MBEDTLS_PRINTF_SIZET
-                                        " > %" MBEDTLS_PRINTF_SIZET,
-                           i + 3 + n, (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN ) );
-            return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
-        }
-
-        ssl->out_msg[i    ] = MBEDTLS_BYTE_2( n );
-        ssl->out_msg[i + 1] = MBEDTLS_BYTE_1( n );
-        ssl->out_msg[i + 2] = MBEDTLS_BYTE_0( n );
-
-        i += 3; memcpy( ssl->out_msg + i, crt->raw.p, n );
-        i += n; crt = crt->next;
-    }
-
-    ssl->out_msg[4]  = MBEDTLS_BYTE_2( i - 7 );
-    ssl->out_msg[5]  = MBEDTLS_BYTE_1( i - 7 );
-    ssl->out_msg[6]  = MBEDTLS_BYTE_0( i - 7 );
-
-    ssl->out_msglen  = i;
-    ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
-    ssl->out_msg[0]  = MBEDTLS_SSL_HS_CERTIFICATE;
-
-    ssl->state++;
-
-    if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
-        return( ret );
-    }
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate" ) );
-
-    return( ret );
-}
-
-#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
-
-#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
-static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl,
-                                         unsigned char *crt_buf,
-                                         size_t crt_buf_len )
-{
-    mbedtls_x509_crt const * const peer_crt = ssl->session->peer_cert;
-
-    if( peer_crt == NULL )
-        return( -1 );
-
-    if( peer_crt->raw.len != crt_buf_len )
-        return( -1 );
-
-    return( memcmp( peer_crt->raw.p, crt_buf, peer_crt->raw.len ) );
-}
-#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl,
-                                         unsigned char *crt_buf,
-                                         size_t crt_buf_len )
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    unsigned char const * const peer_cert_digest =
-        ssl->session->peer_cert_digest;
-    mbedtls_md_type_t const peer_cert_digest_type =
-        ssl->session->peer_cert_digest_type;
-    mbedtls_md_info_t const * const digest_info =
-        mbedtls_md_info_from_type( peer_cert_digest_type );
-    unsigned char tmp_digest[MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN];
-    size_t digest_len;
-
-    if( peer_cert_digest == NULL || digest_info == NULL )
-        return( -1 );
-
-    digest_len = mbedtls_md_get_size( digest_info );
-    if( digest_len > MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN )
-        return( -1 );
-
-    ret = mbedtls_md( digest_info, crt_buf, crt_buf_len, tmp_digest );
-    if( ret != 0 )
-        return( -1 );
-
-    return( memcmp( tmp_digest, peer_cert_digest, digest_len ) );
-}
-#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
-
-/*
- * Once the certificate message is read, parse it into a cert chain and
- * perform basic checks, but leave actual verification to the caller
- */
-static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl,
-                                        mbedtls_x509_crt *chain )
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
-    int crt_cnt=0;
-#endif
-    size_t i, n;
-    uint8_t alert;
-
-    if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
-        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
-    }
-
-    if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE  )
-    {
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
-        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
-    }
-
-    if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 3 + 3 )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
-    }
-
-    i = mbedtls_ssl_hs_hdr_len( ssl );
-
-    /*
-     * Same message structure as in mbedtls_ssl_write_certificate()
-     */
-    n = ( ssl->in_msg[i+1] << 8 ) | ssl->in_msg[i+2];
-
-    if( ssl->in_msg[i] != 0 ||
-        ssl->in_hslen != n + 3 + mbedtls_ssl_hs_hdr_len( ssl ) )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
-    }
-
-    /* Make &ssl->in_msg[i] point to the beginning of the CRT chain. */
-    i += 3;
-
-    /* Iterate through and parse the CRTs in the provided chain. */
-    while( i < ssl->in_hslen )
-    {
-        /* Check that there's room for the next CRT's length fields. */
-        if ( i + 3 > ssl->in_hslen ) {
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
-            mbedtls_ssl_send_alert_message( ssl,
-                              MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                              MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
-        }
-        /* In theory, the CRT can be up to 2**24 Bytes, but we don't support
-         * anything beyond 2**16 ~ 64K. */
-        if( ssl->in_msg[i] != 0 )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
-            mbedtls_ssl_send_alert_message( ssl,
-                            MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                            MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT );
-            return( MBEDTLS_ERR_SSL_BAD_CERTIFICATE );
-        }
-
-        /* Read length of the next CRT in the chain. */
-        n = ( (unsigned int) ssl->in_msg[i + 1] << 8 )
-            | (unsigned int) ssl->in_msg[i + 2];
-        i += 3;
-
-        if( n < 128 || i + n > ssl->in_hslen )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
-            mbedtls_ssl_send_alert_message( ssl,
-                                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
-        }
-
-        /* Check if we're handling the first CRT in the chain. */
-#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
-        if( crt_cnt++ == 0 &&
-            ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
-            ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
-        {
-            /* During client-side renegotiation, check that the server's
-             * end-CRTs hasn't changed compared to the initial handshake,
-             * mitigating the triple handshake attack. On success, reuse
-             * the original end-CRT instead of parsing it again. */
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "Check that peer CRT hasn't changed during renegotiation" ) );
-            if( ssl_check_peer_crt_unchanged( ssl,
-                                              &ssl->in_msg[i],
-                                              n ) != 0 )
-            {
-                MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) );
-                mbedtls_ssl_send_alert_message( ssl,
-                                                MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                                MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
-                return( MBEDTLS_ERR_SSL_BAD_CERTIFICATE );
-            }
-
-            /* Now we can safely free the original chain. */
-            ssl_clear_peer_cert( ssl->session );
-        }
-#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
-
-        /* Parse the next certificate in the chain. */
-#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
-        ret = mbedtls_x509_crt_parse_der( chain, ssl->in_msg + i, n );
-#else
-        /* If we don't need to store the CRT chain permanently, parse
-         * it in-place from the input buffer instead of making a copy. */
-        ret = mbedtls_x509_crt_parse_der_nocopy( chain, ssl->in_msg + i, n );
-#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-        switch( ret )
-        {
-            case 0: /*ok*/
-            case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND:
-                /* Ignore certificate with an unknown algorithm: maybe a
-                   prior certificate was already trusted. */
-                break;
-
-            case MBEDTLS_ERR_X509_ALLOC_FAILED:
-                alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR;
-                goto crt_parse_der_failed;
-
-            case MBEDTLS_ERR_X509_UNKNOWN_VERSION:
-                alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
-                goto crt_parse_der_failed;
-
-            default:
-                alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
-            crt_parse_der_failed:
-                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert );
-                MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret );
-                return( ret );
-        }
-
-        i += n;
-    }
-
-    MBEDTLS_SSL_DEBUG_CRT( 3, "peer certificate", chain );
-    return( 0 );
-}
-
-#if defined(MBEDTLS_SSL_SRV_C)
-static int ssl_srv_check_client_no_crt_notification( mbedtls_ssl_context *ssl )
-{
-    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
-        return( -1 );
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-    if( ssl->in_hslen   == 3 + mbedtls_ssl_hs_hdr_len( ssl ) &&
-        ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE    &&
-        ssl->in_msg[0]  == MBEDTLS_SSL_HS_CERTIFICATE   &&
-        memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), "\0\0\0", 3 ) == 0 )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) );
-        return( 0 );
-    }
-
-    return( -1 );
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-}
-#endif /* MBEDTLS_SSL_SRV_C */
-
-/* Check if a certificate message is expected.
- * Return either
- * - SSL_CERTIFICATE_EXPECTED, or
- * - SSL_CERTIFICATE_SKIP
- * indicating whether a Certificate message is expected or not.
- */
-#define SSL_CERTIFICATE_EXPECTED 0
-#define SSL_CERTIFICATE_SKIP     1
-static int ssl_parse_certificate_coordinate( mbedtls_ssl_context *ssl,
-                                             int authmode )
-{
-    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
-        ssl->handshake->ciphersuite_info;
-
-    if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
-        return( SSL_CERTIFICATE_SKIP );
-
-#if defined(MBEDTLS_SSL_SRV_C)
-    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
-    {
-        if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
-            return( SSL_CERTIFICATE_SKIP );
-
-        if( authmode == MBEDTLS_SSL_VERIFY_NONE )
-        {
-            ssl->session_negotiate->verify_result =
-                MBEDTLS_X509_BADCERT_SKIP_VERIFY;
-            return( SSL_CERTIFICATE_SKIP );
-        }
-    }
-#else
-    ((void) authmode);
-#endif /* MBEDTLS_SSL_SRV_C */
-
-    return( SSL_CERTIFICATE_EXPECTED );
-}
-
-static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl,
-                                         int authmode,
-                                         mbedtls_x509_crt *chain,
-                                         void *rs_ctx )
-{
-    int ret = 0;
-    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
-        ssl->handshake->ciphersuite_info;
-    int have_ca_chain = 0;
-
-    int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *);
-    void *p_vrfy;
-
-    if( authmode == MBEDTLS_SSL_VERIFY_NONE )
-        return( 0 );
-
-    if( ssl->f_vrfy != NULL )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use context-specific verification callback" ) );
-        f_vrfy = ssl->f_vrfy;
-        p_vrfy = ssl->p_vrfy;
-    }
-    else
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use configuration-specific verification callback" ) );
-        f_vrfy = ssl->conf->f_vrfy;
-        p_vrfy = ssl->conf->p_vrfy;
-    }
-
-    /*
-     * Main check: verify certificate
-     */
-#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
-    if( ssl->conf->f_ca_cb != NULL )
-    {
-        ((void) rs_ctx);
-        have_ca_chain = 1;
-
-        MBEDTLS_SSL_DEBUG_MSG( 3, ( "use CA callback for X.509 CRT verification" ) );
-        ret = mbedtls_x509_crt_verify_with_ca_cb(
-            chain,
-            ssl->conf->f_ca_cb,
-            ssl->conf->p_ca_cb,
-            ssl->conf->cert_profile,
-            ssl->hostname,
-            &ssl->session_negotiate->verify_result,
-            f_vrfy, p_vrfy );
-    }
-    else
-#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
-    {
-        mbedtls_x509_crt *ca_chain;
-        mbedtls_x509_crl *ca_crl;
-
-#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
-        if( ssl->handshake->sni_ca_chain != NULL )
-        {
-            ca_chain = ssl->handshake->sni_ca_chain;
-            ca_crl   = ssl->handshake->sni_ca_crl;
-        }
-        else
-#endif
-        {
-            ca_chain = ssl->conf->ca_chain;
-            ca_crl   = ssl->conf->ca_crl;
-        }
-
-        if( ca_chain != NULL )
-            have_ca_chain = 1;
-
-        ret = mbedtls_x509_crt_verify_restartable(
-            chain,
-            ca_chain, ca_crl,
-            ssl->conf->cert_profile,
-            ssl->hostname,
-            &ssl->session_negotiate->verify_result,
-            f_vrfy, p_vrfy, rs_ctx );
-    }
-
-    if( ret != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", ret );
-    }
-
-#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
-    if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
-        return( MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS );
-#endif
-
-    /*
-     * Secondary checks: always done, but change 'ret' only if it was 0
-     */
-
-#if defined(MBEDTLS_ECP_C)
-    {
-        const mbedtls_pk_context *pk = &chain->pk;
-
-        /* If certificate uses an EC key, make sure the curve is OK */
-        if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) &&
-            mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 )
-        {
-            ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY;
-
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) );
-            if( ret == 0 )
-                ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
-        }
-    }
-#endif /* MBEDTLS_ECP_C */
-
-    if( mbedtls_ssl_check_cert_usage( chain,
-                                      ciphersuite_info,
-                                      ! ssl->conf->endpoint,
-                                      &ssl->session_negotiate->verify_result ) != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) );
-        if( ret == 0 )
-            ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
-    }
-
-    /* mbedtls_x509_crt_verify_with_profile is supposed to report a
-     * verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED,
-     * with details encoded in the verification flags. All other kinds
-     * of error codes, including those from the user provided f_vrfy
-     * functions, are treated as fatal and lead to a failure of
-     * ssl_parse_certificate even if verification was optional. */
-    if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
-        ( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
-          ret == MBEDTLS_ERR_SSL_BAD_CERTIFICATE ) )
-    {
-        ret = 0;
-    }
-
-    if( have_ca_chain == 0 && authmode == MBEDTLS_SSL_VERIFY_REQUIRED )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) );
-        ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
-    }
-
-    if( ret != 0 )
-    {
-        uint8_t alert;
-
-        /* The certificate may have been rejected for several reasons.
-           Pick one and send the corresponding alert. Which alert to send
-           may be a subject of debate in some cases. */
-        if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER )
-            alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED;
-        else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH )
-            alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
-        else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE )
-            alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
-        else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE )
-            alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
-        else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NS_CERT_TYPE )
-            alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
-        else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK )
-            alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
-        else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY )
-            alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
-        else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED )
-            alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED;
-        else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED )
-            alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED;
-        else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED )
-            alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA;
-        else
-            alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN;
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        alert );
-    }
-
-#if defined(MBEDTLS_DEBUG_C)
-    if( ssl->session_negotiate->verify_result != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 3, ( "! Certificate verification flags %08x",
-                                    (unsigned int) ssl->session_negotiate->verify_result ) );
-    }
-    else
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 3, ( "Certificate verification flags clear" ) );
-    }
-#endif /* MBEDTLS_DEBUG_C */
-
-    return( ret );
-}
-
-#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
-static int ssl_remember_peer_crt_digest( mbedtls_ssl_context *ssl,
-                                         unsigned char *start, size_t len )
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    /* Remember digest of the peer's end-CRT. */
-    ssl->session_negotiate->peer_cert_digest =
-        mbedtls_calloc( 1, MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN );
-    if( ssl->session_negotiate->peer_cert_digest == NULL )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
-                                    MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN ) );
-        mbedtls_ssl_send_alert_message( ssl,
-                                        MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
-
-        return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
-    }
-
-    ret = mbedtls_md( mbedtls_md_info_from_type(
-                          MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE ),
-                      start, len,
-                      ssl->session_negotiate->peer_cert_digest );
-
-    ssl->session_negotiate->peer_cert_digest_type =
-        MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE;
-    ssl->session_negotiate->peer_cert_digest_len =
-        MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN;
-
-    return( ret );
-}
-
-static int ssl_remember_peer_pubkey( mbedtls_ssl_context *ssl,
-                                     unsigned char *start, size_t len )
-{
-    unsigned char *end = start + len;
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-
-    /* Make a copy of the peer's raw public key. */
-    mbedtls_pk_init( &ssl->handshake->peer_pubkey );
-    ret = mbedtls_pk_parse_subpubkey( &start, end,
-                                      &ssl->handshake->peer_pubkey );
-    if( ret != 0 )
-    {
-        /* We should have parsed the public key before. */
-        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-    }
-
-    return( 0 );
-}
-#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-
-int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
-{
-    int ret = 0;
-    int crt_expected;
-#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
-    const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET
-                       ? ssl->handshake->sni_authmode
-                       : ssl->conf->authmode;
-#else
-    const int authmode = ssl->conf->authmode;
-#endif
-    void *rs_ctx = NULL;
-    mbedtls_x509_crt *chain = NULL;
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
-
-    crt_expected = ssl_parse_certificate_coordinate( ssl, authmode );
-    if( crt_expected == SSL_CERTIFICATE_SKIP )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
-        goto exit;
-    }
-
-#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
-    if( ssl->handshake->ecrs_enabled &&
-        ssl->handshake->ecrs_state == ssl_ecrs_crt_verify )
-    {
-        chain = ssl->handshake->ecrs_peer_cert;
-        ssl->handshake->ecrs_peer_cert = NULL;
-        goto crt_verify;
-    }
-#endif
-
-    if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
-    {
-        /* mbedtls_ssl_read_record may have sent an alert already. We
-           let it decide whether to alert. */
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
-        goto exit;
-    }
-
-#if defined(MBEDTLS_SSL_SRV_C)
-    if( ssl_srv_check_client_no_crt_notification( ssl ) == 0 )
-    {
-        ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
-
-        if( authmode != MBEDTLS_SSL_VERIFY_OPTIONAL )
-            ret = MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE;
-
-        goto exit;
-    }
-#endif /* MBEDTLS_SSL_SRV_C */
-
-    /* Clear existing peer CRT structure in case we tried to
-     * reuse a session but it failed, and allocate a new one. */
-    ssl_clear_peer_cert( ssl->session_negotiate );
-
-    chain = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
-    if( chain == NULL )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%" MBEDTLS_PRINTF_SIZET " bytes) failed",
-                                    sizeof( mbedtls_x509_crt ) ) );
-        mbedtls_ssl_send_alert_message( ssl,
-                                        MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
-
-        ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
-        goto exit;
-    }
-    mbedtls_x509_crt_init( chain );
-
-    ret = ssl_parse_certificate_chain( ssl, chain );
-    if( ret != 0 )
-        goto exit;
-
-#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
-    if( ssl->handshake->ecrs_enabled)
-        ssl->handshake->ecrs_state = ssl_ecrs_crt_verify;
-
-crt_verify:
-    if( ssl->handshake->ecrs_enabled)
-        rs_ctx = &ssl->handshake->ecrs_ctx;
-#endif
-
-    ret = ssl_parse_certificate_verify( ssl, authmode,
-                                        chain, rs_ctx );
-    if( ret != 0 )
-        goto exit;
-
-#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
-    {
-        unsigned char *crt_start, *pk_start;
-        size_t crt_len, pk_len;
-
-        /* We parse the CRT chain without copying, so
-         * these pointers point into the input buffer,
-         * and are hence still valid after freeing the
-         * CRT chain. */
-
-        crt_start = chain->raw.p;
-        crt_len   = chain->raw.len;
-
-        pk_start = chain->pk_raw.p;
-        pk_len   = chain->pk_raw.len;
-
-        /* Free the CRT structures before computing
-         * digest and copying the peer's public key. */
-        mbedtls_x509_crt_free( chain );
-        mbedtls_free( chain );
-        chain = NULL;
-
-        ret = ssl_remember_peer_crt_digest( ssl, crt_start, crt_len );
-        if( ret != 0 )
-            goto exit;
-
-        ret = ssl_remember_peer_pubkey( ssl, pk_start, pk_len );
-        if( ret != 0 )
-            goto exit;
-    }
-#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-    /* Pass ownership to session structure. */
-    ssl->session_negotiate->peer_cert = chain;
-    chain = NULL;
-#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) );
-
-exit:
-
-    if( ret == 0 )
-        ssl->state++;
-
-#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
-    if( ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
-    {
-        ssl->handshake->ecrs_peer_cert = chain;
-        chain = NULL;
-    }
-#endif
-
-    if( chain != NULL )
-    {
-        mbedtls_x509_crt_free( chain );
-        mbedtls_free( chain );
-    }
-
-    return( ret );
-}
-#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
-
 void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl,
                             const mbedtls_ssl_ciphersuite_t *ciphersuite_info )
 {
     ((void) ciphersuite_info);
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 #if defined(MBEDTLS_SHA384_C)
     if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
         ssl->handshake->update_checksum = ssl_update_checksum_sha384;
@@ -2449,7 +469,6 @@
         ssl->handshake->update_checksum = ssl_update_checksum_sha256;
     else
 #endif
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
         return;
@@ -2458,7 +477,7 @@
 
 void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl )
 {
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    ((void) ssl);
 #if defined(MBEDTLS_SHA256_C)
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_hash_abort( &ssl->handshake->fin_sha256_psa );
@@ -2475,13 +494,11 @@
     mbedtls_sha512_starts( &ssl->handshake->fin_sha512, 1 );
 #endif
 #endif
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 }
 
 static void ssl_update_checksum_start( mbedtls_ssl_context *ssl,
                                        const unsigned char *buf, size_t len )
 {
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 #if defined(MBEDTLS_SHA256_C)
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_hash_update( &ssl->handshake->fin_sha256_psa, buf, len );
@@ -2496,10 +513,8 @@
     mbedtls_sha512_update( &ssl->handshake->fin_sha512, buf, len );
 #endif
 #endif
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 }
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 #if defined(MBEDTLS_SHA256_C)
 static void ssl_update_checksum_sha256( mbedtls_ssl_context *ssl,
                                         const unsigned char *buf, size_t len )
@@ -2523,451 +538,11 @@
 #endif
 }
 #endif
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#if defined(MBEDTLS_SHA256_C)
-static void ssl_calc_finished_tls_sha256(
-                mbedtls_ssl_context *ssl, unsigned char *buf, int from )
-{
-    int len = 12;
-    const char *sender;
-    unsigned char padbuf[32];
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-    size_t hash_size;
-    psa_hash_operation_t sha256_psa = PSA_HASH_OPERATION_INIT;
-    psa_status_t status;
-#else
-    mbedtls_sha256_context sha256;
-#endif
-
-    mbedtls_ssl_session *session = ssl->session_negotiate;
-    if( !session )
-        session = ssl->session;
-
-    sender = ( from == MBEDTLS_SSL_IS_CLIENT )
-             ? "client finished"
-             : "server finished";
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-    sha256_psa = psa_hash_operation_init();
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc PSA finished tls sha256" ) );
-
-    status = psa_hash_clone( &ssl->handshake->fin_sha256_psa, &sha256_psa );
-    if( status != PSA_SUCCESS )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
-        return;
-    }
-
-    status = psa_hash_finish( &sha256_psa, padbuf, sizeof( padbuf ), &hash_size );
-    if( status != PSA_SUCCESS )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
-        return;
-    }
-    MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated padbuf", padbuf, 32 );
-#else
-
-    mbedtls_sha256_init( &sha256 );
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc  finished tls sha256" ) );
-
-    mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
-
-    /*
-     * TLSv1.2:
-     *   hash = PRF( master, finished_label,
-     *               Hash( handshake ) )[0.11]
-     */
-
-#if !defined(MBEDTLS_SHA256_ALT)
-    MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *)
-                   sha256.state, sizeof( sha256.state ) );
-#endif
-
-    mbedtls_sha256_finish( &sha256, padbuf );
-    mbedtls_sha256_free( &sha256 );
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
-    ssl->handshake->tls_prf( session->master, 48, sender,
-                             padbuf, 32, buf, len );
-
-    MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
-
-    mbedtls_platform_zeroize(  padbuf, sizeof(  padbuf ) );
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
-}
-#endif /* MBEDTLS_SHA256_C */
-
-#if defined(MBEDTLS_SHA384_C)
-
-static void ssl_calc_finished_tls_sha384(
-                mbedtls_ssl_context *ssl, unsigned char *buf, int from )
-{
-    int len = 12;
-    const char *sender;
-    unsigned char padbuf[48];
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-    size_t hash_size;
-    psa_hash_operation_t sha384_psa = PSA_HASH_OPERATION_INIT;
-    psa_status_t status;
-#else
-    mbedtls_sha512_context sha512;
-#endif
-
-    mbedtls_ssl_session *session = ssl->session_negotiate;
-    if( !session )
-        session = ssl->session;
-
-    sender = ( from == MBEDTLS_SSL_IS_CLIENT )
-                ? "client finished"
-                : "server finished";
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-    sha384_psa = psa_hash_operation_init();
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc PSA finished tls sha384" ) );
-
-    status = psa_hash_clone( &ssl->handshake->fin_sha384_psa, &sha384_psa );
-    if( status != PSA_SUCCESS )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
-        return;
-    }
-
-    status = psa_hash_finish( &sha384_psa, padbuf, sizeof( padbuf ), &hash_size );
-    if( status != PSA_SUCCESS )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
-        return;
-    }
-    MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated padbuf", padbuf, 48 );
-#else
-    mbedtls_sha512_init( &sha512 );
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc  finished tls sha384" ) );
-
-    mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
-
-    /*
-     * TLSv1.2:
-     *   hash = PRF( master, finished_label,
-     *               Hash( handshake ) )[0.11]
-     */
-
-#if !defined(MBEDTLS_SHA512_ALT)
-    MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *)
-                   sha512.state, sizeof( sha512.state ) );
-#endif
-    mbedtls_sha512_finish( &sha512, padbuf );
-
-    mbedtls_sha512_free( &sha512 );
-#endif
-
-    ssl->handshake->tls_prf( session->master, 48, sender,
-                             padbuf, 48, buf, len );
-
-    MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
-
-    mbedtls_platform_zeroize(  padbuf, sizeof( padbuf ) );
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
-}
-#endif /* MBEDTLS_SHA384_C */
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-
-void mbedtls_ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl )
-{
-    MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup: final free" ) );
-
-    /*
-     * Free our handshake params
-     */
-    mbedtls_ssl_handshake_free( ssl );
-    mbedtls_free( ssl->handshake );
-    ssl->handshake = NULL;
-
-    /*
-     * Free the previous transform and swith in the current one
-     */
-    if( ssl->transform )
-    {
-        mbedtls_ssl_transform_free( ssl->transform );
-        mbedtls_free( ssl->transform );
-    }
-    ssl->transform = ssl->transform_negotiate;
-    ssl->transform_negotiate = NULL;
-
-    MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup: final free" ) );
-}
-
-void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl )
-{
-    int resume = ssl->handshake->resume;
-
-    MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup" ) );
-
-#if defined(MBEDTLS_SSL_RENEGOTIATION)
-    if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
-    {
-        ssl->renego_status =  MBEDTLS_SSL_RENEGOTIATION_DONE;
-        ssl->renego_records_seen = 0;
-    }
-#endif
-
-    /*
-     * Free the previous session and switch in the current one
-     */
-    if( ssl->session )
-    {
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
-        /* RFC 7366 3.1: keep the EtM state */
-        ssl->session_negotiate->encrypt_then_mac =
-                  ssl->session->encrypt_then_mac;
-#endif
-
-        mbedtls_ssl_session_free( ssl->session );
-        mbedtls_free( ssl->session );
-    }
-    ssl->session = ssl->session_negotiate;
-    ssl->session_negotiate = NULL;
-
-    /*
-     * Add cache entry
-     */
-    if( ssl->conf->f_set_cache != NULL &&
-        ssl->session->id_len != 0 &&
-        resume == 0 )
-    {
-        if( ssl->conf->f_set_cache( ssl->conf->p_cache,
-                                    ssl->session->id,
-                                    ssl->session->id_len,
-                                    ssl->session ) != 0 )
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "cache did not store session" ) );
-    }
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
-        ssl->handshake->flight != NULL )
-    {
-        /* Cancel handshake timer */
-        mbedtls_ssl_set_timer( ssl, 0 );
-
-        /* Keep last flight around in case we need to resend it:
-         * we need the handshake and transform structures for that */
-        MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip freeing handshake and transform" ) );
-    }
-    else
-#endif
-        mbedtls_ssl_handshake_wrapup_free_hs_transform( ssl );
-
-    ssl->state++;
-
-    MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup" ) );
-}
-
-int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl )
-{
-    int ret, hash_len;
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write finished" ) );
-
-    mbedtls_ssl_update_out_pointers( ssl, ssl->transform_negotiate );
-
-    ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint );
-
-    /*
-     * RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites
-     * may define some other value. Currently (early 2016), no defined
-     * ciphersuite does this (and this is unlikely to change as activity has
-     * moved to TLS 1.3 now) so we can keep the hardcoded 12 here.
-     */
-    hash_len = 12;
-
-#if defined(MBEDTLS_SSL_RENEGOTIATION)
-    ssl->verify_data_len = hash_len;
-    memcpy( ssl->own_verify_data, ssl->out_msg + 4, hash_len );
-#endif
-
-    ssl->out_msglen  = 4 + hash_len;
-    ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
-    ssl->out_msg[0]  = MBEDTLS_SSL_HS_FINISHED;
-
-    /*
-     * In case of session resuming, invert the client and server
-     * ChangeCipherSpec messages order.
-     */
-    if( ssl->handshake->resume != 0 )
-    {
-#if defined(MBEDTLS_SSL_CLI_C)
-        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
-            ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
-#endif
-#if defined(MBEDTLS_SSL_SRV_C)
-        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
-            ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC;
-#endif
-    }
-    else
-        ssl->state++;
-
-    /*
-     * Switch to our negotiated transform and session parameters for outbound
-     * data.
-     */
-    MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for outbound data" ) );
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
-    {
-        unsigned char i;
-
-        /* Remember current epoch settings for resending */
-        ssl->handshake->alt_transform_out = ssl->transform_out;
-        memcpy( ssl->handshake->alt_out_ctr, ssl->cur_out_ctr,
-                sizeof( ssl->handshake->alt_out_ctr ) );
-
-        /* Set sequence_number to zero */
-        memset( &ssl->cur_out_ctr[2], 0, sizeof( ssl->cur_out_ctr ) - 2 );
-
-
-        /* Increment epoch */
-        for( i = 2; i > 0; i-- )
-            if( ++ssl->cur_out_ctr[i - 1] != 0 )
-                break;
-
-        /* The loop goes to its end iff the counter is wrapping */
-        if( i == 0 )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) );
-            return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
-        }
-    }
-    else
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-    memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) );
-
-    ssl->transform_out = ssl->transform_negotiate;
-    ssl->session_out = ssl->session_negotiate;
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
-        mbedtls_ssl_send_flight_completed( ssl );
-#endif
-
-    if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
-        return( ret );
-    }
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
-        ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
-        return( ret );
-    }
-#endif
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write finished" ) );
-
-    return( 0 );
-}
-
-#define SSL_MAX_HASH_LEN 12
-
-int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl )
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    unsigned int hash_len = 12;
-    unsigned char buf[SSL_MAX_HASH_LEN];
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse finished" ) );
-
-    ssl->handshake->calc_finished( ssl, buf, ssl->conf->endpoint ^ 1 );
-
-    if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
-        goto exit;
-    }
-
-    if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
-        ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
-        goto exit;
-    }
-
-    if( ssl->in_msg[0] != MBEDTLS_SSL_HS_FINISHED  )
-    {
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
-        ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
-        goto exit;
-    }
-
-    if( ssl->in_hslen  != mbedtls_ssl_hs_hdr_len( ssl ) + hash_len )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        ret = MBEDTLS_ERR_SSL_DECODE_ERROR;
-        goto exit;
-    }
-
-    if( mbedtls_ct_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ),
-                      buf, hash_len ) != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR );
-        ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
-        goto exit;
-    }
-
-#if defined(MBEDTLS_SSL_RENEGOTIATION)
-    ssl->verify_data_len = hash_len;
-    memcpy( ssl->peer_verify_data, buf, hash_len );
-#endif
-
-    if( ssl->handshake->resume != 0 )
-    {
-#if defined(MBEDTLS_SSL_CLI_C)
-        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
-            ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC;
-#endif
-#if defined(MBEDTLS_SSL_SRV_C)
-        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
-            ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
-#endif
-    }
-    else
-        ssl->state++;
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
-        mbedtls_ssl_recv_flight_completed( ssl );
-#endif
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse finished" ) );
-
-exit:
-    mbedtls_platform_zeroize( buf, hash_len );
-    return( ret );
-}
 
 static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake )
 {
     memset( handshake, 0, sizeof( mbedtls_ssl_handshake_params ) );
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 #if defined(MBEDTLS_SHA256_C)
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     handshake->fin_sha256_psa = psa_hash_operation_init();
@@ -2986,7 +561,6 @@
     mbedtls_sha512_starts( &handshake->fin_sha512, 1 );
 #endif
 #endif
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
     handshake->update_checksum = ssl_update_checksum_start;
 
@@ -4959,177 +2533,6 @@
  *
  */
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-/* Serialization of TLS 1.2 sessions:
- *
- * struct {
- *    uint64 start_time;
- *    uint8 ciphersuite[2];           // defined by the standard
- *    uint8 compression;              // 0 or 1
- *    uint8 session_id_len;           // at most 32
- *    opaque session_id[32];
- *    opaque master[48];              // fixed length in the standard
- *    uint32 verify_result;
- *    opaque peer_cert<0..2^24-1>;    // length 0 means no peer cert
- *    opaque ticket<0..2^24-1>;       // length 0 means no ticket
- *    uint32 ticket_lifetime;
- *    uint8 mfl_code;                 // up to 255 according to standard
- *    uint8 encrypt_then_mac;         // 0 or 1
- * } serialized_session_tls12;
- *
- */
-static size_t ssl_session_save_tls12( const mbedtls_ssl_session *session,
-                                      unsigned char *buf,
-                                      size_t buf_len )
-{
-    unsigned char *p = buf;
-    size_t used = 0;
-
-#if defined(MBEDTLS_HAVE_TIME)
-    uint64_t start;
-#endif
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
-    size_t cert_len;
-#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
-    /*
-     * Time
-     */
-#if defined(MBEDTLS_HAVE_TIME)
-    used += 8;
-
-    if( used <= buf_len )
-    {
-        start = (uint64_t) session->start;
-
-        MBEDTLS_PUT_UINT64_BE( start, p, 0 );
-        p += 8;
-    }
-#endif /* MBEDTLS_HAVE_TIME */
-
-    /*
-     * Basic mandatory fields
-     */
-    used += 2   /* ciphersuite */
-          + 1   /* compression */
-          + 1   /* id_len */
-          + sizeof( session->id )
-          + sizeof( session->master )
-          + 4;  /* verify_result */
-
-    if( used <= buf_len )
-    {
-        MBEDTLS_PUT_UINT16_BE( session->ciphersuite, p, 0 );
-        p += 2;
-
-        *p++ = MBEDTLS_BYTE_0( session->compression );
-
-        *p++ = MBEDTLS_BYTE_0( session->id_len );
-        memcpy( p, session->id, 32 );
-        p += 32;
-
-        memcpy( p, session->master, 48 );
-        p += 48;
-
-        MBEDTLS_PUT_UINT32_BE( session->verify_result, p, 0 );
-        p += 4;
-    }
-
-    /*
-     * Peer's end-entity certificate
-     */
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
-    if( session->peer_cert == NULL )
-        cert_len = 0;
-    else
-        cert_len = session->peer_cert->raw.len;
-
-    used += 3 + cert_len;
-
-    if( used <= buf_len )
-    {
-        *p++ = MBEDTLS_BYTE_2( cert_len );
-        *p++ = MBEDTLS_BYTE_1( cert_len );
-        *p++ = MBEDTLS_BYTE_0( cert_len );
-
-        if( session->peer_cert != NULL )
-        {
-            memcpy( p, session->peer_cert->raw.p, cert_len );
-            p += cert_len;
-        }
-    }
-#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-    if( session->peer_cert_digest != NULL )
-    {
-        used += 1 /* type */ + 1 /* length */ + session->peer_cert_digest_len;
-        if( used <= buf_len )
-        {
-            *p++ = (unsigned char) session->peer_cert_digest_type;
-            *p++ = (unsigned char) session->peer_cert_digest_len;
-            memcpy( p, session->peer_cert_digest,
-                    session->peer_cert_digest_len );
-            p += session->peer_cert_digest_len;
-        }
-    }
-    else
-    {
-        used += 2;
-        if( used <= buf_len )
-        {
-            *p++ = (unsigned char) MBEDTLS_MD_NONE;
-            *p++ = 0;
-        }
-    }
-#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
-    /*
-     * Session ticket if any, plus associated data
-     */
-#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
-    used += 3 + session->ticket_len + 4; /* len + ticket + lifetime */
-
-    if( used <= buf_len )
-    {
-        *p++ = MBEDTLS_BYTE_2( session->ticket_len );
-        *p++ = MBEDTLS_BYTE_1( session->ticket_len );
-        *p++ = MBEDTLS_BYTE_0( session->ticket_len );
-
-        if( session->ticket != NULL )
-        {
-            memcpy( p, session->ticket, session->ticket_len );
-            p += session->ticket_len;
-        }
-
-        MBEDTLS_PUT_UINT32_BE( session->ticket_lifetime, p, 0 );
-        p += 4;
-    }
-#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
-
-    /*
-     * Misc extension-related info
-     */
-#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
-    used += 1;
-
-    if( used <= buf_len )
-        *p++ = session->mfl_code;
-#endif
-
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
-    used += 1;
-
-    if( used <= buf_len )
-        *p++ = MBEDTLS_BYTE_0( session->encrypt_then_mac );
-#endif
-
-    return( used );
-}
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-
 static int ssl_session_save( const mbedtls_ssl_session *session,
                              unsigned char omit_header,
                              unsigned char *buf,
@@ -5204,205 +2607,6 @@
  * This internal version is wrapped by a public function that cleans up in
  * case of error, and has an extra option omit_header.
  */
-static int ssl_session_load_tls12( mbedtls_ssl_session *session,
-                                   const unsigned char *buf,
-                                   size_t len )
-{
-#if defined(MBEDTLS_HAVE_TIME)
-    uint64_t start;
-#endif
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
-    size_t cert_len;
-#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
-    const unsigned char *p = buf;
-    const unsigned char * const end = buf + len;
-
-    /*
-     * Time
-     */
-#if defined(MBEDTLS_HAVE_TIME)
-    if( 8 > (size_t)( end - p ) )
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-    start = ( (uint64_t) p[0] << 56 ) |
-            ( (uint64_t) p[1] << 48 ) |
-            ( (uint64_t) p[2] << 40 ) |
-            ( (uint64_t) p[3] << 32 ) |
-            ( (uint64_t) p[4] << 24 ) |
-            ( (uint64_t) p[5] << 16 ) |
-            ( (uint64_t) p[6] <<  8 ) |
-            ( (uint64_t) p[7]       );
-    p += 8;
-
-    session->start = (time_t) start;
-#endif /* MBEDTLS_HAVE_TIME */
-
-    /*
-     * Basic mandatory fields
-     */
-    if( 2 + 1 + 1 + 32 + 48 + 4 > (size_t)( end - p ) )
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-    session->ciphersuite = ( p[0] << 8 ) | p[1];
-    p += 2;
-
-    session->compression = *p++;
-
-    session->id_len = *p++;
-    memcpy( session->id, p, 32 );
-    p += 32;
-
-    memcpy( session->master, p, 48 );
-    p += 48;
-
-    session->verify_result = ( (uint32_t) p[0] << 24 ) |
-                             ( (uint32_t) p[1] << 16 ) |
-                             ( (uint32_t) p[2] <<  8 ) |
-                             ( (uint32_t) p[3]       );
-    p += 4;
-
-    /* Immediately clear invalid pointer values that have been read, in case
-     * we exit early before we replaced them with valid ones. */
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
-    session->peer_cert = NULL;
-#else
-    session->peer_cert_digest = NULL;
-#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
-    session->ticket = NULL;
-#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
-
-    /*
-     * Peer certificate
-     */
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
-    /* Deserialize CRT from the end of the ticket. */
-    if( 3 > (size_t)( end - p ) )
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-    cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
-    p += 3;
-
-    if( cert_len != 0 )
-    {
-        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-
-        if( cert_len > (size_t)( end - p ) )
-            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-        session->peer_cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
-
-        if( session->peer_cert == NULL )
-            return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
-
-        mbedtls_x509_crt_init( session->peer_cert );
-
-        if( ( ret = mbedtls_x509_crt_parse_der( session->peer_cert,
-                                                p, cert_len ) ) != 0 )
-        {
-            mbedtls_x509_crt_free( session->peer_cert );
-            mbedtls_free( session->peer_cert );
-            session->peer_cert = NULL;
-            return( ret );
-        }
-
-        p += cert_len;
-    }
-#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-    /* Deserialize CRT digest from the end of the ticket. */
-    if( 2 > (size_t)( end - p ) )
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-    session->peer_cert_digest_type = (mbedtls_md_type_t) *p++;
-    session->peer_cert_digest_len  = (size_t) *p++;
-
-    if( session->peer_cert_digest_len != 0 )
-    {
-        const mbedtls_md_info_t *md_info =
-            mbedtls_md_info_from_type( session->peer_cert_digest_type );
-        if( md_info == NULL )
-            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-        if( session->peer_cert_digest_len != mbedtls_md_get_size( md_info ) )
-            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-        if( session->peer_cert_digest_len > (size_t)( end - p ) )
-            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-        session->peer_cert_digest =
-            mbedtls_calloc( 1, session->peer_cert_digest_len );
-        if( session->peer_cert_digest == NULL )
-            return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
-
-        memcpy( session->peer_cert_digest, p,
-                session->peer_cert_digest_len );
-        p += session->peer_cert_digest_len;
-    }
-#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
-    /*
-     * Session ticket and associated data
-     */
-#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
-    if( 3 > (size_t)( end - p ) )
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-    session->ticket_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
-    p += 3;
-
-    if( session->ticket_len != 0 )
-    {
-        if( session->ticket_len > (size_t)( end - p ) )
-            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-        session->ticket = mbedtls_calloc( 1, session->ticket_len );
-        if( session->ticket == NULL )
-            return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
-
-        memcpy( session->ticket, p, session->ticket_len );
-        p += session->ticket_len;
-    }
-
-    if( 4 > (size_t)( end - p ) )
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-    session->ticket_lifetime = ( (uint32_t) p[0] << 24 ) |
-                               ( (uint32_t) p[1] << 16 ) |
-                               ( (uint32_t) p[2] <<  8 ) |
-                               ( (uint32_t) p[3]       );
-    p += 4;
-#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
-
-    /*
-     * Misc extension-related info
-     */
-#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
-    if( 1 > (size_t)( end - p ) )
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-    session->mfl_code = *p++;
-#endif
-
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
-    if( 1 > (size_t)( end - p ) )
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-    session->encrypt_then_mac = *p++;
-#endif
-
-    /* Done, should have consumed entire buffer */
-    if( p != end )
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-    return( 0 );
-}
-
 static int ssl_session_load( mbedtls_ssl_session *session,
                              unsigned char omit_header,
                              const unsigned char *buf,
@@ -5756,7 +2960,12 @@
         mbedtls_free( (void*) handshake->sig_algs );
     handshake->sig_algs = NULL;
 #endif /* MBEDTLS_DEPRECATED_REMOVED */
-
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+    if( ssl->handshake->certificate_request_context )
+    {
+        mbedtls_free( (void*) handshake->certificate_request_context );
+    }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
 #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
@@ -5767,7 +2976,6 @@
     }
 #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 #if defined(MBEDTLS_SHA256_C)
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_hash_abort( &handshake->fin_sha256_psa );
@@ -5782,7 +2990,6 @@
     mbedtls_sha512_free(   &handshake->fin_sha512    );
 #endif
 #endif
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
 #if defined(MBEDTLS_DHM_C)
     mbedtls_dhm_free( &handshake->dhm_ctx );
@@ -6198,28 +3405,6 @@
 }
 
 /*
- * Helper to get TLS 1.2 PRF from ciphersuite
- * (Duplicates bits of logic from ssl_set_handshake_prfs().)
- */
-typedef int (*tls_prf_fn)( const unsigned char *secret, size_t slen,
-                           const char *label,
-                           const unsigned char *random, size_t rlen,
-                           unsigned char *dstbuf, size_t dlen );
-static tls_prf_fn ssl_tls12prf_from_cs( int ciphersuite_id )
-{
-#if defined(MBEDTLS_SHA384_C)
-    const mbedtls_ssl_ciphersuite_t * const ciphersuite_info =
-         mbedtls_ssl_ciphersuite_from_id( ciphersuite_id );
-
-    if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
-        return( tls_prf_sha384 );
-#else
-    (void) ciphersuite_id;
-#endif
-    return( tls_prf_sha256 );
-}
-
-/*
  * Deserialize context, see mbedtls_ssl_context_save() for format.
  *
  * This internal version is wrapped by a public function that cleans up in
@@ -6323,7 +3508,7 @@
     /* Read random bytes and populate structure */
     if( (size_t)( end - p ) < sizeof( ssl->transform->randbytes ) )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
     ret = ssl_tls12_populate_transform( ssl->transform,
                   ssl->session->ciphersuite,
                   ssl->session->master,
@@ -6339,7 +3524,7 @@
                   ssl );
     if( ret != 0 )
         return( ret );
-
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
     p += sizeof( ssl->transform->randbytes );
 
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
@@ -6928,7 +4113,12 @@
             conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3;
             conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */
             conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_TLS1_3)
+            /* Hybrid TLS 1.2/1.3 is not supported yet */
+            conf->max_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3;
+#else
             conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_SSL_PROTO_TLS1_3 */
 
             conf->ciphersuite_list = ssl_preset_suiteb_ciphersuites;
 
@@ -6967,7 +4157,12 @@
                                     MBEDTLS_SSL_MIN_MINOR_VERSION :
                                     MBEDTLS_SSL_MIN_VALID_MINOR_VERSION;
             conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_TLS1_3)
+            /* Hybrid TLS 1.2/1.3 is not supported yet */
+            conf->max_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3;
+#else
             conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_SSL_PROTO_TLS1_3 */
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
             if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
@@ -7088,57 +4283,6 @@
 }
 #endif /* MBEDTLS_PK_C && ( MBEDTLS_RSA_C || MBEDTLS_ECDSA_C ) */
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
-    defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
-
-/* Find an entry in a signature-hash set matching a given hash algorithm. */
-mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set,
-                                                 mbedtls_pk_type_t sig_alg )
-{
-    switch( sig_alg )
-    {
-        case MBEDTLS_PK_RSA:
-            return( set->rsa );
-        case MBEDTLS_PK_ECDSA:
-            return( set->ecdsa );
-        default:
-            return( MBEDTLS_MD_NONE );
-    }
-}
-
-/* Add a signature-hash-pair to a signature-hash set */
-void mbedtls_ssl_sig_hash_set_add( mbedtls_ssl_sig_hash_set_t *set,
-                                   mbedtls_pk_type_t sig_alg,
-                                   mbedtls_md_type_t md_alg )
-{
-    switch( sig_alg )
-    {
-        case MBEDTLS_PK_RSA:
-            if( set->rsa == MBEDTLS_MD_NONE )
-                set->rsa = md_alg;
-            break;
-
-        case MBEDTLS_PK_ECDSA:
-            if( set->ecdsa == MBEDTLS_MD_NONE )
-                set->ecdsa = md_alg;
-            break;
-
-        default:
-            break;
-    }
-}
-
-/* Allow exactly one hash algorithm for each signature. */
-void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set,
-                                          mbedtls_md_type_t md_alg )
-{
-    set->rsa   = md_alg;
-    set->ecdsa = md_alg;
-}
-
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2) &&
-          MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
-
 /*
  * Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX
  */
@@ -7211,18 +4355,16 @@
     }
 }
 
-#if defined(MBEDTLS_ECP_C)
 /*
  * Check if a curve proposed by the peer is in our list.
  * Return 0 if we're willing to use it, -1 otherwise.
  */
-int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id )
+int mbedtls_ssl_check_curve_tls_id( const mbedtls_ssl_context *ssl, uint16_t tls_id )
 {
     const uint16_t *group_list = mbedtls_ssl_get_groups( ssl );
 
     if( group_list == NULL )
         return( -1 );
-    uint16_t tls_id = mbedtls_ecp_curve_info_from_grp_id(grp_id)->tls_id;
 
     for( ; *group_list != 0; group_list++ )
     {
@@ -7232,6 +4374,16 @@
 
     return( -1 );
 }
+
+#if defined(MBEDTLS_ECP_C)
+/*
+ * Same as mbedtls_ssl_check_curve_tls_id() but with a mbedtls_ecp_group_id.
+ */
+int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id )
+{
+    uint16_t tls_id = mbedtls_ecp_curve_info_from_grp_id( grp_id )->tls_id;
+    return mbedtls_ssl_check_curve_tls_id( ssl, tls_id );
+}
 #endif /* MBEDTLS_ECP_C */
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
@@ -7339,131 +4491,6 @@
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 }
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
-                                            unsigned char *hash, size_t *hashlen,
-                                            unsigned char *data, size_t data_len,
-                                            mbedtls_md_type_t md_alg )
-{
-    psa_status_t status;
-    psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT;
-    psa_algorithm_t hash_alg = mbedtls_psa_translate_md( md_alg );
-
-    MBEDTLS_SSL_DEBUG_MSG( 3, ( "Perform PSA-based computation of digest of ServerKeyExchange" ) );
-
-    if( ( status = psa_hash_setup( &hash_operation,
-                                   hash_alg ) ) != PSA_SUCCESS )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_setup", status );
-        goto exit;
-    }
-
-    if( ( status = psa_hash_update( &hash_operation, ssl->handshake->randbytes,
-                                    64 ) ) != PSA_SUCCESS )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_update", status );
-        goto exit;
-    }
-
-    if( ( status = psa_hash_update( &hash_operation,
-                                    data, data_len ) ) != PSA_SUCCESS )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_update", status );
-        goto exit;
-    }
-
-    if( ( status = psa_hash_finish( &hash_operation, hash, PSA_HASH_MAX_SIZE,
-                                    hashlen ) ) != PSA_SUCCESS )
-    {
-         MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_finish", status );
-         goto exit;
-    }
-
-exit:
-    if( status != PSA_SUCCESS )
-    {
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
-        switch( status )
-        {
-            case PSA_ERROR_NOT_SUPPORTED:
-                return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE );
-            case PSA_ERROR_BAD_STATE: /* Intentional fallthrough */
-            case PSA_ERROR_BUFFER_TOO_SMALL:
-                return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
-            case PSA_ERROR_INSUFFICIENT_MEMORY:
-                return( MBEDTLS_ERR_MD_ALLOC_FAILED );
-            default:
-                return( MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED );
-        }
-    }
-    return( 0 );
-}
-
-#else
-
-int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
-                                            unsigned char *hash, size_t *hashlen,
-                                            unsigned char *data, size_t data_len,
-                                            mbedtls_md_type_t md_alg )
-{
-    int ret = 0;
-    mbedtls_md_context_t ctx;
-    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
-    *hashlen = mbedtls_md_get_size( md_info );
-
-    MBEDTLS_SSL_DEBUG_MSG( 3, ( "Perform mbedtls-based computation of digest of ServerKeyExchange" ) );
-
-    mbedtls_md_init( &ctx );
-
-    /*
-     * digitally-signed struct {
-     *     opaque client_random[32];
-     *     opaque server_random[32];
-     *     ServerDHParams params;
-     * };
-     */
-    if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
-        goto exit;
-    }
-    if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_starts", ret );
-        goto exit;
-    }
-    if( ( ret = mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 ) ) != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret );
-        goto exit;
-    }
-    if( ( ret = mbedtls_md_update( &ctx, data, data_len ) ) != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret );
-        goto exit;
-    }
-    if( ( ret = mbedtls_md_finish( &ctx, hash ) ) != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_finish", ret );
-        goto exit;
-    }
-
-exit:
-    mbedtls_md_free( &ctx );
-
-    if( ret != 0 )
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
-
-    return( ret );
-}
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
 int mbedtls_ssl_get_handshake_transcript( mbedtls_ssl_context *ssl,
                                           const mbedtls_md_type_t md,
@@ -7471,12 +4498,40 @@
                                           size_t dst_len,
                                           size_t *olen )
 {
-    ((void) ssl);
-    ((void) md);
-    ((void) dst);
-    ((void) dst_len);
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_hash_operation_t *hash_operation_to_clone;
+    psa_hash_operation_t hash_operation = psa_hash_operation_init();
+
     *olen = 0;
-    return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE);
+
+    switch( md )
+    {
+#if defined(MBEDTLS_SHA384_C)
+    case MBEDTLS_MD_SHA384:
+        hash_operation_to_clone = &ssl->handshake->fin_sha384_psa;
+        break;
+#endif
+
+#if defined(MBEDTLS_SHA256_C)
+    case MBEDTLS_MD_SHA256:
+        hash_operation_to_clone = &ssl->handshake->fin_sha256_psa;
+        break;
+#endif
+
+    default:
+        goto exit;
+    }
+
+    status = psa_hash_clone( hash_operation_to_clone, &hash_operation );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    status = psa_hash_finish( &hash_operation, dst, dst_len, olen );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+exit:
+    return( psa_ssl_status_to_mbedtls( status ) );
 }
 #else /* MBEDTLS_USE_PSA_CRYPTO */
 
@@ -7796,4 +4851,3086 @@
 }
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+int mbedtls_ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
+                                    unsigned char *buf,
+                                    const unsigned char *end,
+                                    size_t *olen )
+{
+    unsigned char *p = buf;
+    size_t hostname_len;
+
+    *olen = 0;
+
+    if( ssl->hostname == NULL )
+        return( 0 );
+
+    MBEDTLS_SSL_DEBUG_MSG( 3,
+        ( "client hello, adding server name extension: %s",
+          ssl->hostname ) );
+
+    hostname_len = strlen( ssl->hostname );
+
+    MBEDTLS_SSL_CHK_BUF_PTR( p, end, hostname_len + 9 );
+
+    /*
+     * Sect. 3, RFC 6066 (TLS Extensions Definitions)
+     *
+     * In order to provide any of the server names, clients MAY include an
+     * extension of type "server_name" in the (extended) client hello. The
+     * "extension_data" field of this extension SHALL contain
+     * "ServerNameList" where:
+     *
+     * struct {
+     *     NameType name_type;
+     *     select (name_type) {
+     *         case host_name: HostName;
+     *     } name;
+     * } ServerName;
+     *
+     * enum {
+     *     host_name(0), (255)
+     * } NameType;
+     *
+     * opaque HostName<1..2^16-1>;
+     *
+     * struct {
+     *     ServerName server_name_list<1..2^16-1>
+     * } ServerNameList;
+     *
+     */
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SERVERNAME, p, 0 );
+    p += 2;
+
+    MBEDTLS_PUT_UINT16_BE( hostname_len + 5, p, 0 );
+    p += 2;
+
+    MBEDTLS_PUT_UINT16_BE( hostname_len + 3, p, 0 );
+    p += 2;
+
+    *p++ = MBEDTLS_BYTE_0( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME );
+
+    MBEDTLS_PUT_UINT16_BE( hostname_len, p, 0 );
+    p += 2;
+
+    memcpy( p, ssl->hostname, hostname_len );
+
+    *olen = hostname_len + 9;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+
+static psa_status_t setup_psa_key_derivation( psa_key_derivation_operation_t* derivation,
+                                              mbedtls_svc_key_id_t key,
+                                              psa_algorithm_t alg,
+                                              const unsigned char* seed, size_t seed_length,
+                                              const unsigned char* label, size_t label_length,
+                                              size_t capacity )
+{
+    psa_status_t status;
+
+    status = psa_key_derivation_setup( derivation, alg );
+    if( status != PSA_SUCCESS )
+        return( status );
+
+    if( PSA_ALG_IS_TLS12_PRF( alg ) || PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
+    {
+        status = psa_key_derivation_input_bytes( derivation,
+                                                 PSA_KEY_DERIVATION_INPUT_SEED,
+                                                 seed, seed_length );
+        if( status != PSA_SUCCESS )
+            return( status );
+
+        if( mbedtls_svc_key_id_is_null( key ) )
+        {
+            status = psa_key_derivation_input_bytes(
+                derivation, PSA_KEY_DERIVATION_INPUT_SECRET,
+                NULL, 0 );
+        }
+        else
+        {
+            status = psa_key_derivation_input_key(
+                derivation, PSA_KEY_DERIVATION_INPUT_SECRET, key );
+        }
+        if( status != PSA_SUCCESS )
+            return( status );
+
+        status = psa_key_derivation_input_bytes( derivation,
+                                                 PSA_KEY_DERIVATION_INPUT_LABEL,
+                                                 label, label_length );
+        if( status != PSA_SUCCESS )
+            return( status );
+    }
+    else
+    {
+        return( PSA_ERROR_NOT_SUPPORTED );
+    }
+
+    status = psa_key_derivation_set_capacity( derivation, capacity );
+    if( status != PSA_SUCCESS )
+        return( status );
+
+    return( PSA_SUCCESS );
+}
+
+static int tls_prf_generic( mbedtls_md_type_t md_type,
+                            const unsigned char *secret, size_t slen,
+                            const char *label,
+                            const unsigned char *random, size_t rlen,
+                            unsigned char *dstbuf, size_t dlen )
+{
+    psa_status_t status;
+    psa_algorithm_t alg;
+    mbedtls_svc_key_id_t master_key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_key_derivation_operation_t derivation =
+        PSA_KEY_DERIVATION_OPERATION_INIT;
+
+    if( md_type == MBEDTLS_MD_SHA384 )
+        alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384);
+    else
+        alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256);
+
+    /* Normally a "secret" should be long enough to be impossible to
+     * find by brute force, and in particular should not be empty. But
+     * this PRF is also used to derive an IV, in particular in EAP-TLS,
+     * and for this use case it makes sense to have a 0-length "secret".
+     * Since the key API doesn't allow importing a key of length 0,
+     * keep master_key=0, which setup_psa_key_derivation() understands
+     * to mean a 0-length "secret" input. */
+    if( slen != 0 )
+    {
+        psa_key_attributes_t key_attributes = psa_key_attributes_init();
+        psa_set_key_usage_flags( &key_attributes, PSA_KEY_USAGE_DERIVE );
+        psa_set_key_algorithm( &key_attributes, alg );
+        psa_set_key_type( &key_attributes, PSA_KEY_TYPE_DERIVE );
+
+        status = psa_import_key( &key_attributes, secret, slen, &master_key );
+        if( status != PSA_SUCCESS )
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+    }
+
+    status = setup_psa_key_derivation( &derivation,
+                                       master_key, alg,
+                                       random, rlen,
+                                       (unsigned char const *) label,
+                                       (size_t) strlen( label ),
+                                       dlen );
+    if( status != PSA_SUCCESS )
+    {
+        psa_key_derivation_abort( &derivation );
+        psa_destroy_key( master_key );
+        return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+    }
+
+    status = psa_key_derivation_output_bytes( &derivation, dstbuf, dlen );
+    if( status != PSA_SUCCESS )
+    {
+        psa_key_derivation_abort( &derivation );
+        psa_destroy_key( master_key );
+        return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+    }
+
+    status = psa_key_derivation_abort( &derivation );
+    if( status != PSA_SUCCESS )
+    {
+        psa_destroy_key( master_key );
+        return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+    }
+
+    if( ! mbedtls_svc_key_id_is_null( master_key ) )
+        status = psa_destroy_key( master_key );
+    if( status != PSA_SUCCESS )
+        return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+
+    return( 0 );
+}
+
+#else /* MBEDTLS_USE_PSA_CRYPTO */
+
+static int tls_prf_generic( mbedtls_md_type_t md_type,
+                            const unsigned char *secret, size_t slen,
+                            const char *label,
+                            const unsigned char *random, size_t rlen,
+                            unsigned char *dstbuf, size_t dlen )
+{
+    size_t nb;
+    size_t i, j, k, md_len;
+    unsigned char *tmp;
+    size_t tmp_len = 0;
+    unsigned char h_i[MBEDTLS_MD_MAX_SIZE];
+    const mbedtls_md_info_t *md_info;
+    mbedtls_md_context_t md_ctx;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+    mbedtls_md_init( &md_ctx );
+
+    if( ( md_info = mbedtls_md_info_from_type( md_type ) ) == NULL )
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+
+    md_len = mbedtls_md_get_size( md_info );
+
+    tmp_len = md_len + strlen( label ) + rlen;
+    tmp = mbedtls_calloc( 1, tmp_len );
+    if( tmp == NULL )
+    {
+        ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
+        goto exit;
+    }
+
+    nb = strlen( label );
+    memcpy( tmp + md_len, label, nb );
+    memcpy( tmp + md_len + nb, random, rlen );
+    nb += rlen;
+
+    /*
+     * Compute P_<hash>(secret, label + random)[0..dlen]
+     */
+    if ( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
+        goto exit;
+
+    ret = mbedtls_md_hmac_starts( &md_ctx, secret, slen );
+    if( ret != 0 )
+        goto exit;
+    ret = mbedtls_md_hmac_update( &md_ctx, tmp + md_len, nb );
+    if( ret != 0 )
+        goto exit;
+    ret = mbedtls_md_hmac_finish( &md_ctx, tmp );
+    if( ret != 0 )
+        goto exit;
+
+    for( i = 0; i < dlen; i += md_len )
+    {
+        ret = mbedtls_md_hmac_reset ( &md_ctx );
+        if( ret != 0 )
+            goto exit;
+        ret = mbedtls_md_hmac_update( &md_ctx, tmp, md_len + nb );
+        if( ret != 0 )
+            goto exit;
+        ret = mbedtls_md_hmac_finish( &md_ctx, h_i );
+        if( ret != 0 )
+            goto exit;
+
+        ret = mbedtls_md_hmac_reset ( &md_ctx );
+        if( ret != 0 )
+            goto exit;
+        ret = mbedtls_md_hmac_update( &md_ctx, tmp, md_len );
+        if( ret != 0 )
+            goto exit;
+        ret = mbedtls_md_hmac_finish( &md_ctx, tmp );
+        if( ret != 0 )
+            goto exit;
+
+        k = ( i + md_len > dlen ) ? dlen % md_len : md_len;
+
+        for( j = 0; j < k; j++ )
+            dstbuf[i + j]  = h_i[j];
+    }
+
+exit:
+    mbedtls_md_free( &md_ctx );
+
+    mbedtls_platform_zeroize( tmp, tmp_len );
+    mbedtls_platform_zeroize( h_i, sizeof( h_i ) );
+
+    mbedtls_free( tmp );
+
+    return( ret );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#if defined(MBEDTLS_SHA256_C)
+static int tls_prf_sha256( const unsigned char *secret, size_t slen,
+                           const char *label,
+                           const unsigned char *random, size_t rlen,
+                           unsigned char *dstbuf, size_t dlen )
+{
+    return( tls_prf_generic( MBEDTLS_MD_SHA256, secret, slen,
+                             label, random, rlen, dstbuf, dlen ) );
+}
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA384_C)
+static int tls_prf_sha384( const unsigned char *secret, size_t slen,
+                           const char *label,
+                           const unsigned char *random, size_t rlen,
+                           unsigned char *dstbuf, size_t dlen )
+{
+    return( tls_prf_generic( MBEDTLS_MD_SHA384, secret, slen,
+                             label, random, rlen, dstbuf, dlen ) );
+}
+#endif /* MBEDTLS_SHA384_C */
+
+/*
+ * Set appropriate PRF function and other SSL / TLS1.2 functions
+ *
+ * Inputs:
+ * - SSL/TLS minor version
+ * - hash associated with the ciphersuite (only used by TLS 1.2)
+ *
+ * Outputs:
+ * - the tls_prf, calc_verify and calc_finished members of handshake structure
+ */
+static int ssl_set_handshake_prfs( mbedtls_ssl_handshake_params *handshake,
+                                   int minor_ver,
+                                   mbedtls_md_type_t hash )
+{
+
+#if defined(MBEDTLS_SHA384_C)
+    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
+        hash == MBEDTLS_MD_SHA384 )
+    {
+        handshake->tls_prf = tls_prf_sha384;
+        handshake->calc_verify = ssl_calc_verify_tls_sha384;
+        handshake->calc_finished = ssl_calc_finished_tls_sha384;
+    }
+    else
+#endif
+#if defined(MBEDTLS_SHA256_C)
+    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+    {
+        handshake->tls_prf = tls_prf_sha256;
+        handshake->calc_verify = ssl_calc_verify_tls_sha256;
+        handshake->calc_finished = ssl_calc_finished_tls_sha256;
+    }
+    else
+#endif
+    {
+        (void) hash;
+        (void) minor_ver;
+        (void) handshake;
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) && \
+    defined(MBEDTLS_USE_PSA_CRYPTO)
+static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl )
+{
+    if( ssl->conf->f_psk != NULL )
+    {
+        /* If we've used a callback to select the PSK,
+         * the static configuration is irrelevant. */
+        if( ! mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) )
+            return( 1 );
+
+        return( 0 );
+    }
+
+    if( ! mbedtls_svc_key_id_is_null( ssl->conf->psk_opaque ) )
+        return( 1 );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO &&
+          MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
+
+/*
+ * Compute master secret if needed
+ *
+ * Parameters:
+ * [in/out] handshake
+ *          [in] resume, premaster, extended_ms, calc_verify, tls_prf
+ *               (PSA-PSK) ciphersuite_info, psk_opaque
+ *          [out] premaster (cleared)
+ * [out] master
+ * [in] ssl: optionally used for debugging, EMS and PSA-PSK
+ *      debug: conf->f_dbg, conf->p_dbg
+ *      EMS: passed to calc_verify (debug + session_negotiate)
+ *      PSA-PSA: minor_ver, conf
+ */
+static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake,
+                               unsigned char *master,
+                               const mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+    /* cf. RFC 5246, Section 8.1:
+     * "The master secret is always exactly 48 bytes in length." */
+    size_t const master_secret_len = 48;
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+    unsigned char session_hash[48];
+#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
+
+    /* The label for the KDF used for key expansion.
+     * This is either "master secret" or "extended master secret"
+     * depending on whether the Extended Master Secret extension
+     * is used. */
+    char const *lbl = "master secret";
+
+    /* The salt for the KDF used for key expansion.
+     * - If the Extended Master Secret extension is not used,
+     *   this is ClientHello.Random + ServerHello.Random
+     *   (see Sect. 8.1 in RFC 5246).
+     * - If the Extended Master Secret extension is used,
+     *   this is the transcript of the handshake so far.
+     *   (see Sect. 4 in RFC 7627). */
+    unsigned char const *salt = handshake->randbytes;
+    size_t salt_len = 64;
+
+#if !defined(MBEDTLS_DEBUG_C) &&                    \
+    !defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \
+    !(defined(MBEDTLS_USE_PSA_CRYPTO) &&            \
+      defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED))
+    ssl = NULL; /* make sure we don't use it except for those cases */
+    (void) ssl;
+#endif
+
+    if( handshake->resume != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) );
+        return( 0 );
+    }
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+    if( handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED )
+    {
+        lbl  = "extended master secret";
+        salt = session_hash;
+        handshake->calc_verify( ssl, session_hash, &salt_len );
+
+        MBEDTLS_SSL_DEBUG_BUF( 3, "session hash for extended master secret",
+                                  session_hash, salt_len );
+    }
+#endif /* MBEDTLS_SSL_EXTENDED_MS_ENABLED */
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO) &&          \
+    defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
+    if( handshake->ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK &&
+        ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
+        ssl_use_opaque_psk( ssl ) == 1 )
+    {
+        /* Perform PSK-to-MS expansion in a single step. */
+        psa_status_t status;
+        psa_algorithm_t alg;
+        mbedtls_svc_key_id_t psk;
+        psa_key_derivation_operation_t derivation =
+            PSA_KEY_DERIVATION_OPERATION_INIT;
+        mbedtls_md_type_t hash_alg = handshake->ciphersuite_info->mac;
+
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "perform PSA-based PSK-to-MS expansion" ) );
+
+        psk = mbedtls_ssl_get_opaque_psk( ssl );
+
+        if( hash_alg == MBEDTLS_MD_SHA384 )
+            alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384);
+        else
+            alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256);
+
+        status = setup_psa_key_derivation( &derivation, psk, alg,
+                                           salt, salt_len,
+                                           (unsigned char const *) lbl,
+                                           (size_t) strlen( lbl ),
+                                           master_secret_len );
+        if( status != PSA_SUCCESS )
+        {
+            psa_key_derivation_abort( &derivation );
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+        }
+
+        status = psa_key_derivation_output_bytes( &derivation,
+                                                  master,
+                                                  master_secret_len );
+        if( status != PSA_SUCCESS )
+        {
+            psa_key_derivation_abort( &derivation );
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+        }
+
+        status = psa_key_derivation_abort( &derivation );
+        if( status != PSA_SUCCESS )
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+    }
+    else
+#endif
+    {
+        ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
+                                  lbl, salt, salt_len,
+                                  master,
+                                  master_secret_len );
+        if( ret != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
+            return( ret );
+        }
+
+        MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret",
+                               handshake->premaster,
+                               handshake->pmslen );
+
+        mbedtls_platform_zeroize( handshake->premaster,
+                                  sizeof(handshake->premaster) );
+    }
+
+    return( 0 );
+}
+
+int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    const mbedtls_ssl_ciphersuite_t * const ciphersuite_info =
+        ssl->handshake->ciphersuite_info;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) );
+
+    /* Set PRF, calc_verify and calc_finished function pointers */
+    ret = ssl_set_handshake_prfs( ssl->handshake,
+                                  ssl->minor_ver,
+                                  ciphersuite_info->mac );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_set_handshake_prfs", ret );
+        return( ret );
+    }
+
+    /* Compute master secret if needed */
+    ret = ssl_compute_master( ssl->handshake,
+                              ssl->session_negotiate->master,
+                              ssl );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compute_master", ret );
+        return( ret );
+    }
+
+    /* Swap the client and server random values:
+     * - MS derivation wanted client+server (RFC 5246 8.1)
+     * - key derivation wants server+client (RFC 5246 6.3) */
+    {
+        unsigned char tmp[64];
+        memcpy( tmp, ssl->handshake->randbytes, 64 );
+        memcpy( ssl->handshake->randbytes, tmp + 32, 32 );
+        memcpy( ssl->handshake->randbytes + 32, tmp, 32 );
+        mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+    }
+
+    /* Populate transform structure */
+    ret = ssl_tls12_populate_transform( ssl->transform_negotiate,
+                                        ssl->session_negotiate->ciphersuite,
+                                        ssl->session_negotiate->master,
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) && \
+    defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+                                        ssl->session_negotiate->encrypt_then_mac,
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC &&
+          MBEDTLS_SSL_SOME_SUITES_USE_MAC */
+                                        ssl->handshake->tls_prf,
+                                        ssl->handshake->randbytes,
+                                        ssl->minor_ver,
+                                        ssl->conf->endpoint,
+                                        ssl );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls12_populate_transform", ret );
+        return( ret );
+    }
+
+    /* We no longer need Server/ClientHello.random values */
+    mbedtls_platform_zeroize( ssl->handshake->randbytes,
+                      sizeof( ssl->handshake->randbytes ) );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= derive keys" ) );
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_SHA256_C)
+void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *ssl,
+                                 unsigned char *hash,
+                                 size_t *hlen )
+{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    size_t hash_size;
+    psa_status_t status;
+    psa_hash_operation_t sha256_psa = psa_hash_operation_init();
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> PSA calc verify sha256" ) );
+    status = psa_hash_clone( &ssl->handshake->fin_sha256_psa, &sha256_psa );
+    if( status != PSA_SUCCESS )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
+        return;
+    }
+
+    status = psa_hash_finish( &sha256_psa, hash, 32, &hash_size );
+    if( status != PSA_SUCCESS )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
+        return;
+    }
+
+    *hlen = 32;
+    MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated verify result", hash, *hlen );
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= PSA calc verify" ) );
+#else
+    mbedtls_sha256_context sha256;
+
+    mbedtls_sha256_init( &sha256 );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha256" ) );
+
+    mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
+    mbedtls_sha256_finish( &sha256, hash );
+
+    *hlen = 32;
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen );
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
+
+    mbedtls_sha256_free( &sha256 );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+    return;
+}
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA384_C)
+void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *ssl,
+                                 unsigned char *hash,
+                                 size_t *hlen )
+{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    size_t hash_size;
+    psa_status_t status;
+    psa_hash_operation_t sha384_psa = psa_hash_operation_init();
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> PSA calc verify sha384" ) );
+    status = psa_hash_clone( &ssl->handshake->fin_sha384_psa, &sha384_psa );
+    if( status != PSA_SUCCESS )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
+        return;
+    }
+
+    status = psa_hash_finish( &sha384_psa, hash, 48, &hash_size );
+    if( status != PSA_SUCCESS )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
+        return;
+    }
+
+    *hlen = 48;
+    MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated verify result", hash, *hlen );
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= PSA calc verify" ) );
+#else
+    mbedtls_sha512_context sha512;
+
+    mbedtls_sha512_init( &sha512 );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha384" ) );
+
+    mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
+    mbedtls_sha512_finish( &sha512, hash );
+
+    *hlen = 48;
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen );
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
+
+    mbedtls_sha512_free( &sha512 );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+    return;
+}
+#endif /* MBEDTLS_SHA384_C */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex )
+{
+    unsigned char *p = ssl->handshake->premaster;
+    unsigned char *end = p + sizeof( ssl->handshake->premaster );
+    const unsigned char *psk = NULL;
+    size_t psk_len = 0;
+
+    if( mbedtls_ssl_get_psk( ssl, &psk, &psk_len )
+            == MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED )
+    {
+        /*
+         * This should never happen because the existence of a PSK is always
+         * checked before calling this function
+         */
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    /*
+     * PMS = struct {
+     *     opaque other_secret<0..2^16-1>;
+     *     opaque psk<0..2^16-1>;
+     * };
+     * with "other_secret" depending on the particular key exchange
+     */
+#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
+    if( key_ex == MBEDTLS_KEY_EXCHANGE_PSK )
+    {
+        if( end - p < 2 )
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+        MBEDTLS_PUT_UINT16_BE( psk_len, p, 0 );
+        p += 2;
+
+        if( end < p || (size_t)( end - p ) < psk_len )
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+        memset( p, 0, psk_len );
+        p += psk_len;
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
+    if( key_ex == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
+    {
+        /*
+         * other_secret already set by the ClientKeyExchange message,
+         * and is 48 bytes long
+         */
+        if( end - p < 2 )
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+        *p++ = 0;
+        *p++ = 48;
+        p += 48;
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+    if( key_ex == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
+    {
+        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+        size_t len;
+
+        /* Write length only when we know the actual value */
+        if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
+                                      p + 2, end - ( p + 2 ), &len,
+                                      ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
+            return( ret );
+        }
+        MBEDTLS_PUT_UINT16_BE( len, p, 0 );
+        p += 2 + len;
+
+        MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K  );
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+    if( key_ex == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
+    {
+        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+        size_t zlen;
+
+        if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &zlen,
+                                       p + 2, end - ( p + 2 ),
+                                       ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
+            return( ret );
+        }
+
+        MBEDTLS_PUT_UINT16_BE( zlen, p, 0 );
+        p += 2 + zlen;
+
+        MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+                                MBEDTLS_DEBUG_ECDH_Z );
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    /* opaque psk<0..2^16-1>; */
+    if( end - p < 2 )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    MBEDTLS_PUT_UINT16_BE( psk_len, p, 0 );
+    p += 2;
+
+    if( end < p || (size_t)( end - p ) < psk_len )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    memcpy( p, psk, psk_len );
+    p += psk_len;
+
+    ssl->handshake->pmslen = p - ssl->handshake->premaster;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
+
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
+static int ssl_write_hello_request( mbedtls_ssl_context *ssl );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+int mbedtls_ssl_resend_hello_request( mbedtls_ssl_context *ssl )
+{
+    /* If renegotiation is not enforced, retransmit until we would reach max
+     * timeout if we were using the usual handshake doubling scheme */
+    if( ssl->conf->renego_max_records < 0 )
+    {
+        uint32_t ratio = ssl->conf->hs_timeout_max / ssl->conf->hs_timeout_min + 1;
+        unsigned char doublings = 1;
+
+        while( ratio != 0 )
+        {
+            ++doublings;
+            ratio >>= 1;
+        }
+
+        if( ++ssl->renego_records_seen > doublings )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "no longer retransmitting hello request" ) );
+            return( 0 );
+        }
+    }
+
+    return( ssl_write_hello_request( ssl ) );
+}
+#endif
+#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
+
+/*
+ * Handshake functions
+ */
+#if !defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+/* No certificate support -> dummy functions */
+int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
+{
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+        ssl->handshake->ciphersuite_info;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
+
+    if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
+        ssl->state++;
+        return( 0 );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+    return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+}
+
+int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
+{
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+        ssl->handshake->ciphersuite_info;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
+
+    if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
+        ssl->state++;
+        return( 0 );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+    return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+}
+
+#else /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+/* Some certificate support -> implement write and parse */
+
+int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+    size_t i, n;
+    const mbedtls_x509_crt *crt;
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+        ssl->handshake->ciphersuite_info;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
+
+    if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
+        ssl->state++;
+        return( 0 );
+    }
+
+#if defined(MBEDTLS_SSL_CLI_C)
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+    {
+        if( ssl->handshake->client_auth == 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
+            ssl->state++;
+            return( 0 );
+        }
+    }
+#endif /* MBEDTLS_SSL_CLI_C */
+#if defined(MBEDTLS_SSL_SRV_C)
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
+    {
+        if( mbedtls_ssl_own_cert( ssl ) == NULL )
+        {
+            /* Should never happen because we shouldn't have picked the
+             * ciphersuite if we don't have a certificate. */
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+    }
+#endif
+
+    MBEDTLS_SSL_DEBUG_CRT( 3, "own certificate", mbedtls_ssl_own_cert( ssl ) );
+
+    /*
+     *     0  .  0    handshake type
+     *     1  .  3    handshake length
+     *     4  .  6    length of all certs
+     *     7  .  9    length of cert. 1
+     *    10  . n-1   peer certificate
+     *     n  . n+2   length of cert. 2
+     *    n+3 . ...   upper level cert, etc.
+     */
+    i = 7;
+    crt = mbedtls_ssl_own_cert( ssl );
+
+    while( crt != NULL )
+    {
+        n = crt->raw.len;
+        if( n > MBEDTLS_SSL_OUT_CONTENT_LEN - 3 - i )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate too large, %" MBEDTLS_PRINTF_SIZET
+                                        " > %" MBEDTLS_PRINTF_SIZET,
+                           i + 3 + n, (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN ) );
+            return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+        }
+
+        ssl->out_msg[i    ] = MBEDTLS_BYTE_2( n );
+        ssl->out_msg[i + 1] = MBEDTLS_BYTE_1( n );
+        ssl->out_msg[i + 2] = MBEDTLS_BYTE_0( n );
+
+        i += 3; memcpy( ssl->out_msg + i, crt->raw.p, n );
+        i += n; crt = crt->next;
+    }
+
+    ssl->out_msg[4]  = MBEDTLS_BYTE_2( i - 7 );
+    ssl->out_msg[5]  = MBEDTLS_BYTE_1( i - 7 );
+    ssl->out_msg[6]  = MBEDTLS_BYTE_0( i - 7 );
+
+    ssl->out_msglen  = i;
+    ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
+    ssl->out_msg[0]  = MBEDTLS_SSL_HS_CERTIFICATE;
+
+    ssl->state++;
+
+    if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
+        return( ret );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate" ) );
+
+    return( ret );
+}
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
+
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl,
+                                         unsigned char *crt_buf,
+                                         size_t crt_buf_len )
+{
+    mbedtls_x509_crt const * const peer_crt = ssl->session->peer_cert;
+
+    if( peer_crt == NULL )
+        return( -1 );
+
+    if( peer_crt->raw.len != crt_buf_len )
+        return( -1 );
+
+    return( memcmp( peer_crt->raw.p, crt_buf, peer_crt->raw.len ) );
+}
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl,
+                                         unsigned char *crt_buf,
+                                         size_t crt_buf_len )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    unsigned char const * const peer_cert_digest =
+        ssl->session->peer_cert_digest;
+    mbedtls_md_type_t const peer_cert_digest_type =
+        ssl->session->peer_cert_digest_type;
+    mbedtls_md_info_t const * const digest_info =
+        mbedtls_md_info_from_type( peer_cert_digest_type );
+    unsigned char tmp_digest[MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN];
+    size_t digest_len;
+
+    if( peer_cert_digest == NULL || digest_info == NULL )
+        return( -1 );
+
+    digest_len = mbedtls_md_get_size( digest_info );
+    if( digest_len > MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN )
+        return( -1 );
+
+    ret = mbedtls_md( digest_info, crt_buf, crt_buf_len, tmp_digest );
+    if( ret != 0 )
+        return( -1 );
+
+    return( memcmp( tmp_digest, peer_cert_digest, digest_len ) );
+}
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
+
+/*
+ * Once the certificate message is read, parse it into a cert chain and
+ * perform basic checks, but leave actual verification to the caller
+ */
+static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl,
+                                        mbedtls_x509_crt *chain )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
+    int crt_cnt=0;
+#endif
+    size_t i, n;
+    uint8_t alert;
+
+    if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+    }
+
+    if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE  )
+    {
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+    }
+
+    if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 3 + 3 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
+    }
+
+    i = mbedtls_ssl_hs_hdr_len( ssl );
+
+    /*
+     * Same message structure as in mbedtls_ssl_write_certificate()
+     */
+    n = ( ssl->in_msg[i+1] << 8 ) | ssl->in_msg[i+2];
+
+    if( ssl->in_msg[i] != 0 ||
+        ssl->in_hslen != n + 3 + mbedtls_ssl_hs_hdr_len( ssl ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
+    }
+
+    /* Make &ssl->in_msg[i] point to the beginning of the CRT chain. */
+    i += 3;
+
+    /* Iterate through and parse the CRTs in the provided chain. */
+    while( i < ssl->in_hslen )
+    {
+        /* Check that there's room for the next CRT's length fields. */
+        if ( i + 3 > ssl->in_hslen ) {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
+            mbedtls_ssl_send_alert_message( ssl,
+                              MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                              MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
+        }
+        /* In theory, the CRT can be up to 2**24 Bytes, but we don't support
+         * anything beyond 2**16 ~ 64K. */
+        if( ssl->in_msg[i] != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
+            mbedtls_ssl_send_alert_message( ssl,
+                            MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                            MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT );
+            return( MBEDTLS_ERR_SSL_BAD_CERTIFICATE );
+        }
+
+        /* Read length of the next CRT in the chain. */
+        n = ( (unsigned int) ssl->in_msg[i + 1] << 8 )
+            | (unsigned int) ssl->in_msg[i + 2];
+        i += 3;
+
+        if( n < 128 || i + n > ssl->in_hslen )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
+            mbedtls_ssl_send_alert_message( ssl,
+                                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
+        }
+
+        /* Check if we're handling the first CRT in the chain. */
+#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
+        if( crt_cnt++ == 0 &&
+            ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
+            ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
+        {
+            /* During client-side renegotiation, check that the server's
+             * end-CRTs hasn't changed compared to the initial handshake,
+             * mitigating the triple handshake attack. On success, reuse
+             * the original end-CRT instead of parsing it again. */
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "Check that peer CRT hasn't changed during renegotiation" ) );
+            if( ssl_check_peer_crt_unchanged( ssl,
+                                              &ssl->in_msg[i],
+                                              n ) != 0 )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) );
+                mbedtls_ssl_send_alert_message( ssl,
+                                                MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                                MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
+                return( MBEDTLS_ERR_SSL_BAD_CERTIFICATE );
+            }
+
+            /* Now we can safely free the original chain. */
+            ssl_clear_peer_cert( ssl->session );
+        }
+#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
+
+        /* Parse the next certificate in the chain. */
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+        ret = mbedtls_x509_crt_parse_der( chain, ssl->in_msg + i, n );
+#else
+        /* If we don't need to store the CRT chain permanently, parse
+         * it in-place from the input buffer instead of making a copy. */
+        ret = mbedtls_x509_crt_parse_der_nocopy( chain, ssl->in_msg + i, n );
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+        switch( ret )
+        {
+            case 0: /*ok*/
+            case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND:
+                /* Ignore certificate with an unknown algorithm: maybe a
+                   prior certificate was already trusted. */
+                break;
+
+            case MBEDTLS_ERR_X509_ALLOC_FAILED:
+                alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR;
+                goto crt_parse_der_failed;
+
+            case MBEDTLS_ERR_X509_UNKNOWN_VERSION:
+                alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+                goto crt_parse_der_failed;
+
+            default:
+                alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
+            crt_parse_der_failed:
+                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert );
+                MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret );
+                return( ret );
+        }
+
+        i += n;
+    }
+
+    MBEDTLS_SSL_DEBUG_CRT( 3, "peer certificate", chain );
+    return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_SRV_C)
+static int ssl_srv_check_client_no_crt_notification( mbedtls_ssl_context *ssl )
+{
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+        return( -1 );
+
+    if( ssl->in_hslen   == 3 + mbedtls_ssl_hs_hdr_len( ssl ) &&
+        ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE    &&
+        ssl->in_msg[0]  == MBEDTLS_SSL_HS_CERTIFICATE   &&
+        memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), "\0\0\0", 3 ) == 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) );
+        return( 0 );
+    }
+    return( -1 );
+}
+#endif /* MBEDTLS_SSL_SRV_C */
+
+/* Check if a certificate message is expected.
+ * Return either
+ * - SSL_CERTIFICATE_EXPECTED, or
+ * - SSL_CERTIFICATE_SKIP
+ * indicating whether a Certificate message is expected or not.
+ */
+#define SSL_CERTIFICATE_EXPECTED 0
+#define SSL_CERTIFICATE_SKIP     1
+static int ssl_parse_certificate_coordinate( mbedtls_ssl_context *ssl,
+                                             int authmode )
+{
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+        ssl->handshake->ciphersuite_info;
+
+    if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
+        return( SSL_CERTIFICATE_SKIP );
+
+#if defined(MBEDTLS_SSL_SRV_C)
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
+    {
+        if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
+            return( SSL_CERTIFICATE_SKIP );
+
+        if( authmode == MBEDTLS_SSL_VERIFY_NONE )
+        {
+            ssl->session_negotiate->verify_result =
+                MBEDTLS_X509_BADCERT_SKIP_VERIFY;
+            return( SSL_CERTIFICATE_SKIP );
+        }
+    }
+#else
+    ((void) authmode);
+#endif /* MBEDTLS_SSL_SRV_C */
+
+    return( SSL_CERTIFICATE_EXPECTED );
+}
+
+static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl,
+                                         int authmode,
+                                         mbedtls_x509_crt *chain,
+                                         void *rs_ctx )
+{
+    int ret = 0;
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+        ssl->handshake->ciphersuite_info;
+    int have_ca_chain = 0;
+
+    int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *);
+    void *p_vrfy;
+
+    if( authmode == MBEDTLS_SSL_VERIFY_NONE )
+        return( 0 );
+
+    if( ssl->f_vrfy != NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use context-specific verification callback" ) );
+        f_vrfy = ssl->f_vrfy;
+        p_vrfy = ssl->p_vrfy;
+    }
+    else
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use configuration-specific verification callback" ) );
+        f_vrfy = ssl->conf->f_vrfy;
+        p_vrfy = ssl->conf->p_vrfy;
+    }
+
+    /*
+     * Main check: verify certificate
+     */
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+    if( ssl->conf->f_ca_cb != NULL )
+    {
+        ((void) rs_ctx);
+        have_ca_chain = 1;
+
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "use CA callback for X.509 CRT verification" ) );
+        ret = mbedtls_x509_crt_verify_with_ca_cb(
+            chain,
+            ssl->conf->f_ca_cb,
+            ssl->conf->p_ca_cb,
+            ssl->conf->cert_profile,
+            ssl->hostname,
+            &ssl->session_negotiate->verify_result,
+            f_vrfy, p_vrfy );
+    }
+    else
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
+    {
+        mbedtls_x509_crt *ca_chain;
+        mbedtls_x509_crl *ca_crl;
+
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+        if( ssl->handshake->sni_ca_chain != NULL )
+        {
+            ca_chain = ssl->handshake->sni_ca_chain;
+            ca_crl   = ssl->handshake->sni_ca_crl;
+        }
+        else
+#endif
+        {
+            ca_chain = ssl->conf->ca_chain;
+            ca_crl   = ssl->conf->ca_crl;
+        }
+
+        if( ca_chain != NULL )
+            have_ca_chain = 1;
+
+        ret = mbedtls_x509_crt_verify_restartable(
+            chain,
+            ca_chain, ca_crl,
+            ssl->conf->cert_profile,
+            ssl->hostname,
+            &ssl->session_negotiate->verify_result,
+            f_vrfy, p_vrfy, rs_ctx );
+    }
+
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", ret );
+    }
+
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
+    if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
+        return( MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS );
+#endif
+
+    /*
+     * Secondary checks: always done, but change 'ret' only if it was 0
+     */
+
+#if defined(MBEDTLS_ECP_C)
+    {
+        const mbedtls_pk_context *pk = &chain->pk;
+
+        /* If certificate uses an EC key, make sure the curve is OK */
+        if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) &&
+            mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 )
+        {
+            ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY;
+
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) );
+            if( ret == 0 )
+                ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
+        }
+    }
+#endif /* MBEDTLS_ECP_C */
+
+    if( mbedtls_ssl_check_cert_usage( chain,
+                                      ciphersuite_info,
+                                      ! ssl->conf->endpoint,
+                                      &ssl->session_negotiate->verify_result ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) );
+        if( ret == 0 )
+            ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
+    }
+
+    /* mbedtls_x509_crt_verify_with_profile is supposed to report a
+     * verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED,
+     * with details encoded in the verification flags. All other kinds
+     * of error codes, including those from the user provided f_vrfy
+     * functions, are treated as fatal and lead to a failure of
+     * ssl_parse_certificate even if verification was optional. */
+    if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
+        ( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
+          ret == MBEDTLS_ERR_SSL_BAD_CERTIFICATE ) )
+    {
+        ret = 0;
+    }
+
+    if( have_ca_chain == 0 && authmode == MBEDTLS_SSL_VERIFY_REQUIRED )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) );
+        ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
+    }
+
+    if( ret != 0 )
+    {
+        uint8_t alert;
+
+        /* The certificate may have been rejected for several reasons.
+           Pick one and send the corresponding alert. Which alert to send
+           may be a subject of debate in some cases. */
+        if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER )
+            alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED;
+        else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH )
+            alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
+        else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE )
+            alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+        else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE )
+            alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+        else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NS_CERT_TYPE )
+            alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+        else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK )
+            alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+        else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY )
+            alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+        else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED )
+            alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED;
+        else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED )
+            alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED;
+        else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED )
+            alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA;
+        else
+            alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN;
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        alert );
+    }
+
+#if defined(MBEDTLS_DEBUG_C)
+    if( ssl->session_negotiate->verify_result != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "! Certificate verification flags %08x",
+                                    (unsigned int) ssl->session_negotiate->verify_result ) );
+    }
+    else
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "Certificate verification flags clear" ) );
+    }
+#endif /* MBEDTLS_DEBUG_C */
+
+    return( ret );
+}
+
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+static int ssl_remember_peer_crt_digest( mbedtls_ssl_context *ssl,
+                                         unsigned char *start, size_t len )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    /* Remember digest of the peer's end-CRT. */
+    ssl->session_negotiate->peer_cert_digest =
+        mbedtls_calloc( 1, MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN );
+    if( ssl->session_negotiate->peer_cert_digest == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
+                                    MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN ) );
+        mbedtls_ssl_send_alert_message( ssl,
+                                        MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+
+        return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+    }
+
+    ret = mbedtls_md( mbedtls_md_info_from_type(
+                          MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE ),
+                      start, len,
+                      ssl->session_negotiate->peer_cert_digest );
+
+    ssl->session_negotiate->peer_cert_digest_type =
+        MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE;
+    ssl->session_negotiate->peer_cert_digest_len =
+        MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN;
+
+    return( ret );
+}
+
+static int ssl_remember_peer_pubkey( mbedtls_ssl_context *ssl,
+                                     unsigned char *start, size_t len )
+{
+    unsigned char *end = start + len;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+    /* Make a copy of the peer's raw public key. */
+    mbedtls_pk_init( &ssl->handshake->peer_pubkey );
+    ret = mbedtls_pk_parse_subpubkey( &start, end,
+                                      &ssl->handshake->peer_pubkey );
+    if( ret != 0 )
+    {
+        /* We should have parsed the public key before. */
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    return( 0 );
+}
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+
+int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
+{
+    int ret = 0;
+    int crt_expected;
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+    const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET
+                       ? ssl->handshake->sni_authmode
+                       : ssl->conf->authmode;
+#else
+    const int authmode = ssl->conf->authmode;
+#endif
+    void *rs_ctx = NULL;
+    mbedtls_x509_crt *chain = NULL;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
+
+    crt_expected = ssl_parse_certificate_coordinate( ssl, authmode );
+    if( crt_expected == SSL_CERTIFICATE_SKIP )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
+        goto exit;
+    }
+
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
+    if( ssl->handshake->ecrs_enabled &&
+        ssl->handshake->ecrs_state == ssl_ecrs_crt_verify )
+    {
+        chain = ssl->handshake->ecrs_peer_cert;
+        ssl->handshake->ecrs_peer_cert = NULL;
+        goto crt_verify;
+    }
+#endif
+
+    if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+    {
+        /* mbedtls_ssl_read_record may have sent an alert already. We
+           let it decide whether to alert. */
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+        goto exit;
+    }
+
+#if defined(MBEDTLS_SSL_SRV_C)
+    if( ssl_srv_check_client_no_crt_notification( ssl ) == 0 )
+    {
+        ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
+
+        if( authmode != MBEDTLS_SSL_VERIFY_OPTIONAL )
+            ret = MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE;
+
+        goto exit;
+    }
+#endif /* MBEDTLS_SSL_SRV_C */
+
+    /* Clear existing peer CRT structure in case we tried to
+     * reuse a session but it failed, and allocate a new one. */
+    ssl_clear_peer_cert( ssl->session_negotiate );
+
+    chain = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
+    if( chain == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%" MBEDTLS_PRINTF_SIZET " bytes) failed",
+                                    sizeof( mbedtls_x509_crt ) ) );
+        mbedtls_ssl_send_alert_message( ssl,
+                                        MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+
+        ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
+        goto exit;
+    }
+    mbedtls_x509_crt_init( chain );
+
+    ret = ssl_parse_certificate_chain( ssl, chain );
+    if( ret != 0 )
+        goto exit;
+
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
+    if( ssl->handshake->ecrs_enabled)
+        ssl->handshake->ecrs_state = ssl_ecrs_crt_verify;
+
+crt_verify:
+    if( ssl->handshake->ecrs_enabled)
+        rs_ctx = &ssl->handshake->ecrs_ctx;
+#endif
+
+    ret = ssl_parse_certificate_verify( ssl, authmode,
+                                        chain, rs_ctx );
+    if( ret != 0 )
+        goto exit;
+
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+    {
+        unsigned char *crt_start, *pk_start;
+        size_t crt_len, pk_len;
+
+        /* We parse the CRT chain without copying, so
+         * these pointers point into the input buffer,
+         * and are hence still valid after freeing the
+         * CRT chain. */
+
+        crt_start = chain->raw.p;
+        crt_len   = chain->raw.len;
+
+        pk_start = chain->pk_raw.p;
+        pk_len   = chain->pk_raw.len;
+
+        /* Free the CRT structures before computing
+         * digest and copying the peer's public key. */
+        mbedtls_x509_crt_free( chain );
+        mbedtls_free( chain );
+        chain = NULL;
+
+        ret = ssl_remember_peer_crt_digest( ssl, crt_start, crt_len );
+        if( ret != 0 )
+            goto exit;
+
+        ret = ssl_remember_peer_pubkey( ssl, pk_start, pk_len );
+        if( ret != 0 )
+            goto exit;
+    }
+#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+    /* Pass ownership to session structure. */
+    ssl->session_negotiate->peer_cert = chain;
+    chain = NULL;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) );
+
+exit:
+
+    if( ret == 0 )
+        ssl->state++;
+
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
+    if( ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
+    {
+        ssl->handshake->ecrs_peer_cert = chain;
+        chain = NULL;
+    }
+#endif
+
+    if( chain != NULL )
+    {
+        mbedtls_x509_crt_free( chain );
+        mbedtls_free( chain );
+    }
+
+    return( ret );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+
+#if defined(MBEDTLS_SHA256_C)
+static void ssl_calc_finished_tls_sha256(
+                mbedtls_ssl_context *ssl, unsigned char *buf, int from )
+{
+    int len = 12;
+    const char *sender;
+    unsigned char padbuf[32];
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    size_t hash_size;
+    psa_hash_operation_t sha256_psa = PSA_HASH_OPERATION_INIT;
+    psa_status_t status;
+#else
+    mbedtls_sha256_context sha256;
+#endif
+
+    mbedtls_ssl_session *session = ssl->session_negotiate;
+    if( !session )
+        session = ssl->session;
+
+    sender = ( from == MBEDTLS_SSL_IS_CLIENT )
+             ? "client finished"
+             : "server finished";
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    sha256_psa = psa_hash_operation_init();
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc PSA finished tls sha256" ) );
+
+    status = psa_hash_clone( &ssl->handshake->fin_sha256_psa, &sha256_psa );
+    if( status != PSA_SUCCESS )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
+        return;
+    }
+
+    status = psa_hash_finish( &sha256_psa, padbuf, sizeof( padbuf ), &hash_size );
+    if( status != PSA_SUCCESS )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
+        return;
+    }
+    MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated padbuf", padbuf, 32 );
+#else
+
+    mbedtls_sha256_init( &sha256 );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc  finished tls sha256" ) );
+
+    mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
+
+    /*
+     * TLSv1.2:
+     *   hash = PRF( master, finished_label,
+     *               Hash( handshake ) )[0.11]
+     */
+
+#if !defined(MBEDTLS_SHA256_ALT)
+    MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *)
+                   sha256.state, sizeof( sha256.state ) );
+#endif
+
+    mbedtls_sha256_finish( &sha256, padbuf );
+    mbedtls_sha256_free( &sha256 );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+    ssl->handshake->tls_prf( session->master, 48, sender,
+                             padbuf, 32, buf, len );
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
+
+    mbedtls_platform_zeroize(  padbuf, sizeof(  padbuf ) );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
+}
+#endif /* MBEDTLS_SHA256_C */
+
+
+#if defined(MBEDTLS_SHA384_C)
+
+static void ssl_calc_finished_tls_sha384(
+                mbedtls_ssl_context *ssl, unsigned char *buf, int from )
+{
+    int len = 12;
+    const char *sender;
+    unsigned char padbuf[48];
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    size_t hash_size;
+    psa_hash_operation_t sha384_psa = PSA_HASH_OPERATION_INIT;
+    psa_status_t status;
+#else
+    mbedtls_sha512_context sha512;
+#endif
+
+    mbedtls_ssl_session *session = ssl->session_negotiate;
+    if( !session )
+        session = ssl->session;
+
+    sender = ( from == MBEDTLS_SSL_IS_CLIENT )
+                ? "client finished"
+                : "server finished";
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    sha384_psa = psa_hash_operation_init();
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc PSA finished tls sha384" ) );
+
+    status = psa_hash_clone( &ssl->handshake->fin_sha384_psa, &sha384_psa );
+    if( status != PSA_SUCCESS )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
+        return;
+    }
+
+    status = psa_hash_finish( &sha384_psa, padbuf, sizeof( padbuf ), &hash_size );
+    if( status != PSA_SUCCESS )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
+        return;
+    }
+    MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated padbuf", padbuf, 48 );
+#else
+    mbedtls_sha512_init( &sha512 );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc  finished tls sha384" ) );
+
+    mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
+
+    /*
+     * TLSv1.2:
+     *   hash = PRF( master, finished_label,
+     *               Hash( handshake ) )[0.11]
+     */
+
+#if !defined(MBEDTLS_SHA512_ALT)
+    MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *)
+                   sha512.state, sizeof( sha512.state ) );
+#endif
+    mbedtls_sha512_finish( &sha512, padbuf );
+
+    mbedtls_sha512_free( &sha512 );
+#endif
+
+    ssl->handshake->tls_prf( session->master, 48, sender,
+                             padbuf, 48, buf, len );
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
+
+    mbedtls_platform_zeroize(  padbuf, sizeof( padbuf ) );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
+}
+#endif /* MBEDTLS_SHA384_C */
+
+void mbedtls_ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl )
+{
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup: final free" ) );
+
+    /*
+     * Free our handshake params
+     */
+    mbedtls_ssl_handshake_free( ssl );
+    mbedtls_free( ssl->handshake );
+    ssl->handshake = NULL;
+
+    /*
+     * Free the previous transform and swith in the current one
+     */
+    if( ssl->transform )
+    {
+        mbedtls_ssl_transform_free( ssl->transform );
+        mbedtls_free( ssl->transform );
+    }
+    ssl->transform = ssl->transform_negotiate;
+    ssl->transform_negotiate = NULL;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup: final free" ) );
+}
+
+void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl )
+{
+    int resume = ssl->handshake->resume;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup" ) );
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
+    {
+        ssl->renego_status =  MBEDTLS_SSL_RENEGOTIATION_DONE;
+        ssl->renego_records_seen = 0;
+    }
+#endif
+
+    /*
+     * Free the previous session and switch in the current one
+     */
+    if( ssl->session )
+    {
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+        /* RFC 7366 3.1: keep the EtM state */
+        ssl->session_negotiate->encrypt_then_mac =
+                  ssl->session->encrypt_then_mac;
+#endif
+
+        mbedtls_ssl_session_free( ssl->session );
+        mbedtls_free( ssl->session );
+    }
+    ssl->session = ssl->session_negotiate;
+    ssl->session_negotiate = NULL;
+
+    /*
+     * Add cache entry
+     */
+    if( ssl->conf->f_set_cache != NULL &&
+        ssl->session->id_len != 0 &&
+        resume == 0 )
+    {
+        if( ssl->conf->f_set_cache( ssl->conf->p_cache,
+                                    ssl->session->id,
+                                    ssl->session->id_len,
+                                    ssl->session ) != 0 )
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "cache did not store session" ) );
+    }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        ssl->handshake->flight != NULL )
+    {
+        /* Cancel handshake timer */
+        mbedtls_ssl_set_timer( ssl, 0 );
+
+        /* Keep last flight around in case we need to resend it:
+         * we need the handshake and transform structures for that */
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip freeing handshake and transform" ) );
+    }
+    else
+#endif
+        mbedtls_ssl_handshake_wrapup_free_hs_transform( ssl );
+
+    ssl->state++;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup" ) );
+}
+
+int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl )
+{
+    int ret, hash_len;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write finished" ) );
+
+    mbedtls_ssl_update_out_pointers( ssl, ssl->transform_negotiate );
+
+    ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint );
+
+    /*
+     * RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites
+     * may define some other value. Currently (early 2016), no defined
+     * ciphersuite does this (and this is unlikely to change as activity has
+     * moved to TLS 1.3 now) so we can keep the hardcoded 12 here.
+     */
+    hash_len = 12;
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    ssl->verify_data_len = hash_len;
+    memcpy( ssl->own_verify_data, ssl->out_msg + 4, hash_len );
+#endif
+
+    ssl->out_msglen  = 4 + hash_len;
+    ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
+    ssl->out_msg[0]  = MBEDTLS_SSL_HS_FINISHED;
+
+    /*
+     * In case of session resuming, invert the client and server
+     * ChangeCipherSpec messages order.
+     */
+    if( ssl->handshake->resume != 0 )
+    {
+#if defined(MBEDTLS_SSL_CLI_C)
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+            ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
+#endif
+#if defined(MBEDTLS_SSL_SRV_C)
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
+            ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC;
+#endif
+    }
+    else
+        ssl->state++;
+
+    /*
+     * Switch to our negotiated transform and session parameters for outbound
+     * data.
+     */
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for outbound data" ) );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        unsigned char i;
+
+        /* Remember current epoch settings for resending */
+        ssl->handshake->alt_transform_out = ssl->transform_out;
+        memcpy( ssl->handshake->alt_out_ctr, ssl->cur_out_ctr,
+                sizeof( ssl->handshake->alt_out_ctr ) );
+
+        /* Set sequence_number to zero */
+        memset( &ssl->cur_out_ctr[2], 0, sizeof( ssl->cur_out_ctr ) - 2 );
+
+
+        /* Increment epoch */
+        for( i = 2; i > 0; i-- )
+            if( ++ssl->cur_out_ctr[i - 1] != 0 )
+                break;
+
+        /* The loop goes to its end iff the counter is wrapping */
+        if( i == 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) );
+            return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
+        }
+    }
+    else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+    memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) );
+
+    ssl->transform_out = ssl->transform_negotiate;
+    ssl->session_out = ssl->session_negotiate;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        mbedtls_ssl_send_flight_completed( ssl );
+#endif
+
+    if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
+        return( ret );
+    }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
+        return( ret );
+    }
+#endif
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write finished" ) );
+
+    return( 0 );
+}
+
+#define SSL_MAX_HASH_LEN 12
+
+int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    unsigned int hash_len = 12;
+    unsigned char buf[SSL_MAX_HASH_LEN];
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse finished" ) );
+
+    ssl->handshake->calc_finished( ssl, buf, ssl->conf->endpoint ^ 1 );
+
+    if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+        goto exit;
+    }
+
+    if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
+        goto exit;
+    }
+
+    if( ssl->in_msg[0] != MBEDTLS_SSL_HS_FINISHED  )
+    {
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
+        goto exit;
+    }
+
+    if( ssl->in_hslen  != mbedtls_ssl_hs_hdr_len( ssl ) + hash_len )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        ret = MBEDTLS_ERR_SSL_DECODE_ERROR;
+        goto exit;
+    }
+
+    if( mbedtls_ct_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ),
+                      buf, hash_len ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR );
+        ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
+        goto exit;
+    }
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    ssl->verify_data_len = hash_len;
+    memcpy( ssl->peer_verify_data, buf, hash_len );
+#endif
+
+    if( ssl->handshake->resume != 0 )
+    {
+#if defined(MBEDTLS_SSL_CLI_C)
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+            ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC;
+#endif
+#if defined(MBEDTLS_SSL_SRV_C)
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
+            ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
+#endif
+    }
+    else
+        ssl->state++;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        mbedtls_ssl_recv_flight_completed( ssl );
+#endif
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse finished" ) );
+
+exit:
+    mbedtls_platform_zeroize( buf, hash_len );
+    return( ret );
+}
+
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+/*
+ * Helper to get TLS 1.2 PRF from ciphersuite
+ * (Duplicates bits of logic from ssl_set_handshake_prfs().)
+ */
+static tls_prf_fn ssl_tls12prf_from_cs( int ciphersuite_id )
+{
+#if defined(MBEDTLS_SHA384_C)
+    const mbedtls_ssl_ciphersuite_t * const ciphersuite_info =
+         mbedtls_ssl_ciphersuite_from_id( ciphersuite_id );
+
+    if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
+        return( tls_prf_sha384 );
+#else
+    (void) ciphersuite_id;
+#endif
+    return( tls_prf_sha256 );
+}
+#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
+
+static mbedtls_tls_prf_types tls_prf_get_type( mbedtls_ssl_tls_prf_cb *tls_prf )
+{
+    ((void) tls_prf);
+#if defined(MBEDTLS_SHA384_C)
+    if( tls_prf == tls_prf_sha384 )
+    {
+        return( MBEDTLS_SSL_TLS_PRF_SHA384 );
+    }
+    else
+#endif
+#if defined(MBEDTLS_SHA256_C)
+    if( tls_prf == tls_prf_sha256 )
+    {
+        return( MBEDTLS_SSL_TLS_PRF_SHA256 );
+    }
+    else
+#endif
+    return( MBEDTLS_SSL_TLS_PRF_NONE );
+}
+
+/*
+ * Populate a transform structure with session keys and all the other
+ * necessary information.
+ *
+ * Parameters:
+ * - [in/out]: transform: structure to populate
+ *      [in] must be just initialised with mbedtls_ssl_transform_init()
+ *      [out] fully populated, ready for use by mbedtls_ssl_{en,de}crypt_buf()
+ * - [in] ciphersuite
+ * - [in] master
+ * - [in] encrypt_then_mac
+ * - [in] compression
+ * - [in] tls_prf: pointer to PRF to use for key derivation
+ * - [in] randbytes: buffer holding ServerHello.random + ClientHello.random
+ * - [in] minor_ver: SSL/TLS minor version
+ * - [in] endpoint: client or server
+ * - [in] ssl: used for:
+ *        - ssl->conf->{f,p}_export_keys
+ *      [in] optionally used for:
+ *        - MBEDTLS_DEBUG_C: ssl->conf->{f,p}_dbg
+ */
+static int ssl_tls12_populate_transform( mbedtls_ssl_transform *transform,
+                                   int ciphersuite,
+                                   const unsigned char master[48],
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) && \
+    defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+                                   int encrypt_then_mac,
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC &&
+          MBEDTLS_SSL_SOME_SUITES_USE_MAC */
+                                   ssl_tls_prf_t tls_prf,
+                                   const unsigned char randbytes[64],
+                                   int minor_ver,
+                                   unsigned endpoint,
+                                   const mbedtls_ssl_context *ssl )
+{
+    int ret = 0;
+    unsigned char keyblk[256];
+    unsigned char *key1;
+    unsigned char *key2;
+    unsigned char *mac_enc;
+    unsigned char *mac_dec;
+    size_t mac_key_len = 0;
+    size_t iv_copy_len;
+    size_t keylen;
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+    const mbedtls_cipher_info_t *cipher_info;
+    const mbedtls_md_info_t *md_info;
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    psa_key_type_t key_type;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_algorithm_t alg;
+    size_t key_bits;
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+#endif
+
+#if !defined(MBEDTLS_DEBUG_C) && \
+    !defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+    if( ssl->f_export_keys == NULL )
+    {
+        ssl = NULL; /* make sure we don't use it except for these cases */
+        (void) ssl;
+    }
+#endif
+
+    /*
+     * Some data just needs copying into the structure
+     */
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \
+    defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
+    transform->encrypt_then_mac = encrypt_then_mac;
+#endif
+    transform->minor_ver = minor_ver;
+
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+    memcpy( transform->randbytes, randbytes, sizeof( transform->randbytes ) );
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 )
+    {
+        /* At the moment, we keep TLS <= 1.2 and TLS 1.3 transform
+         * generation separate. This should never happen. */
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+
+    /*
+     * Get various info structures
+     */
+    ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuite );
+    if( ciphersuite_info == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %d not found",
+                                    ciphersuite ) );
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    cipher_info = mbedtls_cipher_info_from_type( ciphersuite_info->cipher );
+    if( cipher_info == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher info for %u not found",
+                                    ciphersuite_info->cipher ) );
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    md_info = mbedtls_md_info_from_type( ciphersuite_info->mac );
+    if( md_info == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_md info for %u not found",
+                            (unsigned) ciphersuite_info->mac ) );
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+    /* Copy own and peer's CID if the use of the CID
+     * extension has been negotiated. */
+    if( ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_ENABLED )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "Copy CIDs into SSL transform" ) );
+
+        transform->in_cid_len = ssl->own_cid_len;
+        memcpy( transform->in_cid, ssl->own_cid, ssl->own_cid_len );
+        MBEDTLS_SSL_DEBUG_BUF( 3, "Incoming CID", transform->in_cid,
+                               transform->in_cid_len );
+
+        transform->out_cid_len = ssl->handshake->peer_cid_len;
+        memcpy( transform->out_cid, ssl->handshake->peer_cid,
+                ssl->handshake->peer_cid_len );
+        MBEDTLS_SSL_DEBUG_BUF( 3, "Outgoing CID", transform->out_cid,
+                               transform->out_cid_len );
+    }
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
+    /*
+     * Compute key block using the PRF
+     */
+    ret = tls_prf( master, 48, "key expansion", randbytes, 64, keyblk, 256 );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
+        return( ret );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite = %s",
+                           mbedtls_ssl_get_ciphersuite_name( ciphersuite ) ) );
+    MBEDTLS_SSL_DEBUG_BUF( 3, "master secret", master, 48 );
+    MBEDTLS_SSL_DEBUG_BUF( 4, "random bytes", randbytes, 64 );
+    MBEDTLS_SSL_DEBUG_BUF( 4, "key block", keyblk, 256 );
+
+    /*
+     * Determine the appropriate key, IV and MAC length.
+     */
+
+    keylen = mbedtls_cipher_info_get_key_bitlen( cipher_info ) / 8;
+
+#if defined(MBEDTLS_GCM_C) ||                           \
+    defined(MBEDTLS_CCM_C) ||                           \
+    defined(MBEDTLS_CHACHAPOLY_C)
+    if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_GCM ||
+        mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CCM ||
+        mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CHACHAPOLY )
+    {
+        size_t explicit_ivlen;
+
+        transform->maclen = 0;
+        mac_key_len = 0;
+        transform->taglen =
+            ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
+
+        /* All modes haves 96-bit IVs, but the length of the static parts vary
+         * with mode and version:
+         * - For GCM and CCM in TLS 1.2, there's a static IV of 4 Bytes
+         *   (to be concatenated with a dynamically chosen IV of 8 Bytes)
+         * - For ChaChaPoly in TLS 1.2, and all modes in TLS 1.3, there's
+         *   a static IV of 12 Bytes (to be XOR'ed with the 8 Byte record
+         *   sequence number).
+         */
+        transform->ivlen = 12;
+        if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CHACHAPOLY )
+            transform->fixed_ivlen = 12;
+        else
+            transform->fixed_ivlen = 4;
+
+        /* Minimum length of encrypted record */
+        explicit_ivlen = transform->ivlen - transform->fixed_ivlen;
+        transform->minlen = explicit_ivlen + transform->taglen;
+    }
+    else
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
+    if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_STREAM ||
+        mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CBC )
+    {
+        /* Initialize HMAC contexts */
+        if( ( ret = mbedtls_md_setup( &transform->md_ctx_enc, md_info, 1 ) ) != 0 ||
+            ( ret = mbedtls_md_setup( &transform->md_ctx_dec, md_info, 1 ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
+            goto end;
+        }
+
+        /* Get MAC length */
+        mac_key_len = mbedtls_md_get_size( md_info );
+        transform->maclen = mac_key_len;
+
+        /* IV length */
+        transform->ivlen = cipher_info->iv_size;
+
+        /* Minimum length */
+        if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_STREAM )
+            transform->minlen = transform->maclen;
+        else
+        {
+            /*
+             * GenericBlockCipher:
+             * 1. if EtM is in use: one block plus MAC
+             *    otherwise: * first multiple of blocklen greater than maclen
+             * 2. IV
+             */
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+            if( encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
+            {
+                transform->minlen = transform->maclen
+                                  + cipher_info->block_size;
+            }
+            else
+#endif
+            {
+                transform->minlen = transform->maclen
+                                  + cipher_info->block_size
+                                  - transform->maclen % cipher_info->block_size;
+            }
+
+            if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+            {
+                transform->minlen += transform->ivlen;
+            }
+            else
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+                ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+                goto end;
+            }
+        }
+    }
+    else
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "keylen: %u, minlen: %u, ivlen: %u, maclen: %u",
+                                (unsigned) keylen,
+                                (unsigned) transform->minlen,
+                                (unsigned) transform->ivlen,
+                                (unsigned) transform->maclen ) );
+
+    /*
+     * Finally setup the cipher contexts, IVs and MAC secrets.
+     */
+#if defined(MBEDTLS_SSL_CLI_C)
+    if( endpoint == MBEDTLS_SSL_IS_CLIENT )
+    {
+        key1 = keyblk + mac_key_len * 2;
+        key2 = keyblk + mac_key_len * 2 + keylen;
+
+        mac_enc = keyblk;
+        mac_dec = keyblk + mac_key_len;
+
+        /*
+         * This is not used in TLS v1.1.
+         */
+        iv_copy_len = ( transform->fixed_ivlen ) ?
+                            transform->fixed_ivlen : transform->ivlen;
+        memcpy( transform->iv_enc, key2 + keylen,  iv_copy_len );
+        memcpy( transform->iv_dec, key2 + keylen + iv_copy_len,
+                iv_copy_len );
+    }
+    else
+#endif /* MBEDTLS_SSL_CLI_C */
+#if defined(MBEDTLS_SSL_SRV_C)
+    if( endpoint == MBEDTLS_SSL_IS_SERVER )
+    {
+        key1 = keyblk + mac_key_len * 2 + keylen;
+        key2 = keyblk + mac_key_len * 2;
+
+        mac_enc = keyblk + mac_key_len;
+        mac_dec = keyblk;
+
+        /*
+         * This is not used in TLS v1.1.
+         */
+        iv_copy_len = ( transform->fixed_ivlen ) ?
+                            transform->fixed_ivlen : transform->ivlen;
+        memcpy( transform->iv_dec, key1 + keylen,  iv_copy_len );
+        memcpy( transform->iv_enc, key1 + keylen + iv_copy_len,
+                iv_copy_len );
+    }
+    else
+#endif /* MBEDTLS_SSL_SRV_C */
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+        goto end;
+    }
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
+    /* For HMAC-based ciphersuites, initialize the HMAC transforms.
+       For AEAD-based ciphersuites, there is nothing to do here. */
+    if( mac_key_len != 0 )
+    {
+        ret = mbedtls_md_hmac_starts( &transform->md_ctx_enc, mac_enc, mac_key_len );
+        if( ret != 0 )
+            goto end;
+        ret = mbedtls_md_hmac_starts( &transform->md_ctx_dec, mac_dec, mac_key_len );
+        if( ret != 0 )
+            goto end;
+    }
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
+
+    ((void) mac_dec);
+    ((void) mac_enc);
+
+    if( ssl != NULL && ssl->f_export_keys != NULL )
+    {
+        ssl->f_export_keys( ssl->p_export_keys,
+                            MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET,
+                            master, 48,
+                            randbytes + 32,
+                            randbytes,
+                            tls_prf_get_type( tls_prf ) );
+    }
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    if( ( status = mbedtls_ssl_cipher_to_psa( cipher_info->type,
+                                 transform->taglen,
+                                 &alg,
+                                 &key_type,
+                                 &key_bits ) ) != PSA_SUCCESS )
+    {
+        ret = psa_ssl_status_to_mbedtls( status );
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_cipher_to_psa", ret );
+        goto end;
+    }
+
+    transform->psa_alg = alg;
+
+    if ( alg != MBEDTLS_SSL_NULL_CIPHER )
+    {
+        psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
+        psa_set_key_algorithm( &attributes, alg );
+        psa_set_key_type( &attributes, key_type );
+
+        if( ( status = psa_import_key( &attributes,
+                                key1,
+                                PSA_BITS_TO_BYTES( key_bits ),
+                                &transform->psa_key_enc ) ) != PSA_SUCCESS )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 3, "psa_import_key", (int)status );
+            ret = psa_ssl_status_to_mbedtls( status );
+            MBEDTLS_SSL_DEBUG_RET( 1, "psa_import_key", ret );
+            goto end;
+        }
+
+        psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
+
+        if( ( status = psa_import_key( &attributes,
+                                key2,
+                                PSA_BITS_TO_BYTES( key_bits ),
+                                &transform->psa_key_dec ) ) != PSA_SUCCESS )
+        {
+            ret = psa_ssl_status_to_mbedtls( status );
+            MBEDTLS_SSL_DEBUG_RET( 1, "psa_import_key", ret );
+            goto end;
+        }
+    }
+#else
+    if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc,
+                                 cipher_info ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
+        goto end;
+    }
+
+    if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_dec,
+                                 cipher_info ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
+        goto end;
+    }
+
+    if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_enc, key1,
+                               (int) mbedtls_cipher_info_get_key_bitlen( cipher_info ),
+                               MBEDTLS_ENCRYPT ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
+        goto end;
+    }
+
+    if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_dec, key2,
+                               (int) mbedtls_cipher_info_get_key_bitlen( cipher_info ),
+                               MBEDTLS_DECRYPT ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
+        goto end;
+    }
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CBC )
+    {
+        if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_enc,
+                                             MBEDTLS_PADDING_NONE ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret );
+            goto end;
+        }
+
+        if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_dec,
+                                             MBEDTLS_PADDING_NONE ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret );
+            goto end;
+        }
+    }
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+end:
+    mbedtls_platform_zeroize( keyblk, sizeof( keyblk ) );
+    return( ret );
+}
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
+                                            unsigned char *hash, size_t *hashlen,
+                                            unsigned char *data, size_t data_len,
+                                            mbedtls_md_type_t md_alg )
+{
+    psa_status_t status;
+    psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT;
+    psa_algorithm_t hash_alg = mbedtls_psa_translate_md( md_alg );
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "Perform PSA-based computation of digest of ServerKeyExchange" ) );
+
+    if( ( status = psa_hash_setup( &hash_operation,
+                                   hash_alg ) ) != PSA_SUCCESS )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_setup", status );
+        goto exit;
+    }
+
+    if( ( status = psa_hash_update( &hash_operation, ssl->handshake->randbytes,
+                                    64 ) ) != PSA_SUCCESS )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_update", status );
+        goto exit;
+    }
+
+    if( ( status = psa_hash_update( &hash_operation,
+                                    data, data_len ) ) != PSA_SUCCESS )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_update", status );
+        goto exit;
+    }
+
+    if( ( status = psa_hash_finish( &hash_operation, hash, PSA_HASH_MAX_SIZE,
+                                    hashlen ) ) != PSA_SUCCESS )
+    {
+         MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_finish", status );
+         goto exit;
+    }
+
+exit:
+    if( status != PSA_SUCCESS )
+    {
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+        switch( status )
+        {
+            case PSA_ERROR_NOT_SUPPORTED:
+                return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE );
+            case PSA_ERROR_BAD_STATE: /* Intentional fallthrough */
+            case PSA_ERROR_BUFFER_TOO_SMALL:
+                return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+            case PSA_ERROR_INSUFFICIENT_MEMORY:
+                return( MBEDTLS_ERR_MD_ALLOC_FAILED );
+            default:
+                return( MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED );
+        }
+    }
+    return( 0 );
+}
+
+#else
+
+int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
+                                            unsigned char *hash, size_t *hashlen,
+                                            unsigned char *data, size_t data_len,
+                                            mbedtls_md_type_t md_alg )
+{
+    int ret = 0;
+    mbedtls_md_context_t ctx;
+    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
+    *hashlen = mbedtls_md_get_size( md_info );
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "Perform mbedtls-based computation of digest of ServerKeyExchange" ) );
+
+    mbedtls_md_init( &ctx );
+
+    /*
+     * digitally-signed struct {
+     *     opaque client_random[32];
+     *     opaque server_random[32];
+     *     ServerDHParams params;
+     * };
+     */
+    if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_starts", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_md_update( &ctx, data, data_len ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_md_finish( &ctx, hash ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_finish", ret );
+        goto exit;
+    }
+
+exit:
+    mbedtls_md_free( &ctx );
+
+    if( ret != 0 )
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+
+    return( ret );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+
+/* Find an entry in a signature-hash set matching a given hash algorithm. */
+mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set,
+                                                 mbedtls_pk_type_t sig_alg )
+{
+    switch( sig_alg )
+    {
+        case MBEDTLS_PK_RSA:
+            return( set->rsa );
+        case MBEDTLS_PK_ECDSA:
+            return( set->ecdsa );
+        default:
+            return( MBEDTLS_MD_NONE );
+    }
+}
+
+/* Add a signature-hash-pair to a signature-hash set */
+void mbedtls_ssl_sig_hash_set_add( mbedtls_ssl_sig_hash_set_t *set,
+                                   mbedtls_pk_type_t sig_alg,
+                                   mbedtls_md_type_t md_alg )
+{
+    switch( sig_alg )
+    {
+        case MBEDTLS_PK_RSA:
+            if( set->rsa == MBEDTLS_MD_NONE )
+                set->rsa = md_alg;
+            break;
+
+        case MBEDTLS_PK_ECDSA:
+            if( set->ecdsa == MBEDTLS_MD_NONE )
+                set->ecdsa = md_alg;
+            break;
+
+        default:
+            break;
+    }
+}
+
+/* Allow exactly one hash algorithm for each signature. */
+void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set,
+                                          mbedtls_md_type_t md_alg )
+{
+    set->rsa   = md_alg;
+    set->ecdsa = md_alg;
+}
+
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+
+/* Serialization of TLS 1.2 sessions:
+ *
+ * struct {
+ *    uint64 start_time;
+ *    uint8 ciphersuite[2];           // defined by the standard
+ *    uint8 compression;              // 0 or 1
+ *    uint8 session_id_len;           // at most 32
+ *    opaque session_id[32];
+ *    opaque master[48];              // fixed length in the standard
+ *    uint32 verify_result;
+ *    opaque peer_cert<0..2^24-1>;    // length 0 means no peer cert
+ *    opaque ticket<0..2^24-1>;       // length 0 means no ticket
+ *    uint32 ticket_lifetime;
+ *    uint8 mfl_code;                 // up to 255 according to standard
+ *    uint8 encrypt_then_mac;         // 0 or 1
+ * } serialized_session_tls12;
+ *
+ */
+static size_t ssl_session_save_tls12( const mbedtls_ssl_session *session,
+                                      unsigned char *buf,
+                                      size_t buf_len )
+{
+    unsigned char *p = buf;
+    size_t used = 0;
+
+#if defined(MBEDTLS_HAVE_TIME)
+    uint64_t start;
+#endif
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+    size_t cert_len;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+    /*
+     * Time
+     */
+#if defined(MBEDTLS_HAVE_TIME)
+    used += 8;
+
+    if( used <= buf_len )
+    {
+        start = (uint64_t) session->start;
+
+        MBEDTLS_PUT_UINT64_BE( start, p, 0 );
+        p += 8;
+    }
+#endif /* MBEDTLS_HAVE_TIME */
+
+    /*
+     * Basic mandatory fields
+     */
+    used += 2   /* ciphersuite */
+          + 1   /* compression */
+          + 1   /* id_len */
+          + sizeof( session->id )
+          + sizeof( session->master )
+          + 4;  /* verify_result */
+
+    if( used <= buf_len )
+    {
+        MBEDTLS_PUT_UINT16_BE( session->ciphersuite, p, 0 );
+        p += 2;
+
+        *p++ = MBEDTLS_BYTE_0( session->compression );
+
+        *p++ = MBEDTLS_BYTE_0( session->id_len );
+        memcpy( p, session->id, 32 );
+        p += 32;
+
+        memcpy( p, session->master, 48 );
+        p += 48;
+
+        MBEDTLS_PUT_UINT32_BE( session->verify_result, p, 0 );
+        p += 4;
+    }
+
+    /*
+     * Peer's end-entity certificate
+     */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+    if( session->peer_cert == NULL )
+        cert_len = 0;
+    else
+        cert_len = session->peer_cert->raw.len;
+
+    used += 3 + cert_len;
+
+    if( used <= buf_len )
+    {
+        *p++ = MBEDTLS_BYTE_2( cert_len );
+        *p++ = MBEDTLS_BYTE_1( cert_len );
+        *p++ = MBEDTLS_BYTE_0( cert_len );
+
+        if( session->peer_cert != NULL )
+        {
+            memcpy( p, session->peer_cert->raw.p, cert_len );
+            p += cert_len;
+        }
+    }
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+    if( session->peer_cert_digest != NULL )
+    {
+        used += 1 /* type */ + 1 /* length */ + session->peer_cert_digest_len;
+        if( used <= buf_len )
+        {
+            *p++ = (unsigned char) session->peer_cert_digest_type;
+            *p++ = (unsigned char) session->peer_cert_digest_len;
+            memcpy( p, session->peer_cert_digest,
+                    session->peer_cert_digest_len );
+            p += session->peer_cert_digest_len;
+        }
+    }
+    else
+    {
+        used += 2;
+        if( used <= buf_len )
+        {
+            *p++ = (unsigned char) MBEDTLS_MD_NONE;
+            *p++ = 0;
+        }
+    }
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+    /*
+     * Session ticket if any, plus associated data
+     */
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+    used += 3 + session->ticket_len + 4; /* len + ticket + lifetime */
+
+    if( used <= buf_len )
+    {
+        *p++ = MBEDTLS_BYTE_2( session->ticket_len );
+        *p++ = MBEDTLS_BYTE_1( session->ticket_len );
+        *p++ = MBEDTLS_BYTE_0( session->ticket_len );
+
+        if( session->ticket != NULL )
+        {
+            memcpy( p, session->ticket, session->ticket_len );
+            p += session->ticket_len;
+        }
+
+        MBEDTLS_PUT_UINT32_BE( session->ticket_lifetime, p, 0 );
+        p += 4;
+    }
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
+
+    /*
+     * Misc extension-related info
+     */
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+    used += 1;
+
+    if( used <= buf_len )
+        *p++ = session->mfl_code;
+#endif
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+    used += 1;
+
+    if( used <= buf_len )
+        *p++ = MBEDTLS_BYTE_0( session->encrypt_then_mac );
+#endif
+
+    return( used );
+}
+
+static int ssl_session_load_tls12( mbedtls_ssl_session *session,
+                                   const unsigned char *buf,
+                                   size_t len )
+{
+#if defined(MBEDTLS_HAVE_TIME)
+    uint64_t start;
+#endif
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+    size_t cert_len;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+    const unsigned char *p = buf;
+    const unsigned char * const end = buf + len;
+
+    /*
+     * Time
+     */
+#if defined(MBEDTLS_HAVE_TIME)
+    if( 8 > (size_t)( end - p ) )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    start = ( (uint64_t) p[0] << 56 ) |
+            ( (uint64_t) p[1] << 48 ) |
+            ( (uint64_t) p[2] << 40 ) |
+            ( (uint64_t) p[3] << 32 ) |
+            ( (uint64_t) p[4] << 24 ) |
+            ( (uint64_t) p[5] << 16 ) |
+            ( (uint64_t) p[6] <<  8 ) |
+            ( (uint64_t) p[7]       );
+    p += 8;
+
+    session->start = (time_t) start;
+#endif /* MBEDTLS_HAVE_TIME */
+
+    /*
+     * Basic mandatory fields
+     */
+    if( 2 + 1 + 1 + 32 + 48 + 4 > (size_t)( end - p ) )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    session->ciphersuite = ( p[0] << 8 ) | p[1];
+    p += 2;
+
+    session->compression = *p++;
+
+    session->id_len = *p++;
+    memcpy( session->id, p, 32 );
+    p += 32;
+
+    memcpy( session->master, p, 48 );
+    p += 48;
+
+    session->verify_result = ( (uint32_t) p[0] << 24 ) |
+                             ( (uint32_t) p[1] << 16 ) |
+                             ( (uint32_t) p[2] <<  8 ) |
+                             ( (uint32_t) p[3]       );
+    p += 4;
+
+    /* Immediately clear invalid pointer values that have been read, in case
+     * we exit early before we replaced them with valid ones. */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+    session->peer_cert = NULL;
+#else
+    session->peer_cert_digest = NULL;
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+    session->ticket = NULL;
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
+
+    /*
+     * Peer certificate
+     */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+    /* Deserialize CRT from the end of the ticket. */
+    if( 3 > (size_t)( end - p ) )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
+    p += 3;
+
+    if( cert_len != 0 )
+    {
+        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+        if( cert_len > (size_t)( end - p ) )
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+        session->peer_cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
+
+        if( session->peer_cert == NULL )
+            return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+
+        mbedtls_x509_crt_init( session->peer_cert );
+
+        if( ( ret = mbedtls_x509_crt_parse_der( session->peer_cert,
+                                                p, cert_len ) ) != 0 )
+        {
+            mbedtls_x509_crt_free( session->peer_cert );
+            mbedtls_free( session->peer_cert );
+            session->peer_cert = NULL;
+            return( ret );
+        }
+
+        p += cert_len;
+    }
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+    /* Deserialize CRT digest from the end of the ticket. */
+    if( 2 > (size_t)( end - p ) )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    session->peer_cert_digest_type = (mbedtls_md_type_t) *p++;
+    session->peer_cert_digest_len  = (size_t) *p++;
+
+    if( session->peer_cert_digest_len != 0 )
+    {
+        const mbedtls_md_info_t *md_info =
+            mbedtls_md_info_from_type( session->peer_cert_digest_type );
+        if( md_info == NULL )
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+        if( session->peer_cert_digest_len != mbedtls_md_get_size( md_info ) )
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+        if( session->peer_cert_digest_len > (size_t)( end - p ) )
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+        session->peer_cert_digest =
+            mbedtls_calloc( 1, session->peer_cert_digest_len );
+        if( session->peer_cert_digest == NULL )
+            return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+
+        memcpy( session->peer_cert_digest, p,
+                session->peer_cert_digest_len );
+        p += session->peer_cert_digest_len;
+    }
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+    /*
+     * Session ticket and associated data
+     */
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+    if( 3 > (size_t)( end - p ) )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    session->ticket_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
+    p += 3;
+
+    if( session->ticket_len != 0 )
+    {
+        if( session->ticket_len > (size_t)( end - p ) )
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+        session->ticket = mbedtls_calloc( 1, session->ticket_len );
+        if( session->ticket == NULL )
+            return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+
+        memcpy( session->ticket, p, session->ticket_len );
+        p += session->ticket_len;
+    }
+
+    if( 4 > (size_t)( end - p ) )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    session->ticket_lifetime = ( (uint32_t) p[0] << 24 ) |
+                               ( (uint32_t) p[1] << 16 ) |
+                               ( (uint32_t) p[2] <<  8 ) |
+                               ( (uint32_t) p[3]       );
+    p += 4;
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
+
+    /*
+     * Misc extension-related info
+     */
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+    if( 1 > (size_t)( end - p ) )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    session->mfl_code = *p++;
+#endif
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+    if( 1 > (size_t)( end - p ) )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    session->encrypt_then_mac = *p++;
+#endif
+
+    /* Done, should have consumed entire buffer */
+    if( p != end )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
 #endif /* MBEDTLS_SSL_TLS_C */
diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c
index ca91d67..7f120a2 100644
--- a/library/ssl_tls13_client.c
+++ b/library/ssl_tls13_client.c
@@ -21,9 +21,7 @@
 
 #include "common.h"
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
-
-#if defined(MBEDTLS_SSL_CLI_C)
+#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3)
 
 #include <string.h>
 
@@ -1662,31 +1660,213 @@
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
 /*
- * Handler for  MBEDTLS_SSL_CERTIFICATE_REQUEST
+ *
+ * STATE HANDLING: CertificateRequest
+ *
  */
-static int ssl_tls13_process_certificate_request( mbedtls_ssl_context *ssl )
+#define SSL_CERTIFICATE_REQUEST_EXPECT_REQUEST 0
+#define SSL_CERTIFICATE_REQUEST_SKIP           1
+/* Coordination:
+ * Deals with the ambiguity of not knowing if a CertificateRequest
+ * will be sent. Returns a negative code on failure, or
+ * - SSL_CERTIFICATE_REQUEST_EXPECT_REQUEST
+ * - SSL_CERTIFICATE_REQUEST_SKIP
+ * indicating if a Certificate Request is expected or not.
+ */
+static int ssl_tls13_certificate_request_coordinate( mbedtls_ssl_context *ssl )
 {
-    int ret = mbedtls_ssl_read_record( ssl, 0 );
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
-    if( ret != 0 )
+    if( mbedtls_ssl_tls13_some_psk_enabled( ssl ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= skip parse certificate request" ) );
+        return( SSL_CERTIFICATE_REQUEST_SKIP );
+    }
+
+    if( ( ret = mbedtls_ssl_read_record( ssl, 0 ) ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
         return( ret );
     }
+    ssl->keep_current_message = 1;
 
     if( ( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) &&
         ( ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST ) )
     {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "CertificateRequest not supported" ) );
-        MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
-                                      MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
+        return( SSL_CERTIFICATE_REQUEST_EXPECT_REQUEST );
     }
 
-    ssl->keep_current_message = 1;
+    return( SSL_CERTIFICATE_REQUEST_SKIP );
+}
+
+/*
+ * ssl_tls13_parse_certificate_request()
+ *     Parse certificate request
+ * struct {
+ *   opaque certificate_request_context<0..2^8-1>;
+ *   Extension extensions<2..2^16-1>;
+ * } CertificateRequest;
+ */
+static int ssl_tls13_parse_certificate_request( mbedtls_ssl_context *ssl,
+                                                const unsigned char *buf,
+                                                const unsigned char *end )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    const unsigned char *p = buf;
+    size_t certificate_request_context_len = 0;
+    size_t extensions_len = 0;
+    const unsigned char *extensions_end;
+    unsigned char sig_alg_ext_found = 0;
+
+    /* ...
+     * opaque certificate_request_context<0..2^8-1>
+     * ...
+     */
+    MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, 1 );
+    certificate_request_context_len = (size_t) p[0];
+    p += 1;
+
+    if( certificate_request_context_len > 0 )
+    {
+        MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, certificate_request_context_len );
+        MBEDTLS_SSL_DEBUG_BUF( 3, "Certificate Request Context",
+                               p, certificate_request_context_len );
+
+        mbedtls_ssl_handshake_params *handshake = ssl->handshake;
+        handshake->certificate_request_context =
+                mbedtls_calloc( 1, certificate_request_context_len );
+        if( handshake->certificate_request_context == NULL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+            return ( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+        }
+        memcpy( handshake->certificate_request_context, p,
+                certificate_request_context_len );
+        p += certificate_request_context_len;
+    }
+
+    /* ...
+     * Extension extensions<2..2^16-1>;
+     * ...
+     */
+    MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, 2 );
+    extensions_len = MBEDTLS_GET_UINT16_BE( p, 0 );
+    p += 2;
+
+    MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, extensions_len );
+    extensions_end = p + extensions_len;
+
+    while( p < extensions_end )
+    {
+        unsigned int extension_type;
+        size_t extension_data_len;
+
+        MBEDTLS_SSL_CHK_BUF_READ_PTR( p, extensions_end, 4 );
+        extension_type = MBEDTLS_GET_UINT16_BE( p, 0 );
+        extension_data_len = MBEDTLS_GET_UINT16_BE( p, 2 );
+        p += 4;
+
+        MBEDTLS_SSL_CHK_BUF_READ_PTR( p, extensions_end, extension_data_len );
+
+        switch( extension_type )
+        {
+            case MBEDTLS_TLS_EXT_SIG_ALG:
+                MBEDTLS_SSL_DEBUG_MSG( 3,
+                        ( "found signature algorithms extension" ) );
+                ret = mbedtls_ssl_tls13_parse_sig_alg_ext( ssl, p,
+                              p + extension_data_len );
+                if( ret != 0 )
+                    return( ret );
+                if( ! sig_alg_ext_found )
+                    sig_alg_ext_found = 1;
+                else
+                {
+                    MBEDTLS_SSL_DEBUG_MSG( 3,
+                        ( "Duplicate signature algorithms extensions found" ) );
+                    goto decode_error;
+                }
+                break;
+
+            default:
+                MBEDTLS_SSL_DEBUG_MSG(
+                    3,
+                    ( "unknown extension found: %u ( ignoring )",
+                    extension_type ) );
+                break;
+        }
+        p += extension_data_len;
+    }
+    /* Check that we consumed all the message. */
+    if( p != end )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1,
+            ( "CertificateRequest misaligned" ) );
+        goto decode_error;
+    }
+    /* Check that we found signature algorithms extension */
+    if( ! sig_alg_ext_found )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3,
+            ( "no signature algorithms extension found" ) );
+        goto decode_error;
+    }
+
+    ssl->handshake->client_auth = 1;
+    return( 0 );
+
+decode_error:
+    MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
+                                  MBEDTLS_ERR_SSL_DECODE_ERROR );
+    return( MBEDTLS_ERR_SSL_DECODE_ERROR );
+}
+
+/*
+ * Handler for  MBEDTLS_SSL_CERTIFICATE_REQUEST
+ */
+static int ssl_tls13_process_certificate_request( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
+
+    MBEDTLS_SSL_PROC_CHK_NEG( ssl_tls13_certificate_request_coordinate( ssl ) );
+
+    if( ret == SSL_CERTIFICATE_REQUEST_EXPECT_REQUEST )
+    {
+        unsigned char *buf;
+        size_t buf_len;
+
+        MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_tls13_fetch_handshake_msg( ssl,
+                                            MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
+                                            &buf, &buf_len ) );
+
+        MBEDTLS_SSL_PROC_CHK( ssl_tls13_parse_certificate_request( ssl,
+                                              buf, buf + buf_len ) );
+
+        mbedtls_ssl_tls13_add_hs_msg_to_checksum(
+                       ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, buf, buf_len );
+    }
+    else if( ret == SSL_CERTIFICATE_REQUEST_SKIP )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
+        ret = 0;
+    }
+    else
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+        goto cleanup;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "got %s certificate request",
+                                ssl->handshake->client_auth ? "a" : "no" ) );
+
     mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_CERTIFICATE );
 
-    return( 0 );
+cleanup:
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) );
+    return( ret );
 }
 
 /*
@@ -1877,6 +2057,6 @@
     return( ret );
 }
 
-#endif /* MBEDTLS_SSL_CLI_C */
+#endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_PROTO_TLS1_3 */
 
-#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+
diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c
index 9aa2148..d1646eb 100644
--- a/library/ssl_tls13_generic.c
+++ b/library/ssl_tls13_generic.c
@@ -19,9 +19,7 @@
 
 #include "common.h"
 
-#if defined(MBEDTLS_SSL_TLS_C)
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+#if defined(MBEDTLS_SSL_TLS_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3)
 
 #include <string.h>
 
@@ -136,6 +134,80 @@
 }
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+/* mbedtls_ssl_tls13_parse_sig_alg_ext()
+ *
+ * enum {
+ *    ....
+ *   ecdsa_secp256r1_sha256( 0x0403 ),
+ *   ecdsa_secp384r1_sha384( 0x0503 ),
+ *   ecdsa_secp521r1_sha512( 0x0603 ),
+ *    ....
+ * } SignatureScheme;
+ *
+ * struct {
+ *    SignatureScheme supported_signature_algorithms<2..2^16-2>;
+ * } SignatureSchemeList;
+ */
+int mbedtls_ssl_tls13_parse_sig_alg_ext( mbedtls_ssl_context *ssl,
+                                         const unsigned char *buf,
+                                         const unsigned char *end )
+{
+    const unsigned char *p = buf;
+    size_t supported_sig_algs_len = 0;
+    const unsigned char *supported_sig_algs_end;
+    uint16_t sig_alg;
+    uint32_t common_idx = 0;
+
+    MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, 2 );
+    supported_sig_algs_len = MBEDTLS_GET_UINT16_BE( p, 0 );
+    p += 2;
+
+    memset( ssl->handshake->received_sig_algs, 0,
+            sizeof(ssl->handshake->received_sig_algs) );
+
+    MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, supported_sig_algs_len );
+    supported_sig_algs_end = p + supported_sig_algs_len;
+    while( p < supported_sig_algs_end )
+    {
+        MBEDTLS_SSL_CHK_BUF_READ_PTR( p, supported_sig_algs_end, 2 );
+        sig_alg = MBEDTLS_GET_UINT16_BE( p, 0 );
+        p += 2;
+
+        MBEDTLS_SSL_DEBUG_MSG( 4, ( "received signature algorithm: 0x%x",
+                                    sig_alg ) );
+
+        if( ! mbedtls_ssl_sig_alg_is_offered( ssl, sig_alg ) ||
+            ! mbedtls_ssl_sig_alg_is_supported( ssl, sig_alg ) )
+            continue;
+
+        if( common_idx + 1 < MBEDTLS_RECEIVED_SIG_ALGS_SIZE )
+        {
+            ssl->handshake->received_sig_algs[common_idx] = sig_alg;
+            common_idx += 1;
+        }
+    }
+    /* Check that we consumed all the message. */
+    if( p != end )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1,
+            ( "Signature algorithms extension length misaligned" ) );
+        MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
+                                      MBEDTLS_ERR_SSL_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
+    }
+
+    if( common_idx == 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "no signature algorithm in common" ) );
+        MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
+                                      MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
+    }
+
+    ssl->handshake->received_sig_algs[common_idx] = MBEDTLS_TLS1_3_SIG_NONE;
+    return( 0 );
+}
+
 /*
  * STATE HANDLING: Read CertificateVerify
  */
@@ -1202,6 +1274,4 @@
     return( ret );
 }
 
-#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
-
-#endif /* MBEDTLS_SSL_TLS_C */
+#endif /* MBEDTLS_SSL_TLS_C && MBEDTLS_SSL_PROTO_TLS1_3 */
diff --git a/library/ssl_tls13_invasive.h b/library/ssl_tls13_invasive.h
new file mode 100644
index 0000000..aa35784
--- /dev/null
+++ b/library/ssl_tls13_invasive.h
@@ -0,0 +1,63 @@
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef MBEDTLS_SSL_TLS13_INVASIVE_H
+#define MBEDTLS_SSL_TLS13_INVASIVE_H
+
+#include "common.h"
+
+#if defined(MBEDTLS_PSA_CRYPTO_C)
+#include "psa/crypto.h"
+#endif
+
+#if defined(MBEDTLS_TEST_HOOKS)
+
+#if defined(MBEDTLS_PSA_CRYPTO_C)
+
+/**
+ *  \brief  Expand the supplied \p prk into several additional pseudorandom
+ *          keys, which is the output of the HKDF.
+ *
+ *  \param  alg       The HMAC algorithm to use (\c #PSA_ALG_HMAC( PSA_ALG_XXX )
+ *                    value such that PSA_ALG_XXX is a hash algorithm and
+ *                    #PSA_ALG_IS_HMAC(\p alg) is true).
+ *  \param  prk       A pseudorandom key of \p prk_len bytes. \p prk is
+ *                    usually the output from the HKDF extract step.
+ *  \param  prk_len   The length in bytes of \p prk.
+ *  \param  info      An optional context and application specific information
+ *                    string. This can be a zero-length string.
+ *  \param  info_len  The length of \p info in bytes.
+ *  \param  okm       The output keying material of \p okm_len bytes.
+ *  \param  okm_len   The length of the output keying material in bytes. This
+ *                    must be less than or equal to
+ *                    255 * #PSA_HASH_LENGTH( \p alg ) bytes.
+ *
+ *  \return 0 on success.
+ *  \return #PSA_ERROR_INVALID_ARGUMENT when the parameters are invalid.
+ *  \return An PSA_ERROR_* error for errors returned from the underlying
+ *          PSA layer.
+ */
+psa_status_t mbedtls_psa_hkdf_expand( psa_algorithm_t alg,
+                                      const unsigned char *prk, size_t prk_len,
+                                      const unsigned char *info, size_t info_len,
+                                      unsigned char *okm, size_t okm_len );
+
+#endif /* MBEDTLS_PSA_CRYPTO_C */
+
+#endif /* MBEDTLS_TEST_HOOKS */
+
+#endif /* MBEDTLS_SSL_TLS13_INVASIVE_H */
diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c
index 5615386..885dd16 100644
--- a/library/ssl_tls13_keys.c
+++ b/library/ssl_tls13_keys.c
@@ -30,6 +30,9 @@
 
 #include "ssl_misc.h"
 #include "ssl_tls13_keys.h"
+#include "ssl_tls13_invasive.h"
+
+#include "psa/crypto.h"
 
 #define MBEDTLS_SSL_TLS1_3_LABEL( name, string )       \
     .name = string,
@@ -133,6 +136,131 @@
     *dst_len = total_hkdf_lbl_len;
 }
 
+#if defined( MBEDTLS_TEST_HOOKS )
+
+MBEDTLS_STATIC_TESTABLE
+psa_status_t mbedtls_psa_hkdf_expand( psa_algorithm_t alg,
+                                      const unsigned char *prk, size_t prk_len,
+                                      const unsigned char *info, size_t info_len,
+                                      unsigned char *okm, size_t okm_len )
+{
+    size_t hash_len;
+    size_t where = 0;
+    size_t n;
+    size_t t_len = 0;
+    size_t i;
+    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_status_t destroy_status = PSA_ERROR_CORRUPTION_DETECTED;
+    unsigned char t[PSA_MAC_MAX_SIZE];
+
+    if( okm == NULL )
+    {
+        return( PSA_ERROR_INVALID_ARGUMENT );
+    }
+
+    hash_len = PSA_HASH_LENGTH( alg );
+
+    if( prk_len < hash_len || hash_len == 0 )
+    {
+        return( PSA_ERROR_INVALID_ARGUMENT );
+    }
+
+    if( info == NULL )
+    {
+        info = (const unsigned char *) "";
+        info_len = 0;
+    }
+
+    n = okm_len / hash_len;
+
+    if( okm_len % hash_len != 0 )
+    {
+        n++;
+    }
+
+    /*
+     * Per RFC 5869 Section 2.3, okm_len must not exceed
+     * 255 times the hash length
+     */
+    if( n > 255 )
+    {
+        return( PSA_ERROR_INVALID_ARGUMENT );
+    }
+
+    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_MESSAGE );
+    psa_set_key_algorithm( &attributes, alg );
+    psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC );
+
+    status = psa_import_key( &attributes, prk, prk_len, &key );
+    if( status != PSA_SUCCESS )
+    {
+        goto cleanup;
+    }
+
+    memset( t, 0, hash_len );
+
+    /*
+     * Compute T = T(1) | T(2) | T(3) | ... | T(N)
+     * Where T(N) is defined in RFC 5869 Section 2.3
+     */
+    for( i = 1; i <= n; i++ )
+    {
+        size_t num_to_copy;
+        unsigned char c = i & 0xff;
+        size_t len;
+
+        status = psa_mac_sign_setup( &operation, key, alg );
+        if( status != PSA_SUCCESS )
+        {
+            goto cleanup;
+        }
+
+        status = psa_mac_update( &operation, t, t_len );
+        if( status != PSA_SUCCESS )
+        {
+            goto cleanup;
+        }
+
+        status = psa_mac_update( &operation, info, info_len );
+        if( status != PSA_SUCCESS )
+        {
+            goto cleanup;
+        }
+
+        /* The constant concatenated to the end of each T(n) is a single octet. */
+        status = psa_mac_update( &operation, &c, 1 );
+        if( status != PSA_SUCCESS )
+        {
+            goto cleanup;
+        }
+
+        status = psa_mac_sign_finish( &operation, t, PSA_MAC_MAX_SIZE, &len );
+        if( status != PSA_SUCCESS )
+        {
+            goto cleanup;
+        }
+
+        num_to_copy = i != n ? hash_len : okm_len - where;
+        memcpy( okm + where, t, num_to_copy );
+        where += hash_len;
+        t_len = hash_len;
+    }
+
+cleanup:
+    if( status != PSA_SUCCESS )
+        psa_mac_abort( &operation );
+    destroy_status = psa_destroy_key( key );
+
+    mbedtls_platform_zeroize( t, sizeof( t ) );
+
+    return( ( status == PSA_SUCCESS ) ? destroy_status : status );
+}
+
+#endif /* MBEDTLS_TEST_HOOKS */
+
 int mbedtls_ssl_tls13_hkdf_expand_label(
                      mbedtls_md_type_t hash_alg,
                      const unsigned char *secret, size_t secret_len,
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index 5e74083..b5f3ad7 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -19,9 +19,7 @@
 
 #include "common.h"
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
-
-#if defined(MBEDTLS_SSL_SRV_C)
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3)
 
 #include "mbedtls/debug.h"
 
@@ -38,6 +36,4 @@
     return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
 }
 
-#endif /* MBEDTLS_SSL_SRV_C */
-
-#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_PROTO_TLS1_3 */
diff --git a/programs/.gitignore b/programs/.gitignore
index 550239e..44e904a 100644
--- a/programs/.gitignore
+++ b/programs/.gitignore
@@ -13,8 +13,10 @@
 *.exe
 
 aes/crypt_and_hash
+cipher/cipher_aead_demo
 hash/generic_sum
 hash/hello
+hash/md_hmac_demo
 hash/md5sum
 hash/sha1sum
 hash/sha2sum
@@ -38,7 +40,9 @@
 pkey/rsa_sign_pss
 pkey/rsa_verify
 pkey/rsa_verify_pss
+psa/aead_demo
 psa/crypto_examples
+psa/hmac_demo
 psa/key_ladder_demo
 psa/psa_constant_names
 random/gen_entropy
diff --git a/programs/CMakeLists.txt b/programs/CMakeLists.txt
index a8492c6..0633aa6 100644
--- a/programs/CMakeLists.txt
+++ b/programs/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_subdirectory(aes)
+add_subdirectory(cipher)
 if (NOT WIN32)
     add_subdirectory(fuzz)
 endif()
diff --git a/programs/Makefile b/programs/Makefile
index 1ebf8d2..fdfece7 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -80,8 +80,10 @@
 ## make sure to check that it still works if you tweak the format here.
 APPS = \
 	aes/crypt_and_hash \
+	cipher/cipher_aead_demo \
 	hash/generic_sum \
 	hash/hello \
+	hash/md_hmac_demo \
 	pkey/dh_client \
 	pkey/dh_genprime \
 	pkey/dh_server \
@@ -102,7 +104,9 @@
 	pkey/rsa_sign_pss \
 	pkey/rsa_verify \
 	pkey/rsa_verify_pss \
+	psa/aead_demo \
 	psa/crypto_examples \
+	psa/hmac_demo \
 	psa/key_ladder_demo \
 	psa/psa_constant_names \
 	random/gen_entropy \
@@ -195,14 +199,22 @@
 	echo "  CC    aes/crypt_and_hash.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) aes/crypt_and_hash.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
-hash/hello$(EXEXT): hash/hello.c $(DEP)
-	echo "  CC    hash/hello.c"
-	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) hash/hello.c       $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+cipher/cipher_aead_demo$(EXEXT): cipher/cipher_aead_demo.c $(DEP)
+	echo "  CC    cipher/cipher_aead_demo.c"
+	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) cipher/cipher_aead_demo.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
 hash/generic_sum$(EXEXT): hash/generic_sum.c $(DEP)
 	echo "  CC    hash/generic_sum.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) hash/generic_sum.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
+hash/hello$(EXEXT): hash/hello.c $(DEP)
+	echo "  CC    hash/hello.c"
+	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) hash/hello.c       $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+
+hash/md_hmac_demo$(EXEXT): hash/md_hmac_demo.c $(DEP)
+	echo "  CC    hash/md_hmac_demo.c"
+	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) hash/md_hmac_demo.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+
 pkey/dh_client$(EXEXT): pkey/dh_client.c $(DEP)
 	echo "  CC    pkey/dh_client.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) pkey/dh_client.c   $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
@@ -283,6 +295,18 @@
 	echo "  CC    pkey/rsa_encrypt.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) pkey/rsa_encrypt.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
+psa/aead_demo$(EXEXT): psa/aead_demo.c $(DEP)
+	echo "  CC    psa/aead_demo.c"
+	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/aead_demo.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+
+psa/crypto_examples$(EXEXT): psa/crypto_examples.c $(DEP)
+	echo "  CC    psa/crypto_examples.c"
+	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/crypto_examples.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+
+psa/hmac_demo$(EXEXT): psa/hmac_demo.c $(DEP)
+	echo "  CC    psa/hmac_demo.c"
+	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/hmac_demo.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+
 psa/key_ladder_demo$(EXEXT): psa/key_ladder_demo.c $(DEP)
 	echo "  CC    psa/key_ladder_demo.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/key_ladder_demo.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
@@ -427,10 +451,6 @@
 	echo "  CC    x509/req_app.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) x509/req_app.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
-psa/crypto_examples$(EXEXT): psa/crypto_examples.c $(DEP)
-	echo "  CC    psa/crypto_examples.c"
-	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/crypto_examples.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
-
 clean:
 ifndef WINDOWS
 	rm -f $(EXES)
diff --git a/programs/cipher/CMakeLists.txt b/programs/cipher/CMakeLists.txt
new file mode 100644
index 0000000..93e5f31
--- /dev/null
+++ b/programs/cipher/CMakeLists.txt
@@ -0,0 +1,13 @@
+set(executables
+    cipher_aead_demo
+)
+
+foreach(exe IN LISTS executables)
+    add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
+    target_link_libraries(${exe} ${mbedcrypto_target})
+    target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
+endforeach()
+
+install(TARGETS ${executables}
+        DESTINATION "bin"
+        PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
diff --git a/programs/cipher/cipher_aead_demo.c b/programs/cipher/cipher_aead_demo.c
new file mode 100644
index 0000000..18bd66c
--- /dev/null
+++ b/programs/cipher/cipher_aead_demo.c
@@ -0,0 +1,271 @@
+/**
+ * Cipher API multi-part AEAD demonstration.
+ *
+ * This program AEAD-encrypts a message, using the algorithm and key size
+ * specified on the command line, using the multi-part API.
+ *
+ * It comes with a companion program psa/aead_demo.c, which does the same
+ * operations with the PSA Crypto API. The goal is that comparing the two
+ * programs will help people migrating to the PSA Crypto API.
+ *
+ * When used with multi-part AEAD operations, the `mbedtls_cipher_context`
+ * serves a triple purpose (1) hold the key, (2) store the algorithm when no
+ * operation is active, and (3) save progress information for the current
+ * operation. With PSA those roles are held by disinct objects: (1) a
+ * psa_key_id_t to hold the key, a (2) psa_algorithm_t to represent the
+ * algorithm, and (3) a psa_operation_t for multi-part progress.
+ *
+ * On the other hand, with PSA, the algorithms encodes the desired tag length;
+ * with Cipher the desired tag length needs to be tracked separately.
+ *
+ * This program and its companion psa/aead_demo.c illustrate this by doing the
+ * same sequence of multi-part AEAD computation with both APIs; looking at the
+ * two side by side should make the differences and similarities clear.
+ */
+
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/* First include Mbed TLS headers to get the Mbed TLS configuration and
+ * platform definitions that we'll use in this program. Also include
+ * standard C headers for functions we'll use here. */
+#include "mbedtls/build_info.h"
+
+#include "mbedtls/cipher.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/* If the build options we need are not enabled, compile a placeholder. */
+#if !defined(MBEDTLS_CIPHER_C) || \
+    !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_GCM_C) || \
+    !defined(MBEDTLS_CHACHAPOLY_C)
+int main( void )
+{
+    printf( "MBEDTLS_MD_C and/or "
+            "MBEDTLS_AES_C and/or MBEDTLS_GCM_C and/or "
+            "MBEDTLS_CHACHAPOLY_C not defined\r\n" );
+    return( 0 );
+}
+#else
+
+/* The real program starts here. */
+
+const char usage[] =
+"Usage: cipher_aead_demo [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]";
+
+/* Dummy data for encryption: IV/nonce, additional data, 2-part message */
+const unsigned char iv1[12] = { 0x00 };
+const unsigned char add_data1[] = { 0x01, 0x02 };
+const unsigned char msg1_part1[] = { 0x03, 0x04 };
+const unsigned char msg1_part2[] = { 0x05, 0x06, 0x07 };
+
+/* Dummy data (2nd message) */
+const unsigned char iv2[12] = { 0x10 };
+const unsigned char add_data2[] = { 0x11, 0x12 };
+const unsigned char msg2_part1[] = { 0x13, 0x14 };
+const unsigned char msg2_part2[] = { 0x15, 0x16, 0x17 };
+
+/* Maximum total size of the messages */
+#define MSG1_SIZE ( sizeof( msg1_part1 ) + sizeof( msg1_part2 ) )
+#define MSG2_SIZE ( sizeof( msg2_part1 ) + sizeof( msg2_part2 ) )
+#define MSG_MAX_SIZE ( MSG1_SIZE > MSG2_SIZE ? MSG1_SIZE : MSG2_SIZE )
+
+/* Dummy key material - never do this in production!
+ * 32-byte is enough to all the key size supported by this program. */
+const unsigned char key_bytes[32] = { 0x2a };
+
+/* Print the contents of a buffer in hex */
+void print_buf( const char *title, unsigned char *buf, size_t len )
+{
+    printf( "%s:", title );
+    for( size_t i = 0; i < len; i++ )
+        printf( " %02x", buf[i] );
+    printf( "\n" );
+}
+
+/* Run an Mbed TLS function and bail out if it fails.
+ * A string description of the error code can be recovered with:
+ * programs/util/strerror <value> */
+#define CHK( expr )                                             \
+    do                                                          \
+    {                                                           \
+        ret = ( expr );                                         \
+        if( ret != 0 )                                          \
+        {                                                       \
+            printf( "Error %d at line %d: %s\n",                \
+                    ret,                                        \
+                    __LINE__,                                   \
+                    #expr );                                    \
+            goto exit;                                          \
+        }                                                       \
+    } while( 0 )
+
+/*
+ * Prepare encryption material:
+ * - interpret command-line argument
+ * - set up key
+ * - outputs: context and tag length, which together hold all the information
+ */
+static int aead_prepare( const char *info,
+                           mbedtls_cipher_context_t *ctx,
+                           size_t *tag_len )
+{
+    int ret;
+
+    /* Convert arg to type + tag_len */
+    mbedtls_cipher_type_t type;
+    if( strcmp( info, "aes128-gcm" ) == 0 ) {
+        type = MBEDTLS_CIPHER_AES_128_GCM;
+        *tag_len = 16;
+    } else if( strcmp( info, "aes256-gcm" ) == 0 ) {
+        type = MBEDTLS_CIPHER_AES_256_GCM;
+        *tag_len = 16;
+    } else if( strcmp( info, "aes128-gcm_8" ) == 0 ) {
+        type = MBEDTLS_CIPHER_AES_128_GCM;
+        *tag_len = 8;
+    } else if( strcmp( info, "chachapoly" ) == 0 ) {
+        type = MBEDTLS_CIPHER_CHACHA20_POLY1305;
+        *tag_len = 16;
+    } else {
+        puts( usage );
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    }
+
+    /* Prepare context for the given type */
+    CHK( mbedtls_cipher_setup( ctx,
+                               mbedtls_cipher_info_from_type( type ) ) );
+
+    /* Import key */
+    int key_len = mbedtls_cipher_get_key_bitlen( ctx );
+    CHK( mbedtls_cipher_setkey( ctx, key_bytes, key_len, MBEDTLS_ENCRYPT ) );
+
+exit:
+    return( ret );
+}
+
+/*
+ * Print out some information.
+ *
+ * All of this information was present in the command line argument, but his
+ * function demonstrates how each piece can be recovered from (ctx, tag_len).
+ */
+static void aead_info( const mbedtls_cipher_context_t *ctx, size_t tag_len )
+{
+    mbedtls_cipher_type_t type = mbedtls_cipher_get_type( ctx );
+    const mbedtls_cipher_info_t *info = mbedtls_cipher_info_from_type( type );
+    const char *ciph = mbedtls_cipher_info_get_name( info );
+    int key_bits = mbedtls_cipher_get_key_bitlen( ctx );
+    mbedtls_cipher_mode_t mode = mbedtls_cipher_get_cipher_mode( ctx );
+
+    const char *mode_str = mode == MBEDTLS_MODE_GCM ? "GCM"
+                         : mode == MBEDTLS_MODE_CHACHAPOLY ? "ChachaPoly"
+                         : "???";
+
+    printf( "%s, %d, %s, %u\n",
+            ciph, key_bits, mode_str, (unsigned) tag_len );
+}
+
+/*
+ * Encrypt a 2-part message.
+ */
+static int aead_encrypt( mbedtls_cipher_context_t *ctx, size_t tag_len,
+        const unsigned char *iv, size_t iv_len,
+        const unsigned char *ad, size_t ad_len,
+        const unsigned char *part1, size_t part1_len,
+        const unsigned char *part2, size_t part2_len )
+{
+    int ret;
+    size_t olen;
+#define MAX_TAG_LENGTH 16
+    unsigned char out[MSG_MAX_SIZE + MAX_TAG_LENGTH];
+    unsigned char *p = out;
+
+    CHK( mbedtls_cipher_set_iv( ctx, iv, iv_len ) );
+    CHK( mbedtls_cipher_reset( ctx ) );
+    CHK( mbedtls_cipher_update_ad( ctx, ad, ad_len ) );
+    CHK( mbedtls_cipher_update( ctx, part1, part1_len, p, &olen ) );
+    p += olen;
+    CHK( mbedtls_cipher_update( ctx, part2, part2_len, p, &olen ) );
+    p += olen;
+    CHK( mbedtls_cipher_finish( ctx, p, &olen ) );
+    p += olen;
+    CHK( mbedtls_cipher_write_tag( ctx, p, tag_len ) );
+    p += tag_len;
+
+    olen = p - out;
+    print_buf( "out", out, olen );
+
+exit:
+    return( ret );
+}
+
+/*
+ * AEAD demo: set up key/alg, print out info, encrypt messages.
+ */
+static int aead_demo( const char *info )
+{
+    int ret = 0;
+
+    mbedtls_cipher_context_t ctx;
+    size_t tag_len;
+
+    mbedtls_cipher_init( &ctx );
+
+    CHK( aead_prepare( info, &ctx, &tag_len ) );
+
+    aead_info( &ctx, tag_len );
+
+    CHK( aead_encrypt( &ctx, tag_len,
+                         iv1, sizeof( iv1 ), add_data1, sizeof( add_data1 ),
+                         msg1_part1, sizeof( msg1_part1 ),
+                         msg1_part2, sizeof( msg1_part2 ) ) );
+    CHK( aead_encrypt( &ctx, tag_len,
+                         iv2, sizeof( iv2 ), add_data2, sizeof( add_data2 ),
+                         msg2_part1, sizeof( msg2_part1 ),
+                         msg2_part2, sizeof( msg2_part2 ) ) );
+
+exit:
+    mbedtls_cipher_free( &ctx );
+
+    return( ret );
+}
+
+
+/*
+ * Main function
+ */
+int main( int argc, char **argv )
+{
+    /* Check usage */
+    if( argc != 2 )
+    {
+        puts( usage );
+        return( 1 );
+    }
+
+    int ret;
+
+    /* Run the demo */
+    CHK( aead_demo( argv[1] ) );
+
+exit:
+    return( ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE );
+}
+
+#endif
diff --git a/programs/fuzz/common.c b/programs/fuzz/common.c
index e12ee3b..4d58402 100644
--- a/programs/fuzz/common.c
+++ b/programs/fuzz/common.c
@@ -60,8 +60,14 @@
     size_t i;
 
 #if defined(MBEDTLS_CTR_DRBG_C)
-    //use mbedtls_ctr_drbg_random to find bugs in it
-    ret = mbedtls_ctr_drbg_random(p_rng, output, output_len);
+    //mbedtls_ctr_drbg_random requires a valid mbedtls_ctr_drbg_context in p_rng
+    if( p_rng != NULL ) {
+        //use mbedtls_ctr_drbg_random to find bugs in it
+        ret = mbedtls_ctr_drbg_random(p_rng, output, output_len);
+    } else {
+        //fall through to pseudo-random
+        ret = 0;
+    }
 #else
     (void) p_rng;
     ret = 0;
diff --git a/programs/fuzz/fuzz_dtlsserver.c b/programs/fuzz/fuzz_dtlsserver.c
index 9a6e894..1aa757c 100644
--- a/programs/fuzz/fuzz_dtlsserver.c
+++ b/programs/fuzz/fuzz_dtlsserver.c
@@ -44,6 +44,13 @@
     unsigned char buf[4096];
     fuzzBufferOffset_t biomemfuzz;
 
+    mbedtls_ctr_drbg_init( &ctr_drbg );
+    mbedtls_entropy_init( &entropy );
+
+    if( mbedtls_ctr_drbg_seed( &ctr_drbg, dummy_entropy, &entropy,
+                               ( const unsigned char * ) pers, strlen( pers ) ) != 0 )
+        goto exit;
+
     if (initialized == 0) {
 #if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
         mbedtls_x509_crt_init( &srvcert );
@@ -56,7 +63,7 @@
             return 1;
         if (mbedtls_pk_parse_key( &pkey, (const unsigned char *) mbedtls_test_srv_key,
                                  mbedtls_test_srv_key_len, NULL, 0,
-                                 dummy_random, NULL ) != 0)
+                                 dummy_random, &ctr_drbg ) != 0)
             return 1;
 #endif
         dummy_init();
@@ -65,15 +72,8 @@
     }
     mbedtls_ssl_init( &ssl );
     mbedtls_ssl_config_init( &conf );
-    mbedtls_ctr_drbg_init( &ctr_drbg );
-    mbedtls_entropy_init( &entropy );
     mbedtls_ssl_cookie_init( &cookie_ctx );
 
-    if( mbedtls_ctr_drbg_seed( &ctr_drbg, dummy_entropy, &entropy,
-                              (const unsigned char *) pers, strlen( pers ) ) != 0 )
-        goto exit;
-
-
     if( mbedtls_ssl_config_defaults( &conf,
                                     MBEDTLS_SSL_IS_SERVER,
                                     MBEDTLS_SSL_TRANSPORT_DATAGRAM,
diff --git a/programs/fuzz/fuzz_privkey.c b/programs/fuzz/fuzz_privkey.c
index b9a160e..e8e1d44 100644
--- a/programs/fuzz/fuzz_privkey.c
+++ b/programs/fuzz/fuzz_privkey.c
@@ -2,26 +2,41 @@
 
 #include <stdint.h>
 #include <stdlib.h>
+#include <string.h>
 #include "mbedtls/pk.h"
+#include "mbedtls/entropy.h"
+#include "mbedtls/ctr_drbg.h"
 #include "common.h"
 
 //4 Kb should be enough for every bug ;-)
 #define MAX_LEN 0x1000
 
+#if defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_CTR_DRBG_C)
+const char *pers = "fuzz_privkey";
+#endif // MBEDTLS_PK_PARSE_C && MBEDTLS_CTR_DRBG_C
 
 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
-#ifdef MBEDTLS_PK_PARSE_C
+#if defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_CTR_DRBG_C)
     int ret;
     mbedtls_pk_context pk;
+    mbedtls_ctr_drbg_context ctr_drbg;
+    mbedtls_entropy_context entropy;
 
     if (Size > MAX_LEN) {
         //only work on small inputs
         Size = MAX_LEN;
     }
 
+    mbedtls_ctr_drbg_init( &ctr_drbg );
+    mbedtls_entropy_init( &entropy );
+
+    if( mbedtls_ctr_drbg_seed( &ctr_drbg, dummy_entropy, &entropy,
+                               ( const unsigned char * ) pers, strlen( pers ) ) != 0 )
+        return 1;
+
     mbedtls_pk_init( &pk );
     ret = mbedtls_pk_parse_key( &pk, Data, Size, NULL, 0,
-                                dummy_random, NULL );
+                                dummy_random, &ctr_drbg );
     if (ret == 0) {
 #if defined(MBEDTLS_RSA_C)
         if( mbedtls_pk_get_type( &pk ) == MBEDTLS_PK_RSA )
@@ -73,7 +88,7 @@
 #else
     (void) Data;
     (void) Size;
-#endif //MBEDTLS_PK_PARSE_C
+#endif // MBEDTLS_PK_PARSE_C && MBEDTLS_CTR_DRBG_C
 
     return 0;
 }
diff --git a/programs/fuzz/fuzz_server.c b/programs/fuzz/fuzz_server.c
index e6eb5a7..3d11d47 100644
--- a/programs/fuzz/fuzz_server.c
+++ b/programs/fuzz/fuzz_server.c
@@ -55,13 +55,14 @@
     }
     options = Data[Size - 1];
 
-    if (initialized == 0) {
-        mbedtls_ctr_drbg_init( &ctr_drbg );
-        mbedtls_entropy_init( &entropy );
+    mbedtls_ctr_drbg_init( &ctr_drbg );
+    mbedtls_entropy_init( &entropy );
 
-        if( mbedtls_ctr_drbg_seed( &ctr_drbg, dummy_entropy, &entropy,
-                                  (const unsigned char *) pers, strlen( pers ) ) != 0 )
-            return 1;
+    if( mbedtls_ctr_drbg_seed( &ctr_drbg, dummy_entropy, &entropy,
+                               ( const unsigned char * ) pers, strlen( pers ) ) != 0 )
+        return 1;
+
+    if (initialized == 0) {
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
         mbedtls_x509_crt_init( &srvcert );
diff --git a/programs/hash/CMakeLists.txt b/programs/hash/CMakeLists.txt
index 729474c..da98188 100644
--- a/programs/hash/CMakeLists.txt
+++ b/programs/hash/CMakeLists.txt
@@ -1,6 +1,7 @@
 set(executables
     generic_sum
     hello
+    md_hmac_demo
 )
 
 foreach(exe IN LISTS executables)
diff --git a/programs/hash/md_hmac_demo.c b/programs/hash/md_hmac_demo.c
new file mode 100644
index 0000000..d4cc3cc
--- /dev/null
+++ b/programs/hash/md_hmac_demo.c
@@ -0,0 +1,147 @@
+/**
+ * MD API multi-part HMAC demonstration.
+ *
+ * This programs computes the HMAC of two messages using the multi-part API.
+ *
+ * This is a companion to psa/hmac_demo.c, doing the same operations with the
+ * legacy MD API. The goal is that comparing the two programs will help people
+ * migrating to the PSA Crypto API.
+ *
+ * When it comes to multi-part HMAC operations, the `mbedtls_md_context`
+ * serves a dual purpose (1) hold the key, and (2) save progress information
+ * for the current operation. With PSA those roles are held by two disinct
+ * objects: (1) a psa_key_id_t to hold the key, and (2) a psa_operation_t for
+ * multi-part progress.
+ *
+ * This program and its companion psa/hmac_demo.c illustrate this by doing the
+ * same sequence of multi-part HMAC computation with both APIs; looking at the
+ * two side by side should make the differences and similarities clear.
+ */
+
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/* First include Mbed TLS headers to get the Mbed TLS configuration and
+ * platform definitions that we'll use in this program. Also include
+ * standard C headers for functions we'll use here. */
+#include "mbedtls/build_info.h"
+
+#include "mbedtls/md.h"
+
+#include "mbedtls/platform_util.h" // for mbedtls_platform_zeroize
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/* If the build options we need are not enabled, compile a placeholder. */
+#if !defined(MBEDTLS_MD_C)
+int main( void )
+{
+    printf( "MBEDTLS_MD_C not defined\r\n" );
+    return( 0 );
+}
+#else
+
+/* The real program starts here. */
+
+/* Dummy inputs for HMAC */
+const unsigned char msg1_part1[] = { 0x01, 0x02 };
+const unsigned char msg1_part2[] = { 0x03, 0x04 };
+const unsigned char msg2_part1[] = { 0x05, 0x05 };
+const unsigned char msg2_part2[] = { 0x06, 0x06 };
+
+/* Dummy key material - never do this in production!
+ * This example program uses SHA-256, so a 32-byte key makes sense. */
+const unsigned char key_bytes[32] = { 0 };
+
+/* Print the contents of a buffer in hex */
+void print_buf( const char *title, unsigned char *buf, size_t len )
+{
+    printf( "%s:", title );
+    for( size_t i = 0; i < len; i++ )
+        printf( " %02x", buf[i] );
+    printf( "\n" );
+}
+
+/* Run an Mbed TLS function and bail out if it fails.
+ * A string description of the error code can be recovered with:
+ * programs/util/strerror <value> */
+#define CHK( expr )                                             \
+    do                                                          \
+    {                                                           \
+        ret = ( expr );                                         \
+        if( ret != 0 )                                          \
+        {                                                       \
+            printf( "Error %d at line %d: %s\n",                \
+                    ret,                                        \
+                    __LINE__,                                   \
+                    #expr );                                    \
+            goto exit;                                          \
+        }                                                       \
+    } while( 0 )
+
+/*
+ * This function demonstrates computation of the HMAC of two messages using
+ * the multipart API.
+ */
+int hmac_demo(void)
+{
+    int ret;
+    const mbedtls_md_type_t alg = MBEDTLS_MD_SHA256;
+    unsigned char out[MBEDTLS_MD_MAX_SIZE]; // safe but not optimal
+
+    mbedtls_md_context_t ctx;
+
+    mbedtls_md_init( &ctx );
+
+    /* prepare context and load key */
+    // the last argument to setup is 1 to enable HMAC (not just hashing)
+    const mbedtls_md_info_t *info = mbedtls_md_info_from_type( alg );
+    CHK( mbedtls_md_setup( &ctx, info, 1 ) );
+    CHK( mbedtls_md_hmac_starts( &ctx, key_bytes, sizeof( key_bytes ) ) );
+
+    /* compute HMAC(key, msg1_part1 | msg1_part2) */
+    CHK( mbedtls_md_hmac_update( &ctx, msg1_part1, sizeof( msg1_part1 ) ) );
+    CHK( mbedtls_md_hmac_update( &ctx, msg1_part2, sizeof( msg1_part2 ) ) );
+    CHK( mbedtls_md_hmac_finish( &ctx, out ) );
+    print_buf( "msg1", out, mbedtls_md_get_size( info ) );
+
+    /* compute HMAC(key, msg2_part1 | msg2_part2) */
+    CHK( mbedtls_md_hmac_reset( &ctx ) ); // prepare for new operation
+    CHK( mbedtls_md_hmac_update( &ctx, msg2_part1, sizeof( msg2_part1 ) ) );
+    CHK( mbedtls_md_hmac_update( &ctx, msg2_part2, sizeof( msg2_part2 ) ) );
+    CHK( mbedtls_md_hmac_finish( &ctx, out ) );
+    print_buf( "msg2", out, mbedtls_md_get_size( info ) );
+
+exit:
+    mbedtls_md_free( &ctx );
+    mbedtls_platform_zeroize( out, sizeof( out ) );
+
+    return( ret );
+}
+
+int main(void)
+{
+    int ret;
+
+    CHK( hmac_demo() );
+
+exit:
+    return( ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE );
+}
+
+#endif
diff --git a/programs/psa/CMakeLists.txt b/programs/psa/CMakeLists.txt
index 26ca73c..7ba4af6 100644
--- a/programs/psa/CMakeLists.txt
+++ b/programs/psa/CMakeLists.txt
@@ -1,5 +1,7 @@
 set(executables
+    aead_demo
     crypto_examples
+    hmac_demo
     key_ladder_demo
     psa_constant_names
 )
diff --git a/programs/psa/aead_demo.c b/programs/psa/aead_demo.c
new file mode 100644
index 0000000..5bc0af0
--- /dev/null
+++ b/programs/psa/aead_demo.c
@@ -0,0 +1,293 @@
+/**
+ * PSA API multi-part AEAD demonstration.
+ *
+ * This program AEAD-encrypts a message, using the algorithm and key size
+ * specified on the command line, using the multi-part API.
+ *
+ * It comes with a companion program cipher/cipher_aead_demo.c, which does the
+ * same operations with the legacy Cipher API. The goal is that comparing the
+ * two programs will help people migrating to the PSA Crypto API.
+ *
+ * When used with multi-part AEAD operations, the `mbedtls_cipher_context`
+ * serves a triple purpose (1) hold the key, (2) store the algorithm when no
+ * operation is active, and (3) save progress information for the current
+ * operation. With PSA those roles are held by disinct objects: (1) a
+ * psa_key_id_t to hold the key, a (2) psa_algorithm_t to represent the
+ * algorithm, and (3) a psa_operation_t for multi-part progress.
+ *
+ * On the other hand, with PSA, the algorithms encodes the desired tag length;
+ * with Cipher the desired tag length needs to be tracked separately.
+ *
+ * This program and its companion cipher/cipher_aead_demo.c illustrate this by
+ * doing the same sequence of multi-part AEAD computation with both APIs;
+ * looking at the two side by side should make the differences and
+ * similarities clear.
+ */
+
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/* First include Mbed TLS headers to get the Mbed TLS configuration and
+ * platform definitions that we'll use in this program. Also include
+ * standard C headers for functions we'll use here. */
+#include "mbedtls/build_info.h"
+
+#include "psa/crypto.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/* If the build options we need are not enabled, compile a placeholder. */
+#if !defined(MBEDTLS_PSA_CRYPTO_C) || \
+    !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_GCM_C) || \
+    !defined(MBEDTLS_CHACHAPOLY_C) || \
+    defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
+int main( void )
+{
+    printf( "MBEDTLS_PSA_CRYPTO_C and/or "
+            "MBEDTLS_AES_C and/or MBEDTLS_GCM_C and/or "
+            "MBEDTLS_CHACHAPOLY_C not defined, and/or "
+            "MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined\r\n" );
+    return( 0 );
+}
+#else
+
+/* The real program starts here. */
+
+const char usage[] =
+"Usage: aead_demo [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]";
+
+/* Dummy data for encryption: IV/nonce, additional data, 2-part message */
+const unsigned char iv1[12] = { 0x00 };
+const unsigned char add_data1[] = { 0x01, 0x02 };
+const unsigned char msg1_part1[] = { 0x03, 0x04 };
+const unsigned char msg1_part2[] = { 0x05, 0x06, 0x07 };
+
+/* Dummy data (2nd message) */
+const unsigned char iv2[12] = { 0x10 };
+const unsigned char add_data2[] = { 0x11, 0x12 };
+const unsigned char msg2_part1[] = { 0x13, 0x14 };
+const unsigned char msg2_part2[] = { 0x15, 0x16, 0x17 };
+
+/* Maximum total size of the messages */
+#define MSG1_SIZE ( sizeof( msg1_part1 ) + sizeof( msg1_part2 ) )
+#define MSG2_SIZE ( sizeof( msg2_part1 ) + sizeof( msg2_part2 ) )
+#define MSG_MAX_SIZE ( MSG1_SIZE > MSG2_SIZE ? MSG1_SIZE : MSG2_SIZE )
+
+/* Dummy key material - never do this in production!
+ * 32-byte is enough to all the key size supported by this program. */
+const unsigned char key_bytes[32] = { 0x2a };
+
+/* Print the contents of a buffer in hex */
+void print_buf( const char *title, uint8_t *buf, size_t len )
+{
+    printf( "%s:", title );
+    for( size_t i = 0; i < len; i++ )
+        printf( " %02x", buf[i] );
+    printf( "\n" );
+}
+
+/* Run a PSA function and bail out if it fails.
+ * The symbolic name of the error code can be recovered using:
+ * programs/psa/psa_consant_name status <value> */
+#define PSA_CHECK( expr )                                       \
+    do                                                          \
+    {                                                           \
+        status = ( expr );                                      \
+        if( status != PSA_SUCCESS )                             \
+        {                                                       \
+            printf( "Error %d at line %d: %s\n",                \
+                    (int) status,                               \
+                    __LINE__,                                   \
+                    #expr );                                    \
+            goto exit;                                          \
+        }                                                       \
+    }                                                           \
+    while( 0 )
+
+/*
+ * Prepare encryption material:
+ * - interpret command-line argument
+ * - set up key
+ * - outputs: key and algorithm, which together hold all the information
+ */
+static psa_status_t aead_prepare( const char *info,
+                                  psa_key_id_t *key,
+                                  psa_algorithm_t *alg )
+{
+    psa_status_t status;
+
+    /* Convert arg to alg + key_bits + key_type */
+    size_t key_bits;
+    psa_key_type_t key_type;
+    if( strcmp( info, "aes128-gcm" ) == 0 ) {
+        *alg = PSA_ALG_GCM;
+        key_bits = 128;
+        key_type = PSA_KEY_TYPE_AES;
+    } else if( strcmp( info, "aes256-gcm" ) == 0 ) {
+        *alg = PSA_ALG_GCM;
+        key_bits = 256;
+        key_type = PSA_KEY_TYPE_AES;
+    } else if( strcmp( info, "aes128-gcm_8" ) == 0 ) {
+        *alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 8);
+        key_bits = 128;
+        key_type = PSA_KEY_TYPE_AES;
+    } else if( strcmp( info, "chachapoly" ) == 0 ) {
+        *alg = PSA_ALG_CHACHA20_POLY1305;
+        key_bits = 256;
+        key_type = PSA_KEY_TYPE_CHACHA20;
+    } else {
+        puts( usage );
+        return( PSA_ERROR_INVALID_ARGUMENT );
+    }
+
+    /* Prepare key attibutes */
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
+    psa_set_key_algorithm( &attributes, *alg );
+    psa_set_key_type( &attributes, key_type );
+    psa_set_key_bits( &attributes, key_bits ); // optional
+
+    /* Import key */
+    PSA_CHECK( psa_import_key( &attributes, key_bytes, key_bits / 8, key ) );
+
+exit:
+    return( status );
+}
+
+/*
+ * Print out some information.
+ *
+ * All of this information was present in the command line argument, but his
+ * function demonstrates how each piece can be recovered from (key, alg).
+ */
+static void aead_info( psa_key_id_t key, psa_algorithm_t alg )
+{
+    psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
+    (void) psa_get_key_attributes( key, &attr );
+    psa_key_type_t key_type = psa_get_key_type( &attr );
+    size_t key_bits = psa_get_key_bits( &attr );
+    psa_algorithm_t base_alg = PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG( alg );
+    size_t tag_len = PSA_AEAD_TAG_LENGTH( key_type, key_bits, alg );
+
+    const char *type_str = key_type == PSA_KEY_TYPE_AES ? "AES"
+                         : key_type == PSA_KEY_TYPE_CHACHA20 ? "Chacha"
+                         : "???";
+    const char *base_str = base_alg == PSA_ALG_GCM ? "GCM"
+                         : base_alg == PSA_ALG_CHACHA20_POLY1305 ? "ChachaPoly"
+                         : "???";
+
+    printf( "%s, %u, %s, %u\n",
+            type_str, (unsigned) key_bits, base_str, (unsigned) tag_len );
+}
+
+/*
+ * Encrypt a 2-part message.
+ */
+static int aead_encrypt( psa_key_id_t key, psa_algorithm_t alg,
+        const unsigned char *iv, size_t iv_len,
+        const unsigned char *ad, size_t ad_len,
+        const unsigned char *part1, size_t part1_len,
+        const unsigned char *part2, size_t part2_len )
+{
+    psa_status_t status;
+    size_t olen, olen_tag;
+    unsigned char out[PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(MSG_MAX_SIZE)];
+    unsigned char *p = out, *end = out + sizeof( out );
+    unsigned char tag[PSA_AEAD_TAG_MAX_SIZE];
+
+    psa_aead_operation_t op = PSA_AEAD_OPERATION_INIT;
+    PSA_CHECK( psa_aead_encrypt_setup( &op, key, alg ) );
+
+    PSA_CHECK( psa_aead_set_nonce( &op, iv, iv_len ) );
+    PSA_CHECK( psa_aead_update_ad( &op, ad, ad_len ) );
+    PSA_CHECK( psa_aead_update( &op, part1, part1_len, p, end - p, &olen ) );
+    p += olen;
+    PSA_CHECK( psa_aead_update( &op, part2, part2_len, p, end - p, &olen ) );
+    p += olen;
+    PSA_CHECK( psa_aead_finish( &op, p, end - p, &olen,
+                               tag, sizeof( tag ), &olen_tag ) );
+    p += olen;
+    memcpy( p, tag, olen_tag );
+    p += olen_tag;
+
+    olen = p - out;
+    print_buf( "out", out, olen );
+
+exit:
+    psa_aead_abort( &op ); // required on errors, harmless on success
+    return( status );
+}
+
+/*
+ * AEAD demo: set up key/alg, print out info, encrypt messages.
+ */
+static psa_status_t aead_demo( const char *info )
+{
+    psa_status_t status;
+
+    psa_key_id_t key;
+    psa_algorithm_t alg;
+
+    PSA_CHECK( aead_prepare( info, &key, &alg ) );
+
+    aead_info( key, alg );
+
+    PSA_CHECK( aead_encrypt( key, alg,
+                       iv1, sizeof( iv1 ), add_data1, sizeof( add_data1 ),
+                       msg1_part1, sizeof( msg1_part1 ),
+                       msg1_part2, sizeof( msg1_part2 ) ) );
+    PSA_CHECK( aead_encrypt( key, alg,
+                       iv2, sizeof( iv2 ), add_data2, sizeof( add_data2 ),
+                       msg2_part1, sizeof( msg2_part1 ),
+                       msg2_part2, sizeof( msg2_part2 ) ) );
+
+exit:
+    psa_destroy_key( key );
+
+    return( status );
+}
+
+/*
+ * Main function
+ */
+int main( int argc, char **argv )
+{
+    psa_status_t status = PSA_SUCCESS;
+
+    /* Check usage */
+    if( argc != 2 )
+    {
+        puts( usage );
+        return( EXIT_FAILURE );
+    }
+
+    /* Initialize the PSA crypto library. */
+    PSA_CHECK( psa_crypto_init( ) );
+
+    /* Run the demo */
+    PSA_CHECK( aead_demo( argv[1] ) );
+
+    /* Deinitialize the PSA crypto library. */
+    mbedtls_psa_crypto_free( );
+
+exit:
+    return( status == PSA_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE );
+}
+
+#endif
diff --git a/programs/psa/hmac_demo.c b/programs/psa/hmac_demo.c
new file mode 100644
index 0000000..aa56b41
--- /dev/null
+++ b/programs/psa/hmac_demo.c
@@ -0,0 +1,169 @@
+/**
+ * PSA API multi-part HMAC demonstration.
+ *
+ * This programs computes the HMAC of two messages using the multi-part API.
+ *
+ * It comes with a companion program hash/md_hmac_demo.c, which does the same
+ * operations with the legacy MD API. The goal is that comparing the two
+ * programs will help people migrating to the PSA Crypto API.
+ *
+ * When it comes to multi-part HMAC operations, the `mbedtls_md_context`
+ * serves a dual purpose (1) hold the key, and (2) save progress information
+ * for the current operation. With PSA those roles are held by two disinct
+ * objects: (1) a psa_key_id_t to hold the key, and (2) a psa_operation_t for
+ * multi-part progress.
+ *
+ * This program and its companion hash/md_hmac_demo.c illustrate this by doing
+ * the same sequence of multi-part HMAC computation with both APIs; looking at
+ * the two side by side should make the differences and similarities clear.
+ */
+
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/* First include Mbed TLS headers to get the Mbed TLS configuration and
+ * platform definitions that we'll use in this program. Also include
+ * standard C headers for functions we'll use here. */
+#include "mbedtls/build_info.h"
+
+#include "psa/crypto.h"
+
+#include "mbedtls/platform_util.h" // for mbedtls_platform_zeroize
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/* If the build options we need are not enabled, compile a placeholder. */
+#if !defined(MBEDTLS_PSA_CRYPTO_C) || \
+    defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
+int main( void )
+{
+    printf( "MBEDTLS_PSA_CRYPTO_C not defined, "
+            "and/or MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined\r\n" );
+    return( 0 );
+}
+#else
+
+/* The real program starts here. */
+
+/* Dummy inputs for HMAC */
+const unsigned char msg1_part1[] = { 0x01, 0x02 };
+const unsigned char msg1_part2[] = { 0x03, 0x04 };
+const unsigned char msg2_part1[] = { 0x05, 0x05 };
+const unsigned char msg2_part2[] = { 0x06, 0x06 };
+
+/* Dummy key material - never do this in production!
+ * This example program uses SHA-256, so a 32-byte key makes sense. */
+const unsigned char key_bytes[32] = { 0 };
+
+/* Print the contents of a buffer in hex */
+void print_buf( const char *title, uint8_t *buf, size_t len )
+{
+    printf( "%s:", title );
+    for( size_t i = 0; i < len; i++ )
+        printf( " %02x", buf[i] );
+    printf( "\n" );
+}
+
+/* Run a PSA function and bail out if it fails.
+ * The symbolic name of the error code can be recovered using:
+ * programs/psa/psa_consant_name status <value> */
+#define PSA_CHECK( expr )                                       \
+    do                                                          \
+    {                                                           \
+        status = ( expr );                                      \
+        if( status != PSA_SUCCESS )                             \
+        {                                                       \
+            printf( "Error %d at line %d: %s\n",                \
+                    (int) status,                               \
+                    __LINE__,                                   \
+                    #expr );                                    \
+            goto exit;                                          \
+        }                                                       \
+    }                                                           \
+    while( 0 )
+
+/*
+ * This function demonstrates computation of the HMAC of two messages using
+ * the multipart API.
+ */
+psa_status_t hmac_demo(void)
+{
+    psa_status_t status;
+    const psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
+    uint8_t out[PSA_MAC_MAX_SIZE]; // safe but not optimal
+    /* PSA_MAC_LENGTH(PSA_KEY_TYPE_HMAC, 8 * sizeof( key_bytes ), alg)
+     * should work but see https://github.com/ARMmbed/mbedtls/issues/4320 */
+
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_key_id_t key = 0;
+
+    /* prepare key */
+    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_MESSAGE );
+    psa_set_key_algorithm( &attributes, alg );
+    psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC );
+    psa_set_key_bits( &attributes, 8 * sizeof( key_bytes ) ); // optional
+
+    status = psa_import_key( &attributes,
+                             key_bytes, sizeof( key_bytes ), &key );
+    if( status != PSA_SUCCESS )
+        return( status );
+
+    /* prepare operation */
+    psa_mac_operation_t op = PSA_MAC_OPERATION_INIT;
+    size_t out_len = 0;
+
+    /* compute HMAC(key, msg1_part1 | msg1_part2) */
+    PSA_CHECK( psa_mac_sign_setup( &op, key, alg ) );
+    PSA_CHECK( psa_mac_update( &op, msg1_part1, sizeof( msg1_part1 ) ) );
+    PSA_CHECK( psa_mac_update( &op, msg1_part2, sizeof( msg1_part2 ) ) );
+    PSA_CHECK( psa_mac_sign_finish( &op, out, sizeof( out ), &out_len ) );
+    print_buf( "msg1", out, out_len );
+
+    /* compute HMAC(key, msg2_part1 | msg2_part2) */
+    PSA_CHECK( psa_mac_sign_setup( &op, key, alg ) );
+    PSA_CHECK( psa_mac_update( &op, msg2_part1, sizeof( msg2_part1 ) ) );
+    PSA_CHECK( psa_mac_update( &op, msg2_part2, sizeof( msg2_part2 ) ) );
+    PSA_CHECK( psa_mac_sign_finish( &op, out, sizeof( out ), &out_len ) );
+    print_buf( "msg2", out, out_len );
+
+exit:
+    psa_mac_abort( &op ); // needed on error, harmless on success
+    psa_destroy_key( key );
+    mbedtls_platform_zeroize( out, sizeof( out ) );
+
+    return( status );
+}
+
+int main(void)
+{
+    psa_status_t status = PSA_SUCCESS;
+
+    /* Initialize the PSA crypto library. */
+    PSA_CHECK( psa_crypto_init( ) );
+
+    /* Run the demo */
+    PSA_CHECK( hmac_demo() );
+
+    /* Deinitialize the PSA crypto library. */
+    mbedtls_psa_crypto_free( );
+
+exit:
+    return( status == PSA_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE );
+}
+
+#endif
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index c77119b..595300e 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -119,6 +119,7 @@
 #define DFL_MFL_CODE            MBEDTLS_SSL_MAX_FRAG_LEN_NONE
 #define DFL_TRUNC_HMAC          -1
 #define DFL_TICKETS             MBEDTLS_SSL_SESSION_TICKETS_ENABLED
+#define DFL_TICKET_ROTATE       0
 #define DFL_TICKET_TIMEOUT      86400
 #define DFL_TICKET_AEAD         MBEDTLS_CIPHER_AES_256_GCM
 #define DFL_CACHE_MAX           -1
@@ -286,6 +287,7 @@
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
 #define USAGE_TICKETS                                       \
     "    tickets=%%d          default: 1 (enabled)\n"       \
+    "    ticket_rotate=%%d    default: 0 (disabled)\n"      \
     "    ticket_timeout=%%d   default: 86400 (one day)\n"   \
     "    ticket_aead=%%s      default: \"AES-256-GCM\"\n"
 #else
@@ -613,6 +615,7 @@
     unsigned char mfl_code;     /* code for maximum fragment length         */
     int trunc_hmac;             /* accept truncated hmac?                   */
     int tickets;                /* enable / disable session tickets         */
+    int ticket_rotate;          /* session ticket rotate (code coverage)    */
     int ticket_timeout;         /* session ticket lifetime                  */
     int ticket_aead;            /* session ticket protection                */
     int cache_max;              /* max number of session cache entries      */
@@ -1542,6 +1545,7 @@
     opt.mfl_code            = DFL_MFL_CODE;
     opt.trunc_hmac          = DFL_TRUNC_HMAC;
     opt.tickets             = DFL_TICKETS;
+    opt.ticket_rotate       = DFL_TICKET_ROTATE;
     opt.ticket_timeout      = DFL_TICKET_TIMEOUT;
     opt.ticket_aead         = DFL_TICKET_AEAD;
     opt.cache_max           = DFL_CACHE_MAX;
@@ -1915,6 +1919,12 @@
             if( opt.tickets < 0 || opt.tickets > 1 )
                 goto usage;
         }
+        else if( strcmp( p, "ticket_rotate" ) == 0 )
+        {
+            opt.ticket_rotate = atoi( q );
+            if( opt.ticket_rotate < 0 || opt.ticket_rotate > 1 )
+                goto usage;
+        }
         else if( strcmp( p, "ticket_timeout" ) == 0 )
         {
             opt.ticket_timeout = atoi( q );
@@ -2737,6 +2747,23 @@
                 mbedtls_ssl_ticket_write,
                 mbedtls_ssl_ticket_parse,
                 &ticket_ctx );
+
+        /* exercise manual ticket rotation (not required for typical use)
+         * (used for external synchronization of session ticket encryption keys)
+         */
+        if( opt.ticket_rotate ) {
+            unsigned char kbuf[MBEDTLS_SSL_TICKET_MAX_KEY_BYTES];
+            unsigned char name[MBEDTLS_SSL_TICKET_KEY_NAME_BYTES];
+            if( ( ret = rng_get( &rng, name, sizeof( name ) ) ) != 0 ||
+                ( ret = rng_get( &rng, kbuf, sizeof( kbuf ) ) ) != 0 ||
+                ( ret = mbedtls_ssl_ticket_rotate( &ticket_ctx,
+                        name, sizeof(name), kbuf, sizeof(kbuf),
+                        opt.ticket_timeout ) ) != 0 )
+            {
+                mbedtls_printf( " failed\n  ! mbedtls_ssl_ticket_rotate returned %d\n\n", ret );
+                goto exit;
+            }
+        }
     }
 #endif
 
diff --git a/scripts/driver.requirements.txt b/scripts/driver.requirements.txt
index 17569bb..38838f5 100644
--- a/scripts/driver.requirements.txt
+++ b/scripts/driver.requirements.txt
@@ -1,10 +1,16 @@
 # Python package requirements for driver implementers.
 
+# Jinja2 <3.0 needs an older version of markupsafe, but does not
+# declare it.
+#   https://github.com/pallets/markupsafe/issues/282
+#   https://github.com/pallets/jinja/issues/1585
+markupsafe < 2.1
+
 # Use the version of Jinja that's in Ubuntu 20.04.
 # See https://github.com/ARMmbed/mbedtls/pull/5067#discussion_r738794607 .
 # Note that Jinja 3.0 drops support for Python 3.5, so we need to support
 # Jinja 2.x as long as we're still using Python 3.5 anywhere.
 Jinja2 >= 2.10.1
-# Jinja2 >=2.10, <<3.0 needs a separate package for type annotations
+# Jinja2 >=2.10, <3.0 needs a separate package for type annotations
 types-Jinja2
 
diff --git a/tests/configs/tls13-only.h b/tests/configs/tls13-only.h
new file mode 100644
index 0000000..0a22c54
--- /dev/null
+++ b/tests/configs/tls13-only.h
@@ -0,0 +1,34 @@
+/* MBEDTLS_USER_CONFIG_FILE for testing.
+ * Only used for a few test configurations.
+ *
+ * Typical usage (note multiple levels of quoting):
+ *     make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
+ */
+
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#define MBEDTLS_SSL_PROTO_TLS1_3
+#define MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+
+#undef MBEDTLS_SSL_ENCRYPT_THEN_MAC
+#undef MBEDTLS_SSL_EXTENDED_MASTER_SECRET
+#undef MBEDTLS_SSL_PROTO_TLS1_2
+#undef MBEDTLS_SSL_PROTO_DTLS
+#undef MBEDTLS_SSL_DTLS_ANTI_REPLAY
+#undef MBEDTLS_SSL_DTLS_HELLO_VERIFY
+#undef MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
diff --git a/tests/opt-testcases/tls13-compat.sh b/tests/opt-testcases/tls13-compat.sh
index ed60686..f5989ba 100755
--- a/tests/opt-testcases/tls13-compat.sh
+++ b/tests/opt-testcases/tls13-compat.sh
@@ -29,7 +29,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_GCM_SHA256,secp256r1,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_GCM_SHA256 -sigalgs ecdsa_secp256r1_sha256 -groups P-256 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -47,7 +46,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_GCM_SHA256,secp256r1,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+AES-128-GCM:+GROUP-SECP256R1:+SHA256:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -63,7 +61,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_GCM_SHA256,secp384r1,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_GCM_SHA256 -sigalgs ecdsa_secp256r1_sha256 -groups P-384 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -81,7 +78,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_GCM_SHA256,secp384r1,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+AES-128-GCM:+GROUP-SECP384R1:+SHA256:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -97,7 +93,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_GCM_SHA256,secp521r1,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_GCM_SHA256 -sigalgs ecdsa_secp256r1_sha256 -groups P-521 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -115,7 +110,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_GCM_SHA256,secp521r1,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+AES-128-GCM:+GROUP-SECP521R1:+SHA256:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -131,7 +125,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_GCM_SHA256,x25519,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_GCM_SHA256 -sigalgs ecdsa_secp256r1_sha256 -groups X25519 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -149,7 +142,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_GCM_SHA256,x25519,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+AES-128-GCM:+GROUP-X25519:+SHA256:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -165,7 +157,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_GCM_SHA256,x448,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_GCM_SHA256 -sigalgs ecdsa_secp256r1_sha256 -groups X448 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -183,7 +174,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_GCM_SHA256,x448,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+AES-128-GCM:+GROUP-X448:+SHA256:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -199,7 +189,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_GCM_SHA256,secp256r1,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_GCM_SHA256 -sigalgs ecdsa_secp384r1_sha384 -groups P-256 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -217,7 +206,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_GCM_SHA256,secp256r1,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+AES-128-GCM:+GROUP-SECP256R1:+SHA256:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -233,7 +221,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_GCM_SHA256,secp384r1,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_GCM_SHA256 -sigalgs ecdsa_secp384r1_sha384 -groups P-384 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -251,7 +238,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_GCM_SHA256,secp384r1,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+AES-128-GCM:+GROUP-SECP384R1:+SHA256:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -267,7 +253,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_GCM_SHA256,secp521r1,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_GCM_SHA256 -sigalgs ecdsa_secp384r1_sha384 -groups P-521 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -285,7 +270,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_GCM_SHA256,secp521r1,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+AES-128-GCM:+GROUP-SECP521R1:+SHA256:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -301,7 +285,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_GCM_SHA256,x25519,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_GCM_SHA256 -sigalgs ecdsa_secp384r1_sha384 -groups X25519 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -319,7 +302,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_GCM_SHA256,x25519,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+AES-128-GCM:+GROUP-X25519:+SHA256:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -335,7 +317,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_GCM_SHA256,x448,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_GCM_SHA256 -sigalgs ecdsa_secp384r1_sha384 -groups X448 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -353,7 +334,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_GCM_SHA256,x448,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+AES-128-GCM:+GROUP-X448:+SHA256:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -369,7 +349,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_GCM_SHA256,secp256r1,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_GCM_SHA256 -sigalgs ecdsa_secp521r1_sha512 -groups P-256 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -387,7 +366,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_GCM_SHA256,secp256r1,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+AES-128-GCM:+GROUP-SECP256R1:+SHA256:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -403,7 +381,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_GCM_SHA256,secp384r1,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_GCM_SHA256 -sigalgs ecdsa_secp521r1_sha512 -groups P-384 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -421,7 +398,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_GCM_SHA256,secp384r1,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+AES-128-GCM:+GROUP-SECP384R1:+SHA256:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -437,7 +413,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_GCM_SHA256,secp521r1,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_GCM_SHA256 -sigalgs ecdsa_secp521r1_sha512 -groups P-521 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -455,7 +430,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_GCM_SHA256,secp521r1,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+AES-128-GCM:+GROUP-SECP521R1:+SHA256:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -471,7 +445,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_GCM_SHA256,x25519,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_GCM_SHA256 -sigalgs ecdsa_secp521r1_sha512 -groups X25519 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -489,7 +462,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_GCM_SHA256,x25519,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+AES-128-GCM:+GROUP-X25519:+SHA256:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -505,7 +477,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_GCM_SHA256,x448,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_GCM_SHA256 -sigalgs ecdsa_secp521r1_sha512 -groups X448 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -523,7 +494,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_GCM_SHA256,x448,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+AES-128-GCM:+GROUP-X448:+SHA256:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -539,7 +509,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_AES_128_GCM_SHA256,secp256r1,rsa_pss_rsae_sha256" \
@@ -558,7 +527,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_AES_128_GCM_SHA256,secp256r1,rsa_pss_rsae_sha256" \
@@ -575,7 +543,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_AES_128_GCM_SHA256,secp384r1,rsa_pss_rsae_sha256" \
@@ -594,7 +561,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_AES_128_GCM_SHA256,secp384r1,rsa_pss_rsae_sha256" \
@@ -611,7 +577,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_AES_128_GCM_SHA256,secp521r1,rsa_pss_rsae_sha256" \
@@ -630,7 +595,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_AES_128_GCM_SHA256,secp521r1,rsa_pss_rsae_sha256" \
@@ -647,7 +611,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_AES_128_GCM_SHA256,x25519,rsa_pss_rsae_sha256" \
@@ -666,7 +629,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_AES_128_GCM_SHA256,x25519,rsa_pss_rsae_sha256" \
@@ -683,7 +645,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_AES_128_GCM_SHA256,x448,rsa_pss_rsae_sha256" \
@@ -702,7 +663,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_AES_128_GCM_SHA256,x448,rsa_pss_rsae_sha256" \
@@ -719,7 +679,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_256_GCM_SHA384,secp256r1,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_AES_256_GCM_SHA384 -sigalgs ecdsa_secp256r1_sha256 -groups P-256 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -737,7 +696,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_256_GCM_SHA384,secp256r1,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+AES-256-GCM:+GROUP-SECP256R1:+SHA384:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -753,7 +711,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_256_GCM_SHA384,secp384r1,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_AES_256_GCM_SHA384 -sigalgs ecdsa_secp256r1_sha256 -groups P-384 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -771,7 +728,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_256_GCM_SHA384,secp384r1,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+AES-256-GCM:+GROUP-SECP384R1:+SHA384:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -787,7 +743,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_256_GCM_SHA384,secp521r1,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_AES_256_GCM_SHA384 -sigalgs ecdsa_secp256r1_sha256 -groups P-521 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -805,7 +760,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_256_GCM_SHA384,secp521r1,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+AES-256-GCM:+GROUP-SECP521R1:+SHA384:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -821,7 +775,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_256_GCM_SHA384,x25519,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_AES_256_GCM_SHA384 -sigalgs ecdsa_secp256r1_sha256 -groups X25519 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -839,7 +792,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_256_GCM_SHA384,x25519,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+AES-256-GCM:+GROUP-X25519:+SHA384:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -855,7 +807,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_256_GCM_SHA384,x448,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_AES_256_GCM_SHA384 -sigalgs ecdsa_secp256r1_sha256 -groups X448 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -873,7 +824,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_256_GCM_SHA384,x448,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+AES-256-GCM:+GROUP-X448:+SHA384:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -889,7 +839,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_256_GCM_SHA384,secp256r1,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_AES_256_GCM_SHA384 -sigalgs ecdsa_secp384r1_sha384 -groups P-256 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -907,7 +856,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_256_GCM_SHA384,secp256r1,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+AES-256-GCM:+GROUP-SECP256R1:+SHA384:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -923,7 +871,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_256_GCM_SHA384,secp384r1,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_AES_256_GCM_SHA384 -sigalgs ecdsa_secp384r1_sha384 -groups P-384 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -941,7 +888,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_256_GCM_SHA384,secp384r1,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+AES-256-GCM:+GROUP-SECP384R1:+SHA384:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -957,7 +903,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_256_GCM_SHA384,secp521r1,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_AES_256_GCM_SHA384 -sigalgs ecdsa_secp384r1_sha384 -groups P-521 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -975,7 +920,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_256_GCM_SHA384,secp521r1,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+AES-256-GCM:+GROUP-SECP521R1:+SHA384:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -991,7 +935,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_256_GCM_SHA384,x25519,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_AES_256_GCM_SHA384 -sigalgs ecdsa_secp384r1_sha384 -groups X25519 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1009,7 +952,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_256_GCM_SHA384,x25519,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+AES-256-GCM:+GROUP-X25519:+SHA384:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1025,7 +967,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_256_GCM_SHA384,x448,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_AES_256_GCM_SHA384 -sigalgs ecdsa_secp384r1_sha384 -groups X448 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1043,7 +984,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_256_GCM_SHA384,x448,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+AES-256-GCM:+GROUP-X448:+SHA384:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1059,7 +999,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_256_GCM_SHA384,secp256r1,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_AES_256_GCM_SHA384 -sigalgs ecdsa_secp521r1_sha512 -groups P-256 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1077,7 +1016,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_256_GCM_SHA384,secp256r1,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+AES-256-GCM:+GROUP-SECP256R1:+SHA384:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1093,7 +1031,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_256_GCM_SHA384,secp384r1,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_AES_256_GCM_SHA384 -sigalgs ecdsa_secp521r1_sha512 -groups P-384 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1111,7 +1048,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_256_GCM_SHA384,secp384r1,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+AES-256-GCM:+GROUP-SECP384R1:+SHA384:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1127,7 +1063,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_256_GCM_SHA384,secp521r1,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_AES_256_GCM_SHA384 -sigalgs ecdsa_secp521r1_sha512 -groups P-521 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1145,7 +1080,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_256_GCM_SHA384,secp521r1,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+AES-256-GCM:+GROUP-SECP521R1:+SHA384:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1161,7 +1095,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_256_GCM_SHA384,x25519,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_AES_256_GCM_SHA384 -sigalgs ecdsa_secp521r1_sha512 -groups X25519 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1179,7 +1112,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_256_GCM_SHA384,x25519,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+AES-256-GCM:+GROUP-X25519:+SHA384:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1195,7 +1127,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_256_GCM_SHA384,x448,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_AES_256_GCM_SHA384 -sigalgs ecdsa_secp521r1_sha512 -groups X448 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1213,7 +1144,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_256_GCM_SHA384,x448,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+AES-256-GCM:+GROUP-X448:+SHA384:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1229,7 +1159,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_AES_256_GCM_SHA384,secp256r1,rsa_pss_rsae_sha256" \
@@ -1248,7 +1177,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_AES_256_GCM_SHA384,secp256r1,rsa_pss_rsae_sha256" \
@@ -1265,7 +1193,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_AES_256_GCM_SHA384,secp384r1,rsa_pss_rsae_sha256" \
@@ -1284,7 +1211,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_AES_256_GCM_SHA384,secp384r1,rsa_pss_rsae_sha256" \
@@ -1301,7 +1227,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_AES_256_GCM_SHA384,secp521r1,rsa_pss_rsae_sha256" \
@@ -1320,7 +1245,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_AES_256_GCM_SHA384,secp521r1,rsa_pss_rsae_sha256" \
@@ -1337,7 +1261,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_AES_256_GCM_SHA384,x25519,rsa_pss_rsae_sha256" \
@@ -1356,7 +1279,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_AES_256_GCM_SHA384,x25519,rsa_pss_rsae_sha256" \
@@ -1373,7 +1295,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_AES_256_GCM_SHA384,x448,rsa_pss_rsae_sha256" \
@@ -1392,7 +1313,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_AES_256_GCM_SHA384,x448,rsa_pss_rsae_sha256" \
@@ -1409,7 +1329,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_CHACHA20_POLY1305_SHA256,secp256r1,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_CHACHA20_POLY1305_SHA256 -sigalgs ecdsa_secp256r1_sha256 -groups P-256 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1427,7 +1346,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_CHACHA20_POLY1305_SHA256,secp256r1,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+CHACHA20-POLY1305:+GROUP-SECP256R1:+SHA256:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1443,7 +1361,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_CHACHA20_POLY1305_SHA256,secp384r1,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_CHACHA20_POLY1305_SHA256 -sigalgs ecdsa_secp256r1_sha256 -groups P-384 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1461,7 +1378,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_CHACHA20_POLY1305_SHA256,secp384r1,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+CHACHA20-POLY1305:+GROUP-SECP384R1:+SHA256:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1477,7 +1393,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_CHACHA20_POLY1305_SHA256,secp521r1,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_CHACHA20_POLY1305_SHA256 -sigalgs ecdsa_secp256r1_sha256 -groups P-521 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1495,7 +1410,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_CHACHA20_POLY1305_SHA256,secp521r1,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+CHACHA20-POLY1305:+GROUP-SECP521R1:+SHA256:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1511,7 +1425,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_CHACHA20_POLY1305_SHA256,x25519,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_CHACHA20_POLY1305_SHA256 -sigalgs ecdsa_secp256r1_sha256 -groups X25519 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1529,7 +1442,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_CHACHA20_POLY1305_SHA256,x25519,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+CHACHA20-POLY1305:+GROUP-X25519:+SHA256:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1545,7 +1457,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_CHACHA20_POLY1305_SHA256,x448,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_CHACHA20_POLY1305_SHA256 -sigalgs ecdsa_secp256r1_sha256 -groups X448 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1563,7 +1474,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_CHACHA20_POLY1305_SHA256,x448,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+CHACHA20-POLY1305:+GROUP-X448:+SHA256:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1579,7 +1489,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_CHACHA20_POLY1305_SHA256,secp256r1,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_CHACHA20_POLY1305_SHA256 -sigalgs ecdsa_secp384r1_sha384 -groups P-256 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1597,7 +1506,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_CHACHA20_POLY1305_SHA256,secp256r1,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+CHACHA20-POLY1305:+GROUP-SECP256R1:+SHA256:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1613,7 +1521,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_CHACHA20_POLY1305_SHA256,secp384r1,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_CHACHA20_POLY1305_SHA256 -sigalgs ecdsa_secp384r1_sha384 -groups P-384 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1631,7 +1538,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_CHACHA20_POLY1305_SHA256,secp384r1,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+CHACHA20-POLY1305:+GROUP-SECP384R1:+SHA256:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1647,7 +1553,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_CHACHA20_POLY1305_SHA256,secp521r1,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_CHACHA20_POLY1305_SHA256 -sigalgs ecdsa_secp384r1_sha384 -groups P-521 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1665,7 +1570,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_CHACHA20_POLY1305_SHA256,secp521r1,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+CHACHA20-POLY1305:+GROUP-SECP521R1:+SHA256:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1681,7 +1585,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_CHACHA20_POLY1305_SHA256,x25519,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_CHACHA20_POLY1305_SHA256 -sigalgs ecdsa_secp384r1_sha384 -groups X25519 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1699,7 +1602,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_CHACHA20_POLY1305_SHA256,x25519,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+CHACHA20-POLY1305:+GROUP-X25519:+SHA256:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1715,7 +1617,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_CHACHA20_POLY1305_SHA256,x448,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_CHACHA20_POLY1305_SHA256 -sigalgs ecdsa_secp384r1_sha384 -groups X448 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1733,7 +1634,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_CHACHA20_POLY1305_SHA256,x448,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+CHACHA20-POLY1305:+GROUP-X448:+SHA256:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1749,7 +1649,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_CHACHA20_POLY1305_SHA256,secp256r1,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_CHACHA20_POLY1305_SHA256 -sigalgs ecdsa_secp521r1_sha512 -groups P-256 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1767,7 +1666,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_CHACHA20_POLY1305_SHA256,secp256r1,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+CHACHA20-POLY1305:+GROUP-SECP256R1:+SHA256:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1783,7 +1681,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_CHACHA20_POLY1305_SHA256,secp384r1,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_CHACHA20_POLY1305_SHA256 -sigalgs ecdsa_secp521r1_sha512 -groups P-384 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1801,7 +1698,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_CHACHA20_POLY1305_SHA256,secp384r1,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+CHACHA20-POLY1305:+GROUP-SECP384R1:+SHA256:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1817,7 +1713,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_CHACHA20_POLY1305_SHA256,secp521r1,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_CHACHA20_POLY1305_SHA256 -sigalgs ecdsa_secp521r1_sha512 -groups P-521 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1835,7 +1730,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_CHACHA20_POLY1305_SHA256,secp521r1,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+CHACHA20-POLY1305:+GROUP-SECP521R1:+SHA256:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1851,7 +1745,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_CHACHA20_POLY1305_SHA256,x25519,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_CHACHA20_POLY1305_SHA256 -sigalgs ecdsa_secp521r1_sha512 -groups X25519 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1869,7 +1762,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_CHACHA20_POLY1305_SHA256,x25519,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+CHACHA20-POLY1305:+GROUP-X25519:+SHA256:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1885,7 +1777,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_CHACHA20_POLY1305_SHA256,x448,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_CHACHA20_POLY1305_SHA256 -sigalgs ecdsa_secp521r1_sha512 -groups X448 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -1903,7 +1794,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_CHACHA20_POLY1305_SHA256,x448,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+CHACHA20-POLY1305:+GROUP-X448:+SHA256:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -1919,7 +1809,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_CHACHA20_POLY1305_SHA256,secp256r1,rsa_pss_rsae_sha256" \
@@ -1938,7 +1827,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_CHACHA20_POLY1305_SHA256,secp256r1,rsa_pss_rsae_sha256" \
@@ -1955,7 +1843,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_CHACHA20_POLY1305_SHA256,secp384r1,rsa_pss_rsae_sha256" \
@@ -1974,7 +1861,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_CHACHA20_POLY1305_SHA256,secp384r1,rsa_pss_rsae_sha256" \
@@ -1991,7 +1877,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_CHACHA20_POLY1305_SHA256,secp521r1,rsa_pss_rsae_sha256" \
@@ -2010,7 +1895,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_CHACHA20_POLY1305_SHA256,secp521r1,rsa_pss_rsae_sha256" \
@@ -2027,7 +1911,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_CHACHA20_POLY1305_SHA256,x25519,rsa_pss_rsae_sha256" \
@@ -2046,7 +1929,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_CHACHA20_POLY1305_SHA256,x25519,rsa_pss_rsae_sha256" \
@@ -2063,7 +1945,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_CHACHA20_POLY1305_SHA256,x448,rsa_pss_rsae_sha256" \
@@ -2082,7 +1963,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_CHACHA20_POLY1305_SHA256,x448,rsa_pss_rsae_sha256" \
@@ -2099,7 +1979,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_SHA256,secp256r1,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_SHA256 -sigalgs ecdsa_secp256r1_sha256 -groups P-256 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2117,7 +1996,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_SHA256,secp256r1,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+AES-128-CCM:+GROUP-SECP256R1:+SHA256:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2133,7 +2011,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_SHA256,secp384r1,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_SHA256 -sigalgs ecdsa_secp256r1_sha256 -groups P-384 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2151,7 +2028,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_SHA256,secp384r1,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+AES-128-CCM:+GROUP-SECP384R1:+SHA256:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2167,7 +2043,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_SHA256,secp521r1,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_SHA256 -sigalgs ecdsa_secp256r1_sha256 -groups P-521 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2185,7 +2060,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_SHA256,secp521r1,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+AES-128-CCM:+GROUP-SECP521R1:+SHA256:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2201,7 +2075,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_SHA256,x25519,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_SHA256 -sigalgs ecdsa_secp256r1_sha256 -groups X25519 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2219,7 +2092,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_SHA256,x25519,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+AES-128-CCM:+GROUP-X25519:+SHA256:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2235,7 +2107,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_SHA256,x448,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_SHA256 -sigalgs ecdsa_secp256r1_sha256 -groups X448 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2253,7 +2124,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_SHA256,x448,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+AES-128-CCM:+GROUP-X448:+SHA256:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2269,7 +2139,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_SHA256,secp256r1,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_SHA256 -sigalgs ecdsa_secp384r1_sha384 -groups P-256 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2287,7 +2156,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_SHA256,secp256r1,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+AES-128-CCM:+GROUP-SECP256R1:+SHA256:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2303,7 +2171,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_SHA256,secp384r1,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_SHA256 -sigalgs ecdsa_secp384r1_sha384 -groups P-384 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2321,7 +2188,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_SHA256,secp384r1,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+AES-128-CCM:+GROUP-SECP384R1:+SHA256:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2337,7 +2203,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_SHA256,secp521r1,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_SHA256 -sigalgs ecdsa_secp384r1_sha384 -groups P-521 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2355,7 +2220,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_SHA256,secp521r1,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+AES-128-CCM:+GROUP-SECP521R1:+SHA256:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2371,7 +2235,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_SHA256,x25519,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_SHA256 -sigalgs ecdsa_secp384r1_sha384 -groups X25519 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2389,7 +2252,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_SHA256,x25519,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+AES-128-CCM:+GROUP-X25519:+SHA256:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2405,7 +2267,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_SHA256,x448,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_SHA256 -sigalgs ecdsa_secp384r1_sha384 -groups X448 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2423,7 +2284,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_SHA256,x448,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+AES-128-CCM:+GROUP-X448:+SHA256:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2439,7 +2299,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_SHA256,secp256r1,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_SHA256 -sigalgs ecdsa_secp521r1_sha512 -groups P-256 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2457,7 +2316,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_SHA256,secp256r1,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+AES-128-CCM:+GROUP-SECP256R1:+SHA256:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2473,7 +2331,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_SHA256,secp384r1,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_SHA256 -sigalgs ecdsa_secp521r1_sha512 -groups P-384 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2491,7 +2348,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_SHA256,secp384r1,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+AES-128-CCM:+GROUP-SECP384R1:+SHA256:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2507,7 +2363,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_SHA256,secp521r1,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_SHA256 -sigalgs ecdsa_secp521r1_sha512 -groups P-521 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2525,7 +2380,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_SHA256,secp521r1,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+AES-128-CCM:+GROUP-SECP521R1:+SHA256:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2541,7 +2395,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_SHA256,x25519,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_SHA256 -sigalgs ecdsa_secp521r1_sha512 -groups X25519 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2559,7 +2412,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_SHA256,x25519,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+AES-128-CCM:+GROUP-X25519:+SHA256:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2575,7 +2427,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_SHA256,x448,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_SHA256 -sigalgs ecdsa_secp521r1_sha512 -groups X448 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2593,7 +2444,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_SHA256,x448,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+AES-128-CCM:+GROUP-X448:+SHA256:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2609,7 +2459,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_SHA256,secp256r1,rsa_pss_rsae_sha256" \
@@ -2628,7 +2477,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_SHA256,secp256r1,rsa_pss_rsae_sha256" \
@@ -2645,7 +2493,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_SHA256,secp384r1,rsa_pss_rsae_sha256" \
@@ -2664,7 +2511,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_SHA256,secp384r1,rsa_pss_rsae_sha256" \
@@ -2681,7 +2527,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_SHA256,secp521r1,rsa_pss_rsae_sha256" \
@@ -2700,7 +2545,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_SHA256,secp521r1,rsa_pss_rsae_sha256" \
@@ -2717,7 +2561,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_SHA256,x25519,rsa_pss_rsae_sha256" \
@@ -2736,7 +2579,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_SHA256,x25519,rsa_pss_rsae_sha256" \
@@ -2753,7 +2595,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_SHA256,x448,rsa_pss_rsae_sha256" \
@@ -2772,7 +2613,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_SHA256,x448,rsa_pss_rsae_sha256" \
@@ -2789,7 +2629,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_8_SHA256,secp256r1,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_8_SHA256 -sigalgs ecdsa_secp256r1_sha256 -groups P-256 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2807,7 +2646,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_8_SHA256,secp256r1,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+AES-128-CCM-8:+GROUP-SECP256R1:+SHA256:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2823,7 +2661,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_8_SHA256,secp384r1,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_8_SHA256 -sigalgs ecdsa_secp256r1_sha256 -groups P-384 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2841,7 +2678,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_8_SHA256,secp384r1,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+AES-128-CCM-8:+GROUP-SECP384R1:+SHA256:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2857,7 +2693,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_8_SHA256,secp521r1,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_8_SHA256 -sigalgs ecdsa_secp256r1_sha256 -groups P-521 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2875,7 +2710,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_8_SHA256,secp521r1,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+AES-128-CCM-8:+GROUP-SECP521R1:+SHA256:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2891,7 +2725,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_8_SHA256,x25519,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_8_SHA256 -sigalgs ecdsa_secp256r1_sha256 -groups X25519 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2909,7 +2742,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_8_SHA256,x25519,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+AES-128-CCM-8:+GROUP-X25519:+SHA256:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2925,7 +2757,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_8_SHA256,x448,ecdsa_secp256r1_sha256" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp256r1.crt -key data_files/ecdsa_secp256r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_8_SHA256 -sigalgs ecdsa_secp256r1_sha256 -groups X448 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2943,7 +2774,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_8_SHA256,x448,ecdsa_secp256r1_sha256" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp256r1.crt --x509keyfile data_files/ecdsa_secp256r1.key --priority=NONE:+AEAD:+AES-128-CCM-8:+GROUP-X448:+SHA256:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2959,7 +2789,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_8_SHA256,secp256r1,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_8_SHA256 -sigalgs ecdsa_secp384r1_sha384 -groups P-256 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -2977,7 +2806,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_8_SHA256,secp256r1,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+AES-128-CCM-8:+GROUP-SECP256R1:+SHA256:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -2993,7 +2821,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_8_SHA256,secp384r1,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_8_SHA256 -sigalgs ecdsa_secp384r1_sha384 -groups P-384 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -3011,7 +2838,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_8_SHA256,secp384r1,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+AES-128-CCM-8:+GROUP-SECP384R1:+SHA256:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -3027,7 +2853,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_8_SHA256,secp521r1,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_8_SHA256 -sigalgs ecdsa_secp384r1_sha384 -groups P-521 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -3045,7 +2870,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_8_SHA256,secp521r1,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+AES-128-CCM-8:+GROUP-SECP521R1:+SHA256:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -3061,7 +2885,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_8_SHA256,x25519,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_8_SHA256 -sigalgs ecdsa_secp384r1_sha384 -groups X25519 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -3079,7 +2902,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_8_SHA256,x25519,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+AES-128-CCM-8:+GROUP-X25519:+SHA256:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -3095,7 +2917,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_8_SHA256,x448,ecdsa_secp384r1_sha384" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp384r1.crt -key data_files/ecdsa_secp384r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_8_SHA256 -sigalgs ecdsa_secp384r1_sha384 -groups X448 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -3113,7 +2934,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_8_SHA256,x448,ecdsa_secp384r1_sha384" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp384r1.crt --x509keyfile data_files/ecdsa_secp384r1.key --priority=NONE:+AEAD:+AES-128-CCM-8:+GROUP-X448:+SHA256:+SIGN-ECDSA-SECP384R1-SHA384:+VERS-TLS1.3:%NO_TICKETS" \
@@ -3129,7 +2949,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_8_SHA256,secp256r1,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_8_SHA256 -sigalgs ecdsa_secp521r1_sha512 -groups P-256 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -3147,7 +2966,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_8_SHA256,secp256r1,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+AES-128-CCM-8:+GROUP-SECP256R1:+SHA256:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -3163,7 +2981,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_8_SHA256,secp384r1,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_8_SHA256 -sigalgs ecdsa_secp521r1_sha512 -groups P-384 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -3181,7 +2998,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_8_SHA256,secp384r1,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+AES-128-CCM-8:+GROUP-SECP384R1:+SHA256:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -3197,7 +3013,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_8_SHA256,secp521r1,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_8_SHA256 -sigalgs ecdsa_secp521r1_sha512 -groups P-521 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -3215,7 +3030,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_8_SHA256,secp521r1,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+AES-128-CCM-8:+GROUP-SECP521R1:+SHA256:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -3231,7 +3045,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_8_SHA256,x25519,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_8_SHA256 -sigalgs ecdsa_secp521r1_sha512 -groups X25519 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -3249,7 +3062,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_8_SHA256,x25519,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+AES-128-CCM-8:+GROUP-X25519:+SHA256:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -3265,7 +3077,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_8_SHA256,x448,ecdsa_secp521r1_sha512" \
          "$O_NEXT_SRV_NO_CERT -cert data_files/ecdsa_secp521r1.crt -key data_files/ecdsa_secp521r1.key -accept $SRV_PORT -ciphersuites TLS_AES_128_CCM_8_SHA256 -sigalgs ecdsa_secp521r1_sha512 -groups X448 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -3283,7 +3094,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_8_SHA256,x448,ecdsa_secp521r1_sha512" \
          "$G_NEXT_SRV_NO_CERT --http --disable-client-cert --debug=4 --x509certfile data_files/ecdsa_secp521r1.crt --x509keyfile data_files/ecdsa_secp521r1.key --priority=NONE:+AEAD:+AES-128-CCM-8:+GROUP-X448:+SHA256:+SIGN-ECDSA-SECP521R1-SHA512:+VERS-TLS1.3:%NO_TICKETS" \
@@ -3299,7 +3109,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_8_SHA256,secp256r1,rsa_pss_rsae_sha256" \
@@ -3318,7 +3127,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_8_SHA256,secp256r1,rsa_pss_rsae_sha256" \
@@ -3335,7 +3143,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_8_SHA256,secp384r1,rsa_pss_rsae_sha256" \
@@ -3354,7 +3161,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_8_SHA256,secp384r1,rsa_pss_rsae_sha256" \
@@ -3371,7 +3177,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_8_SHA256,secp521r1,rsa_pss_rsae_sha256" \
@@ -3390,7 +3195,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_8_SHA256,secp521r1,rsa_pss_rsae_sha256" \
@@ -3407,7 +3211,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_8_SHA256,x25519,rsa_pss_rsae_sha256" \
@@ -3426,7 +3229,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_8_SHA256,x25519,rsa_pss_rsae_sha256" \
@@ -3443,7 +3245,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->O: TLS_AES_128_CCM_8_SHA256,x448,rsa_pss_rsae_sha256" \
@@ -3462,7 +3263,6 @@
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
 run_test "TLS 1.3 m->G: TLS_AES_128_CCM_8_SHA256,x448,rsa_pss_rsae_sha256" \
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index bd38cdb..0c2d9dd 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -2705,6 +2705,17 @@
     armc6_build_test "--target=aarch64-arm-none-eabi -march=armv8.2-a"
 }
 
+component_test_tls13_only () {
+    msg "build: default config with MBEDTLS_SSL_PROTO_TLS1_3, without MBEDTLS_SSL_PROTO_TLS1_2"
+    make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
+
+    msg "test: default config with MBEDTLS_SSL_PROTO_TLS1_3 enabled, without MBEDTLS_SSL_PROTO_TLS1_2"
+    if_build_succeeded make test
+
+    msg "ssl-opt.sh (TLS 1.3)"
+    if_build_succeeded tests/ssl-opt.sh
+}
+
 component_test_tls13 () {
     msg "build: default config with MBEDTLS_SSL_PROTO_TLS1_3 enabled, without padding"
     scripts/config.py set MBEDTLS_SSL_PROTO_TLS1_3
diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py
index 73f16bd..d06a059 100755
--- a/tests/scripts/analyze_outcomes.py
+++ b/tests/scripts/analyze_outcomes.py
@@ -7,7 +7,6 @@
 """
 
 import argparse
-import re
 import sys
 import traceback
 
@@ -51,29 +50,9 @@
         """
         return len(self.successes) + len(self.failures)
 
-class TestDescriptions(check_test_cases.TestDescriptionExplorer):
-    """Collect the available test cases."""
-
-    def __init__(self):
-        super().__init__()
-        self.descriptions = set()
-
-    def process_test_case(self, _per_file_state,
-                          file_name, _line_number, description):
-        """Record an available test case."""
-        base_name = re.sub(r'\.[^.]*$', '', re.sub(r'.*/', '', file_name))
-        key = ';'.join([base_name, description.decode('utf-8')])
-        self.descriptions.add(key)
-
-def collect_available_test_cases():
-    """Collect the available test cases."""
-    explorer = TestDescriptions()
-    explorer.walk_all()
-    return sorted(explorer.descriptions)
-
 def analyze_coverage(results, outcomes):
     """Check that all available test cases are executed at least once."""
-    available = collect_available_test_cases()
+    available = check_test_cases.collect_available_test_cases()
     for key in available:
         hits = outcomes[key].hits() if key in outcomes else 0
         if hits == 0:
diff --git a/tests/scripts/check_test_cases.py b/tests/scripts/check_test_cases.py
index f9ae36c..d84ed04 100755
--- a/tests/scripts/check_test_cases.py
+++ b/tests/scripts/check_test_cases.py
@@ -137,6 +137,26 @@
                                                             '*.sh')):
                 self.walk_ssl_opt_sh(ssl_opt_file_name)
 
+class TestDescriptions(TestDescriptionExplorer):
+    """Collect the available test cases."""
+
+    def __init__(self):
+        super().__init__()
+        self.descriptions = set()
+
+    def process_test_case(self, _per_file_state,
+                          file_name, _line_number, description):
+        """Record an available test case."""
+        base_name = re.sub(r'\.[^.]*$', '', re.sub(r'.*/', '', file_name))
+        key = ';'.join([base_name, description.decode('utf-8')])
+        self.descriptions.add(key)
+
+def collect_available_test_cases():
+    """Collect the available test cases."""
+    explorer = TestDescriptions()
+    explorer.walk_all()
+    return sorted(explorer.descriptions)
+
 class DescriptionChecker(TestDescriptionExplorer):
     """Check all test case descriptions.
 
@@ -176,6 +196,9 @@
 
 def main():
     parser = argparse.ArgumentParser(description=__doc__)
+    parser.add_argument('--list-all',
+                        action='store_true',
+                        help='List all test cases, without doing checks')
     parser.add_argument('--quiet', '-q',
                         action='store_true',
                         help='Hide warnings')
@@ -183,6 +206,10 @@
                         action='store_false', dest='quiet',
                         help='Show warnings (default: on; undoes --quiet)')
     options = parser.parse_args()
+    if options.list_all:
+        descriptions = collect_available_test_cases()
+        sys.stdout.write('\n'.join(descriptions + ['']))
+        return
     results = Results(options)
     checker = DescriptionChecker(results)
     checker.walk_all()
diff --git a/tests/scripts/generate_tls13_compat_tests.py b/tests/scripts/generate_tls13_compat_tests.py
index a6d2fe7..2e6ff72 100755
--- a/tests/scripts/generate_tls13_compat_tests.py
+++ b/tests/scripts/generate_tls13_compat_tests.py
@@ -278,8 +278,7 @@
     def pre_checks(self):
         ret = ['requires_config_enabled MBEDTLS_DEBUG_C',
                'requires_config_enabled MBEDTLS_SSL_CLI_C',
-               'requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3',
-               'requires_config_disabled MBEDTLS_USE_PSA_CRYPTO']
+               'requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3']
 
         if self._compat_mode:
             ret += ['requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE']
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 299cbbd..dd05716 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -543,16 +543,18 @@
 
 # record_outcome <outcome> [<failure-reason>]
 # The test name must be in $NAME.
+# Use $TEST_SUITE_NAME as the test suite name if set.
 record_outcome() {
     echo "$1"
     if [ -n "$MBEDTLS_TEST_OUTCOME_FILE" ]; then
         printf '%s;%s;%s;%s;%s;%s\n' \
                "$MBEDTLS_TEST_PLATFORM" "$MBEDTLS_TEST_CONFIGURATION" \
-               "ssl-opt" "$NAME" \
+               "${TEST_SUITE_NAME:-ssl-opt}" "$NAME" \
                "$1" "${2-}" \
                >>"$MBEDTLS_TEST_OUTCOME_FILE"
     fi
 }
+unset TEST_SUITE_NAME
 
 # True if the presence of the given pattern in a log definitely indicates
 # that the test has failed. False if the presence is inconclusive.
@@ -1190,6 +1192,7 @@
 }
 
 run_test_psa() {
+    requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
     requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
     run_test    "PSA-supported ciphersuite: $1" \
                 "$P_SRV debug_level=3 force_version=tls12" \
@@ -1209,6 +1212,7 @@
 }
 
 run_test_psa_force_curve() {
+    requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
     requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
     run_test    "PSA - ECDH with $1" \
                 "$P_SRV debug_level=4 force_version=tls12 curves=$1" \
@@ -1443,6 +1447,7 @@
 # - things work with all ciphersuites active (used with config-full in all.sh)
 # - the expected parameters are selected
 #   ("signature_algorithm ext: 6" means SHA-512 (highest common hash))
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Default" \
             "$P_SRV debug_level=3" \
             "$P_CLI" \
@@ -1454,6 +1459,7 @@
             -S "error" \
             -C "error"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Default, DTLS" \
             "$P_SRV dtls=1" \
             "$P_CLI dtls=1" \
@@ -1461,12 +1467,14 @@
             -s "Protocol is DTLSv1.2" \
             -s "Ciphersuite is TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "TLS client auth: required" \
             "$P_SRV auth_mode=required" \
             "$P_CLI" \
             0 \
             -s "Verifying peer X.509 certificate... ok"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "key size: TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256" \
             "$P_SRV" \
             "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256" \
@@ -1474,6 +1482,7 @@
             -c "Ciphersuite is TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256" \
             -c "Key size is 256"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "key size: TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8" \
             "$P_SRV" \
             "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8" \
@@ -1481,6 +1490,7 @@
             -c "Ciphersuite is TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8" \
             -c "Key size is 128"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_X509_CRT_PARSE_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SHA256_C
@@ -1489,6 +1499,7 @@
             "$P_CLI crt_file=data_files/server5.crt key_file=data_files/server5.key.enc key_pwd=PolarSSLTest" \
             0
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_X509_CRT_PARSE_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SHA256_C
@@ -1497,6 +1508,7 @@
             "$P_CLI" \
             0
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_X509_CRT_PARSE_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_RSA_C
@@ -1508,6 +1520,7 @@
             "$P_CLI" \
             0
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
 run_test    "CA callback on client" \
             "$P_SRV debug_level=3" \
@@ -1517,6 +1530,7 @@
             -S "error" \
             -C "error"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
 requires_config_enabled MBEDTLS_X509_CRT_PARSE_C
 requires_config_enabled MBEDTLS_ECDSA_C
@@ -1532,6 +1546,7 @@
             -C "error"
 
 # Test using an opaque private key for client authentication
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_X509_CRT_PARSE_C
 requires_config_enabled MBEDTLS_ECDSA_C
@@ -1550,6 +1565,7 @@
             -C "error"
 
 # Test using an opaque private key for server authentication
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_X509_CRT_PARSE_C
 requires_config_enabled MBEDTLS_ECDSA_C
@@ -1568,6 +1584,7 @@
             -C "error"
 
 # Test using an opaque private key for client/server authentication
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_X509_CRT_PARSE_C
 requires_config_enabled MBEDTLS_ECDSA_C
@@ -1628,6 +1645,7 @@
 run_test_psa_force_curve "secp192k1"
 
 # Test current time in ServerHello
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_HAVE_TIME
 run_test    "ServerHello contains gmt_unix_time" \
             "$P_SRV debug_level=3" \
@@ -1637,6 +1655,7 @@
             -F "check_server_hello_time"
 
 # Test for uniqueness of IVs in AEAD ciphersuites
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Unique IV in GCM" \
             "$P_SRV exchanges=20 debug_level=4" \
             "$P_CLI exchanges=20 debug_level=4 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384" \
@@ -1645,6 +1664,7 @@
             -U "IV used"
 
 # Tests for certificate verification callback
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Configuration-specific CRT verification callback" \
             "$P_SRV debug_level=3" \
             "$P_CLI context_crt_cb=0 debug_level=3" \
@@ -1655,6 +1675,7 @@
             -C "Use context-specific verification callback" \
             -C "error"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Context-specific CRT verification callback" \
             "$P_SRV debug_level=3" \
             "$P_CLI context_crt_cb=1 debug_level=3" \
@@ -1666,33 +1687,39 @@
             -C "error"
 
 # Tests for SHA-1 support
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SHA-1 forbidden by default in server certificate" \
             "$P_SRV key_file=data_files/server2.key crt_file=data_files/server2.crt" \
             "$P_CLI debug_level=2 allow_sha1=0" \
             1 \
             -c "The certificate is signed with an unacceptable hash"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SHA-1 explicitly allowed in server certificate" \
             "$P_SRV key_file=data_files/server2.key crt_file=data_files/server2.crt" \
             "$P_CLI allow_sha1=1" \
             0
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SHA-256 allowed by default in server certificate" \
             "$P_SRV key_file=data_files/server2.key crt_file=data_files/server2-sha256.crt" \
             "$P_CLI allow_sha1=0" \
             0
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SHA-1 forbidden by default in client certificate" \
             "$P_SRV auth_mode=required allow_sha1=0" \
             "$P_CLI key_file=data_files/cli-rsa.key crt_file=data_files/cli-rsa-sha1.crt" \
             1 \
             -s "The certificate is signed with an unacceptable hash"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SHA-1 explicitly allowed in client certificate" \
             "$P_SRV auth_mode=required allow_sha1=1" \
             "$P_CLI key_file=data_files/cli-rsa.key crt_file=data_files/cli-rsa-sha1.crt" \
             0
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SHA-256 allowed by default in client certificate" \
             "$P_SRV auth_mode=required allow_sha1=0" \
             "$P_CLI key_file=data_files/cli-rsa.key crt_file=data_files/cli-rsa-sha256.crt" \
@@ -1701,31 +1728,37 @@
 # Dummy TLS 1.3 test
 # Currently only checking that passing TLS 1.3 key exchange modes to
 # ssl_client2/ssl_server2 example programs works.
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
 run_test    "TLS 1.3, key exchange mode parameter passing: PSK only" \
-            "$P_SRV tls13_kex_modes=psk" \
-            "$P_CLI tls13_kex_modes=psk" \
+            "$P_SRV tls13_kex_modes=psk debug_level=4" \
+            "$P_CLI tls13_kex_modes=psk debug_level=4" \
             0
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
 run_test    "TLS 1.3, key exchange mode parameter passing: PSK-ephemeral only" \
             "$P_SRV tls13_kex_modes=psk_ephemeral" \
             "$P_CLI tls13_kex_modes=psk_ephemeral" \
             0
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
 run_test    "TLS 1.3, key exchange mode parameter passing: Pure-ephemeral only" \
             "$P_SRV tls13_kex_modes=ephemeral" \
             "$P_CLI tls13_kex_modes=ephemeral" \
             0
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
 run_test    "TLS 1.3, key exchange mode parameter passing: All ephemeral" \
             "$P_SRV tls13_kex_modes=ephemeral_all" \
             "$P_CLI tls13_kex_modes=ephemeral_all" \
             0
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
 run_test    "TLS 1.3, key exchange mode parameter passing: All PSK" \
             "$P_SRV tls13_kex_modes=psk_all" \
             "$P_CLI tls13_kex_modes=psk_all" \
             0
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
 run_test    "TLS 1.3, key exchange mode parameter passing: All" \
             "$P_SRV tls13_kex_modes=all" \
@@ -1733,6 +1766,7 @@
             0
 
 # Tests for datagram packing
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS: multiple records in same datagram, client and server" \
             "$P_SRV dtls=1 dgram_packing=1 debug_level=2" \
             "$P_CLI dtls=1 dgram_packing=1 debug_level=2" \
@@ -1740,6 +1774,7 @@
             -c "next record in same datagram" \
             -s "next record in same datagram"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS: multiple records in same datagram, client only" \
             "$P_SRV dtls=1 dgram_packing=0 debug_level=2" \
             "$P_CLI dtls=1 dgram_packing=1 debug_level=2" \
@@ -1747,6 +1782,7 @@
             -s "next record in same datagram" \
             -C "next record in same datagram"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS: multiple records in same datagram, server only" \
             "$P_SRV dtls=1 dgram_packing=1 debug_level=2" \
             "$P_CLI dtls=1 dgram_packing=0 debug_level=2" \
@@ -1754,6 +1790,7 @@
             -S "next record in same datagram" \
             -c "next record in same datagram"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS: multiple records in same datagram, neither client nor server" \
             "$P_SRV dtls=1 dgram_packing=0 debug_level=2" \
             "$P_CLI dtls=1 dgram_packing=0 debug_level=2" \
@@ -1763,6 +1800,7 @@
 
 # Tests for Context serialization
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 run_test    "Context serialization, client serializes, CCM" \
             "$P_SRV dtls=1 serialize=0 exchanges=2" \
@@ -1771,6 +1809,7 @@
             -c "Deserializing connection..." \
             -S "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 run_test    "Context serialization, client serializes, ChaChaPoly" \
             "$P_SRV dtls=1 serialize=0 exchanges=2" \
@@ -1779,6 +1818,7 @@
             -c "Deserializing connection..." \
             -S "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 run_test    "Context serialization, client serializes, GCM" \
             "$P_SRV dtls=1 serialize=0 exchanges=2" \
@@ -1787,6 +1827,7 @@
             -c "Deserializing connection..." \
             -S "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Context serialization, client serializes, with CID" \
@@ -1796,6 +1837,7 @@
             -c "Deserializing connection..." \
             -S "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 run_test    "Context serialization, server serializes, CCM" \
             "$P_SRV dtls=1 serialize=1 exchanges=2" \
@@ -1804,6 +1846,7 @@
             -C "Deserializing connection..." \
             -s "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 run_test    "Context serialization, server serializes, ChaChaPoly" \
             "$P_SRV dtls=1 serialize=1 exchanges=2" \
@@ -1812,6 +1855,7 @@
             -C "Deserializing connection..." \
             -s "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 run_test    "Context serialization, server serializes, GCM" \
             "$P_SRV dtls=1 serialize=1 exchanges=2" \
@@ -1820,6 +1864,7 @@
             -C "Deserializing connection..." \
             -s "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Context serialization, server serializes, with CID" \
@@ -1829,6 +1874,7 @@
             -C "Deserializing connection..." \
             -s "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 run_test    "Context serialization, both serialize, CCM" \
             "$P_SRV dtls=1 serialize=1 exchanges=2" \
@@ -1837,6 +1883,7 @@
             -c "Deserializing connection..." \
             -s "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 run_test    "Context serialization, both serialize, ChaChaPoly" \
             "$P_SRV dtls=1 serialize=1 exchanges=2" \
@@ -1845,6 +1892,7 @@
             -c "Deserializing connection..." \
             -s "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 run_test    "Context serialization, both serialize, GCM" \
             "$P_SRV dtls=1 serialize=1 exchanges=2" \
@@ -1853,6 +1901,7 @@
             -c "Deserializing connection..." \
             -s "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Context serialization, both serialize, with CID" \
@@ -1862,6 +1911,7 @@
             -c "Deserializing connection..." \
             -s "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 run_test    "Context serialization, re-init, client serializes, CCM" \
             "$P_SRV dtls=1 serialize=0 exchanges=2" \
@@ -1870,6 +1920,7 @@
             -c "Deserializing connection..." \
             -S "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 run_test    "Context serialization, re-init, client serializes, ChaChaPoly" \
             "$P_SRV dtls=1 serialize=0 exchanges=2" \
@@ -1878,6 +1929,7 @@
             -c "Deserializing connection..." \
             -S "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 run_test    "Context serialization, re-init, client serializes, GCM" \
             "$P_SRV dtls=1 serialize=0 exchanges=2" \
@@ -1886,6 +1938,7 @@
             -c "Deserializing connection..." \
             -S "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Context serialization, re-init, client serializes, with CID" \
@@ -1895,6 +1948,7 @@
             -c "Deserializing connection..." \
             -S "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 run_test    "Context serialization, re-init, server serializes, CCM" \
             "$P_SRV dtls=1 serialize=2 exchanges=2" \
@@ -1903,6 +1957,7 @@
             -C "Deserializing connection..." \
             -s "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 run_test    "Context serialization, re-init, server serializes, ChaChaPoly" \
             "$P_SRV dtls=1 serialize=2 exchanges=2" \
@@ -1911,6 +1966,7 @@
             -C "Deserializing connection..." \
             -s "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 run_test    "Context serialization, re-init, server serializes, GCM" \
             "$P_SRV dtls=1 serialize=2 exchanges=2" \
@@ -1919,6 +1975,7 @@
             -C "Deserializing connection..." \
             -s "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Context serialization, re-init, server serializes, with CID" \
@@ -1928,6 +1985,7 @@
             -C "Deserializing connection..." \
             -s "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 run_test    "Context serialization, re-init, both serialize, CCM" \
             "$P_SRV dtls=1 serialize=2 exchanges=2" \
@@ -1936,6 +1994,7 @@
             -c "Deserializing connection..." \
             -s "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 run_test    "Context serialization, re-init, both serialize, ChaChaPoly" \
             "$P_SRV dtls=1 serialize=2 exchanges=2" \
@@ -1944,6 +2003,7 @@
             -c "Deserializing connection..." \
             -s "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 run_test    "Context serialization, re-init, both serialize, GCM" \
             "$P_SRV dtls=1 serialize=2 exchanges=2" \
@@ -1952,6 +2012,7 @@
             -c "Deserializing connection..." \
             -s "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Context serialization, re-init, both serialize, with CID" \
@@ -1961,6 +2022,7 @@
             -c "Deserializing connection..." \
             -s "Deserializing connection..."
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
 run_test    "Saving the serialized context to a file" \
             "$P_SRV dtls=1 serialize=1 context_file=context_srv.txt" \
@@ -1977,6 +2039,7 @@
 # grep for output witnessing its use. This needs to be
 # changed once the CID extension is implemented.
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Connection ID: Cli enabled, Srv disabled" \
             "$P_SRV debug_level=3 dtls=1 cid=0" \
@@ -1993,6 +2056,7 @@
             -C "Copy CIDs into SSL transform" \
             -c "Use of Connection ID was rejected by the server"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Connection ID: Cli disabled, Srv enabled" \
             "$P_SRV debug_level=3 dtls=1 cid=1 cid_val=deadbeef" \
@@ -2008,6 +2072,7 @@
             -C "Copy CIDs into SSL transform"  \
             -s "Use of Connection ID was not offered by client"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Connection ID: Cli+Srv enabled, Cli+Srv CID nonempty" \
             "$P_SRV debug_level=3 dtls=1 cid=1 cid_val=dead" \
@@ -2028,6 +2093,7 @@
             -s "Use of Connection ID has been negotiated" \
             -c "Use of Connection ID has been negotiated"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Connection ID, 3D: Cli+Srv enabled, Cli+Srv CID nonempty" \
             -p "$P_PXY drop=5 delay=5 duplicate=5 bad_cid=1" \
@@ -2051,6 +2117,7 @@
             -c "ignoring unexpected CID" \
             -s "ignoring unexpected CID"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Connection ID, MTU: Cli+Srv enabled, Cli+Srv CID nonempty" \
             -p "$P_PXY mtu=800" \
@@ -2072,6 +2139,7 @@
             -s "Use of Connection ID has been negotiated" \
             -c "Use of Connection ID has been negotiated"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Connection ID, 3D+MTU: Cli+Srv enabled, Cli+Srv CID nonempty" \
             -p "$P_PXY mtu=800 drop=5 delay=5 duplicate=5 bad_cid=1" \
@@ -2095,6 +2163,7 @@
             -c "ignoring unexpected CID" \
             -s "ignoring unexpected CID"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Connection ID: Cli+Srv enabled, Cli CID empty" \
             "$P_SRV debug_level=3 dtls=1 cid=1 cid_val=deadbeef" \
@@ -2115,6 +2184,7 @@
             -s "Use of Connection ID has been negotiated" \
             -c "Use of Connection ID has been negotiated"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Connection ID: Cli+Srv enabled, Srv CID empty" \
             "$P_SRV debug_level=3 dtls=1 cid=1" \
@@ -2135,6 +2205,7 @@
             -s "Use of Connection ID has been negotiated" \
             -c "Use of Connection ID has been negotiated"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Connection ID: Cli+Srv enabled, Cli+Srv CID empty" \
             "$P_SRV debug_level=3 dtls=1 cid=1" \
@@ -2153,6 +2224,7 @@
             -S "Use of Connection ID has been negotiated" \
             -C "Use of Connection ID has been negotiated"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Connection ID: Cli+Srv enabled, Cli+Srv CID nonempty, AES-128-CCM-8" \
             "$P_SRV debug_level=3 dtls=1 cid=1 cid_val=dead" \
@@ -2173,6 +2245,7 @@
             -s "Use of Connection ID has been negotiated" \
             -c "Use of Connection ID has been negotiated"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Connection ID: Cli+Srv enabled, Cli CID empty, AES-128-CCM-8" \
             "$P_SRV debug_level=3 dtls=1 cid=1 cid_val=deadbeef" \
@@ -2193,6 +2266,7 @@
             -s "Use of Connection ID has been negotiated" \
             -c "Use of Connection ID has been negotiated"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Connection ID: Cli+Srv enabled, Srv CID empty, AES-128-CCM-8" \
             "$P_SRV debug_level=3 dtls=1 cid=1" \
@@ -2213,6 +2287,7 @@
             -s "Use of Connection ID has been negotiated" \
             -c "Use of Connection ID has been negotiated"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Connection ID: Cli+Srv enabled, Cli+Srv CID empty, AES-128-CCM-8" \
             "$P_SRV debug_level=3 dtls=1 cid=1" \
@@ -2231,6 +2306,7 @@
             -S "Use of Connection ID has been negotiated" \
             -C "Use of Connection ID has been negotiated"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Connection ID: Cli+Srv enabled, Cli+Srv CID nonempty, AES-128-CBC" \
             "$P_SRV debug_level=3 dtls=1 cid=1 cid_val=dead" \
@@ -2251,6 +2327,7 @@
             -s "Use of Connection ID has been negotiated" \
             -c "Use of Connection ID has been negotiated"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Connection ID: Cli+Srv enabled, Cli CID empty, AES-128-CBC" \
             "$P_SRV debug_level=3 dtls=1 cid=1 cid_val=deadbeef" \
@@ -2271,6 +2348,7 @@
             -s "Use of Connection ID has been negotiated" \
             -c "Use of Connection ID has been negotiated"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Connection ID: Cli+Srv enabled, Srv CID empty, AES-128-CBC" \
             "$P_SRV debug_level=3 dtls=1 cid=1" \
@@ -2291,6 +2369,7 @@
             -s "Use of Connection ID has been negotiated" \
             -c "Use of Connection ID has been negotiated"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 run_test    "Connection ID: Cli+Srv enabled, Cli+Srv CID empty, AES-128-CBC" \
             "$P_SRV debug_level=3 dtls=1 cid=1" \
@@ -2309,6 +2388,7 @@
             -S "Use of Connection ID has been negotiated" \
             -C "Use of Connection ID has been negotiated"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Connection ID: Cli+Srv enabled, renegotiate without change of CID" \
@@ -2324,6 +2404,7 @@
             -s "(after renegotiation) Use of Connection ID has been negotiated" \
             -c "(after renegotiation) Use of Connection ID has been negotiated"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Connection ID: Cli+Srv enabled, renegotiate with different CID" \
@@ -2339,6 +2420,7 @@
             -s "(after renegotiation) Use of Connection ID has been negotiated" \
             -c "(after renegotiation) Use of Connection ID has been negotiated"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Connection ID, no packing: Cli+Srv enabled, renegotiate with different CID" \
@@ -2354,6 +2436,7 @@
             -s "(after renegotiation) Use of Connection ID has been negotiated" \
             -c "(after renegotiation) Use of Connection ID has been negotiated"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Connection ID, 3D+MTU: Cli+Srv enabled, renegotiate with different CID" \
@@ -2372,6 +2455,7 @@
             -c "ignoring unexpected CID" \
             -s "ignoring unexpected CID"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Connection ID: Cli+Srv enabled, renegotiate without CID" \
@@ -2387,6 +2471,7 @@
             -C "(after renegotiation) Use of Connection ID has been negotiated" \
             -S "(after renegotiation) Use of Connection ID has been negotiated"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Connection ID, no packing: Cli+Srv enabled, renegotiate without CID" \
@@ -2402,6 +2487,7 @@
             -C "(after renegotiation) Use of Connection ID has been negotiated" \
             -S "(after renegotiation) Use of Connection ID has been negotiated"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Connection ID, 3D+MTU: Cli+Srv enabled, renegotiate without CID" \
@@ -2420,6 +2506,7 @@
             -c "ignoring unexpected CID" \
             -s "ignoring unexpected CID"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Connection ID: Cli+Srv enabled, CID on renegotiation" \
@@ -2433,6 +2520,7 @@
             -c "(after renegotiation) Use of Connection ID has been negotiated" \
             -s "(after renegotiation) Use of Connection ID has been negotiated"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Connection ID, no packing: Cli+Srv enabled, CID on renegotiation" \
@@ -2446,6 +2534,7 @@
             -c "(after renegotiation) Use of Connection ID has been negotiated" \
             -s "(after renegotiation) Use of Connection ID has been negotiated"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Connection ID, 3D+MTU: Cli+Srv enabled, CID on renegotiation" \
@@ -2462,6 +2551,7 @@
             -c "ignoring unexpected CID" \
             -s "ignoring unexpected CID"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Connection ID: Cli+Srv enabled, Cli disables on renegotiation" \
@@ -2478,6 +2568,7 @@
             -S "(after renegotiation) Use of Connection ID has been negotiated" \
             -s "(after renegotiation) Use of Connection ID was not offered by client"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Connection ID, 3D: Cli+Srv enabled, Cli disables on renegotiation" \
@@ -2497,6 +2588,7 @@
             -c "ignoring unexpected CID" \
             -s "ignoring unexpected CID"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Connection ID: Cli+Srv enabled, Srv disables on renegotiation" \
@@ -2513,6 +2605,7 @@
             -S "(after renegotiation) Use of Connection ID has been negotiated" \
             -c "(after renegotiation) Use of Connection ID was rejected by the server"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Connection ID, 3D: Cli+Srv enabled, Srv disables on renegotiation" \
@@ -2535,6 +2628,7 @@
 # This and the test below it require MAX_CONTENT_LEN to be at least MFL+1, because the
 # tests check that the buffer contents are reallocated when the message is
 # larger than the buffer.
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 requires_config_enabled MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
 requires_max_content_len 513
@@ -2549,6 +2643,7 @@
             -s "Reallocating in_buf" \
             -s "Reallocating out_buf"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
 requires_config_enabled MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
 requires_max_content_len 1025
@@ -2565,6 +2660,7 @@
 
 # Tests for Encrypt-then-MAC extension
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Encrypt then MAC: default" \
             "$P_SRV debug_level=3 \
              force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
@@ -2577,6 +2673,7 @@
             -c "using encrypt then mac" \
             -s "using encrypt then mac"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Encrypt then MAC: client enabled, server disabled" \
             "$P_SRV debug_level=3 etm=0 \
              force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
@@ -2589,6 +2686,7 @@
             -C "using encrypt then mac" \
             -S "using encrypt then mac"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Encrypt then MAC: client enabled, aead cipher" \
             "$P_SRV debug_level=3 etm=1 \
              force_ciphersuite=TLS-RSA-WITH-AES-128-GCM-SHA256" \
@@ -2601,6 +2699,7 @@
             -C "using encrypt then mac" \
             -S "using encrypt then mac"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Encrypt then MAC: client disabled, server enabled" \
             "$P_SRV debug_level=3 etm=1 \
              force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
@@ -2615,6 +2714,7 @@
 
 # Tests for Extended Master Secret extension
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Extended Master Secret: default" \
             "$P_SRV debug_level=3" \
             "$P_CLI debug_level=3" \
@@ -2626,6 +2726,7 @@
             -c "session hash for extended master secret" \
             -s "session hash for extended master secret"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Extended Master Secret: client enabled, server disabled" \
             "$P_SRV debug_level=3 extended_ms=0" \
             "$P_CLI debug_level=3 extended_ms=1" \
@@ -2637,6 +2738,7 @@
             -C "session hash for extended master secret" \
             -S "session hash for extended master secret"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Extended Master Secret: client disabled, server enabled" \
             "$P_SRV debug_level=3 extended_ms=1" \
             "$P_CLI debug_level=3 extended_ms=0" \
@@ -2650,6 +2752,7 @@
 
 # Test sending and receiving empty application data records
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Encrypt then MAC: empty application data record" \
             "$P_SRV auth_mode=none debug_level=4 etm=1" \
             "$P_CLI auth_mode=none etm=1 request_size=0 force_ciphersuite=TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA" \
@@ -2658,6 +2761,7 @@
             -s "dumping 'input payload after decrypt' (0 bytes)" \
             -c "0 bytes written in 1 fragments"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Encrypt then MAC: disabled, empty application data record" \
             "$P_SRV auth_mode=none debug_level=4 etm=0" \
             "$P_CLI auth_mode=none etm=0 request_size=0" \
@@ -2665,6 +2769,7 @@
             -s "dumping 'input payload after decrypt' (0 bytes)" \
             -c "0 bytes written in 1 fragments"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Encrypt then MAC, DTLS: empty application data record" \
             "$P_SRV auth_mode=none debug_level=4 etm=1 dtls=1" \
             "$P_CLI auth_mode=none etm=1 request_size=0 force_ciphersuite=TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA dtls=1" \
@@ -2673,6 +2778,7 @@
             -s "dumping 'input payload after decrypt' (0 bytes)" \
             -c "0 bytes written in 1 fragments"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Encrypt then MAC, DTLS: disabled, empty application data record" \
             "$P_SRV auth_mode=none debug_level=4 etm=0 dtls=1" \
             "$P_CLI auth_mode=none etm=0 request_size=0 dtls=1" \
@@ -2682,6 +2788,7 @@
 
 # Tests for CBC 1/n-1 record splitting
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "CBC Record splitting: TLS 1.2, no splitting" \
             "$P_SRV" \
             "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA \
@@ -2693,6 +2800,7 @@
 
 # Tests for Session Tickets
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets: basic" \
             "$P_SRV debug_level=3 tickets=1" \
             "$P_CLI debug_level=3 tickets=1 reconnect=1" \
@@ -2707,6 +2815,23 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
+run_test    "Session resume using tickets: manual rotation" \
+            "$P_SRV debug_level=3 tickets=1 ticket_rotate=1" \
+            "$P_CLI debug_level=3 tickets=1 reconnect=1" \
+            0 \
+            -c "client hello, adding session ticket extension" \
+            -s "found session ticket extension" \
+            -s "server hello, adding session ticket extension" \
+            -c "found session_ticket extension" \
+            -c "parse new session ticket" \
+            -S "session successfully restored from cache" \
+            -s "session successfully restored from ticket" \
+            -s "a session has been resumed" \
+            -c "a session has been resumed"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets: cache disabled" \
             "$P_SRV debug_level=3 tickets=1 cache_max=0" \
             "$P_CLI debug_level=3 tickets=1 reconnect=1" \
@@ -2721,6 +2846,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets: timeout" \
             "$P_SRV debug_level=3 tickets=1 cache_max=0 ticket_timeout=1" \
             "$P_CLI debug_level=3 tickets=1 reconnect=1 reco_delay=2" \
@@ -2735,6 +2861,7 @@
             -S "a session has been resumed" \
             -C "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets: session copy" \
             "$P_SRV debug_level=3 tickets=1 cache_max=0" \
             "$P_CLI debug_level=3 tickets=1 reconnect=1 reco_mode=0" \
@@ -2749,6 +2876,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets: openssl server" \
             "$O_SRV" \
             "$P_CLI debug_level=3 tickets=1 reconnect=1" \
@@ -2758,6 +2886,7 @@
             -c "parse new session ticket" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets: openssl client" \
             "$P_SRV debug_level=3 tickets=1" \
             "( $O_CLI -sess_out $SESSION; \
@@ -2770,6 +2899,7 @@
             -s "session successfully restored from ticket" \
             -s "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets: AES-128-GCM" \
             "$P_SRV debug_level=3 tickets=1 ticket_aead=AES-128-GCM" \
             "$P_CLI debug_level=3 tickets=1 reconnect=1" \
@@ -2784,6 +2914,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets: AES-192-GCM" \
             "$P_SRV debug_level=3 tickets=1 ticket_aead=AES-192-GCM" \
             "$P_CLI debug_level=3 tickets=1 reconnect=1" \
@@ -2798,6 +2929,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets: AES-128-CCM" \
             "$P_SRV debug_level=3 tickets=1 ticket_aead=AES-128-CCM" \
             "$P_CLI debug_level=3 tickets=1 reconnect=1" \
@@ -2812,6 +2944,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets: AES-192-CCM" \
             "$P_SRV debug_level=3 tickets=1 ticket_aead=AES-192-CCM" \
             "$P_CLI debug_level=3 tickets=1 reconnect=1" \
@@ -2826,6 +2959,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets: AES-256-CCM" \
             "$P_SRV debug_level=3 tickets=1 ticket_aead=AES-256-CCM" \
             "$P_CLI debug_level=3 tickets=1 reconnect=1" \
@@ -2840,6 +2974,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets: CAMELLIA-128-CCM" \
             "$P_SRV debug_level=3 tickets=1 ticket_aead=CAMELLIA-128-CCM" \
             "$P_CLI debug_level=3 tickets=1 reconnect=1" \
@@ -2854,6 +2989,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets: CAMELLIA-192-CCM" \
             "$P_SRV debug_level=3 tickets=1 ticket_aead=CAMELLIA-192-CCM" \
             "$P_CLI debug_level=3 tickets=1 reconnect=1" \
@@ -2868,6 +3004,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets: CAMELLIA-256-CCM" \
             "$P_SRV debug_level=3 tickets=1 ticket_aead=CAMELLIA-256-CCM" \
             "$P_CLI debug_level=3 tickets=1 reconnect=1" \
@@ -2882,6 +3019,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets: ARIA-128-GCM" \
             "$P_SRV debug_level=3 tickets=1 ticket_aead=ARIA-128-GCM" \
             "$P_CLI debug_level=3 tickets=1 reconnect=1" \
@@ -2896,6 +3034,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets: ARIA-192-GCM" \
             "$P_SRV debug_level=3 tickets=1 ticket_aead=ARIA-192-GCM" \
             "$P_CLI debug_level=3 tickets=1 reconnect=1" \
@@ -2910,6 +3049,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets: ARIA-256-GCM" \
             "$P_SRV debug_level=3 tickets=1 ticket_aead=ARIA-256-GCM" \
             "$P_CLI debug_level=3 tickets=1 reconnect=1" \
@@ -2924,6 +3064,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets: ARIA-128-CCM" \
             "$P_SRV debug_level=3 tickets=1 ticket_aead=ARIA-128-CCM" \
             "$P_CLI debug_level=3 tickets=1 reconnect=1" \
@@ -2938,6 +3079,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets: ARIA-192-CCM" \
             "$P_SRV debug_level=3 tickets=1 ticket_aead=ARIA-192-CCM" \
             "$P_CLI debug_level=3 tickets=1 reconnect=1" \
@@ -2952,6 +3094,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets: ARIA-256-CCM" \
             "$P_SRV debug_level=3 tickets=1 ticket_aead=ARIA-256-CCM" \
             "$P_CLI debug_level=3 tickets=1 reconnect=1" \
@@ -2968,6 +3111,7 @@
 
 # Tests for Session Tickets with DTLS
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets, DTLS: basic" \
             "$P_SRV debug_level=3 dtls=1 tickets=1" \
             "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 skip_close_notify=1" \
@@ -2982,6 +3126,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets, DTLS: cache disabled" \
             "$P_SRV debug_level=3 dtls=1 tickets=1 cache_max=0" \
             "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 skip_close_notify=1" \
@@ -2996,6 +3141,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets, DTLS: timeout" \
             "$P_SRV debug_level=3 dtls=1 tickets=1 cache_max=0 ticket_timeout=1" \
             "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 skip_close_notify=1 reco_delay=2" \
@@ -3010,6 +3156,7 @@
             -S "a session has been resumed" \
             -C "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets, DTLS: session copy" \
             "$P_SRV debug_level=3 dtls=1 tickets=1 cache_max=0" \
             "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 skip_close_notify=1 reco_mode=0" \
@@ -3024,6 +3171,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets, DTLS: openssl server" \
             "$O_SRV -dtls" \
             "$P_CLI dtls=1 debug_level=3 tickets=1 reconnect=1" \
@@ -3036,6 +3184,7 @@
 # For reasons that aren't fully understood, this test randomly fails with high
 # probability with OpenSSL 1.0.2g on the CI, see #5012.
 requires_openssl_next
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using tickets, DTLS: openssl client" \
             "$P_SRV dtls=1 debug_level=3 tickets=1" \
             "( $O_NEXT_CLI -dtls -sess_out $SESSION; \
@@ -3050,6 +3199,7 @@
 
 # Tests for Session Resume based on session-ID and cache
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using cache: tickets enabled on client" \
             "$P_SRV debug_level=3 tickets=0" \
             "$P_CLI debug_level=3 tickets=1 reconnect=1" \
@@ -3064,6 +3214,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using cache: tickets enabled on server" \
             "$P_SRV debug_level=3 tickets=1" \
             "$P_CLI debug_level=3 tickets=0 reconnect=1" \
@@ -3078,6 +3229,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using cache: cache_max=0" \
             "$P_SRV debug_level=3 tickets=0 cache_max=0" \
             "$P_CLI debug_level=3 tickets=0 reconnect=1" \
@@ -3087,6 +3239,7 @@
             -S "a session has been resumed" \
             -C "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using cache: cache_max=1" \
             "$P_SRV debug_level=3 tickets=0 cache_max=1" \
             "$P_CLI debug_level=3 tickets=0 reconnect=1" \
@@ -3096,6 +3249,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using cache: timeout > delay" \
             "$P_SRV debug_level=3 tickets=0" \
             "$P_CLI debug_level=3 tickets=0 reconnect=1 reco_delay=0" \
@@ -3105,6 +3259,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using cache: timeout < delay" \
             "$P_SRV debug_level=3 tickets=0 cache_timeout=1" \
             "$P_CLI debug_level=3 tickets=0 reconnect=1 reco_delay=2" \
@@ -3114,6 +3269,7 @@
             -S "a session has been resumed" \
             -C "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using cache: no timeout" \
             "$P_SRV debug_level=3 tickets=0 cache_timeout=0" \
             "$P_CLI debug_level=3 tickets=0 reconnect=1 reco_delay=2" \
@@ -3123,6 +3279,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using cache: session copy" \
             "$P_SRV debug_level=3 tickets=0" \
             "$P_CLI debug_level=3 tickets=0 reconnect=1 reco_mode=0" \
@@ -3132,6 +3289,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using cache: openssl client" \
             "$P_SRV debug_level=3 tickets=0" \
             "( $O_CLI -sess_out $SESSION; \
@@ -3144,6 +3302,7 @@
             -S "session successfully restored from ticket" \
             -s "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using cache: openssl server" \
             "$O_SRV" \
             "$P_CLI debug_level=3 tickets=0 reconnect=1" \
@@ -3154,6 +3313,7 @@
 
 # Tests for Session Resume based on session-ID and cache, DTLS
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using cache, DTLS: tickets enabled on client" \
             "$P_SRV dtls=1 debug_level=3 tickets=0" \
             "$P_CLI dtls=1 debug_level=3 tickets=1 reconnect=1 skip_close_notify=1" \
@@ -3168,6 +3328,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using cache, DTLS: tickets enabled on server" \
             "$P_SRV dtls=1 debug_level=3 tickets=1" \
             "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1" \
@@ -3182,6 +3343,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using cache, DTLS: cache_max=0" \
             "$P_SRV dtls=1 debug_level=3 tickets=0 cache_max=0" \
             "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1" \
@@ -3191,6 +3353,7 @@
             -S "a session has been resumed" \
             -C "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using cache, DTLS: cache_max=1" \
             "$P_SRV dtls=1 debug_level=3 tickets=0 cache_max=1" \
             "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1" \
@@ -3200,6 +3363,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using cache, DTLS: timeout > delay" \
             "$P_SRV dtls=1 debug_level=3 tickets=0" \
             "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1 reco_delay=0" \
@@ -3209,6 +3373,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using cache, DTLS: timeout < delay" \
             "$P_SRV dtls=1 debug_level=3 tickets=0 cache_timeout=1" \
             "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1 reco_delay=2" \
@@ -3218,6 +3383,7 @@
             -S "a session has been resumed" \
             -C "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using cache, DTLS: no timeout" \
             "$P_SRV dtls=1 debug_level=3 tickets=0 cache_timeout=0" \
             "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1 reco_delay=2" \
@@ -3227,6 +3393,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using cache, DTLS: session copy" \
             "$P_SRV dtls=1 debug_level=3 tickets=0" \
             "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1 reco_mode=0" \
@@ -3239,6 +3406,7 @@
 # For reasons that aren't fully understood, this test randomly fails with high
 # probability with OpenSSL 1.0.2g on the CI, see #5012.
 requires_openssl_next
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using cache, DTLS: openssl client" \
             "$P_SRV dtls=1 debug_level=3 tickets=0" \
             "( $O_NEXT_CLI -dtls -sess_out $SESSION; \
@@ -3251,6 +3419,7 @@
             -S "session successfully restored from ticket" \
             -s "a session has been resumed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Session resume using cache, DTLS: openssl server" \
             "$O_SRV -dtls" \
             "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1" \
@@ -3262,6 +3431,7 @@
 # Tests for Max Fragment Length extension
 
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: enabled, default" \
             "$P_SRV debug_level=3" \
             "$P_CLI debug_level=3" \
@@ -3276,6 +3446,7 @@
             -C "found max_fragment_length extension"
 
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: enabled, default, larger message" \
             "$P_SRV debug_level=3" \
             "$P_CLI debug_level=3 request_size=$(( $MAX_CONTENT_LEN + 1))" \
@@ -3293,6 +3464,7 @@
             -s "1 bytes read"
 
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length, DTLS: enabled, default, larger message" \
             "$P_SRV debug_level=3 dtls=1" \
             "$P_CLI debug_level=3 dtls=1 request_size=$(( $MAX_CONTENT_LEN + 1))" \
@@ -3312,6 +3484,7 @@
 # content length configuration.)
 
 requires_config_disabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: disabled, larger message" \
             "$P_SRV debug_level=3" \
             "$P_CLI debug_level=3 request_size=$(( $MAX_CONTENT_LEN + 1))" \
@@ -3325,6 +3498,7 @@
             -s "1 bytes read"
 
 requires_config_disabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length, DTLS: disabled, larger message" \
             "$P_SRV debug_level=3 dtls=1" \
             "$P_CLI debug_level=3 dtls=1 request_size=$(( $MAX_CONTENT_LEN + 1))" \
@@ -3337,6 +3511,7 @@
 
 requires_max_content_len 4096
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: used by client" \
             "$P_SRV debug_level=3" \
             "$P_CLI debug_level=3 max_frag_len=4096" \
@@ -3352,6 +3527,7 @@
 
 requires_max_content_len 1024
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: client 512, server 1024" \
             "$P_SRV debug_level=3 max_frag_len=1024" \
             "$P_CLI debug_level=3 max_frag_len=512" \
@@ -3367,6 +3543,7 @@
 
 requires_max_content_len 2048
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: client 512, server 2048" \
             "$P_SRV debug_level=3 max_frag_len=2048" \
             "$P_CLI debug_level=3 max_frag_len=512" \
@@ -3382,6 +3559,7 @@
 
 requires_max_content_len 4096
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: client 512, server 4096" \
             "$P_SRV debug_level=3 max_frag_len=4096" \
             "$P_CLI debug_level=3 max_frag_len=512" \
@@ -3397,6 +3575,7 @@
 
 requires_max_content_len 1024
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: client 1024, server 512" \
             "$P_SRV debug_level=3 max_frag_len=512" \
             "$P_CLI debug_level=3 max_frag_len=1024" \
@@ -3412,6 +3591,7 @@
 
 requires_max_content_len 2048
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: client 1024, server 2048" \
             "$P_SRV debug_level=3 max_frag_len=2048" \
             "$P_CLI debug_level=3 max_frag_len=1024" \
@@ -3427,6 +3607,7 @@
 
 requires_max_content_len 4096
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: client 1024, server 4096" \
             "$P_SRV debug_level=3 max_frag_len=4096" \
             "$P_CLI debug_level=3 max_frag_len=1024" \
@@ -3442,6 +3623,7 @@
 
 requires_max_content_len 2048
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: client 2048, server 512" \
             "$P_SRV debug_level=3 max_frag_len=512" \
             "$P_CLI debug_level=3 max_frag_len=2048" \
@@ -3457,6 +3639,7 @@
 
 requires_max_content_len 2048
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: client 2048, server 1024" \
             "$P_SRV debug_level=3 max_frag_len=1024" \
             "$P_CLI debug_level=3 max_frag_len=2048" \
@@ -3472,6 +3655,7 @@
 
 requires_max_content_len 4096
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: client 2048, server 4096" \
             "$P_SRV debug_level=3 max_frag_len=4096" \
             "$P_CLI debug_level=3 max_frag_len=2048" \
@@ -3487,6 +3671,7 @@
 
 requires_max_content_len 4096
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: client 4096, server 512" \
             "$P_SRV debug_level=3 max_frag_len=512" \
             "$P_CLI debug_level=3 max_frag_len=4096" \
@@ -3502,6 +3687,7 @@
 
 requires_max_content_len 4096
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: client 4096, server 1024" \
             "$P_SRV debug_level=3 max_frag_len=1024" \
             "$P_CLI debug_level=3 max_frag_len=4096" \
@@ -3517,6 +3703,7 @@
 
 requires_max_content_len 4096
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: client 4096, server 2048" \
             "$P_SRV debug_level=3 max_frag_len=2048" \
             "$P_CLI debug_level=3 max_frag_len=4096" \
@@ -3532,6 +3719,7 @@
 
 requires_max_content_len 4096
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: used by server" \
             "$P_SRV debug_level=3 max_frag_len=4096" \
             "$P_CLI debug_level=3" \
@@ -3548,6 +3736,7 @@
 requires_max_content_len 4096
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: gnutls server" \
             "$G_SRV" \
             "$P_CLI debug_level=3 max_frag_len=4096" \
@@ -3559,6 +3748,7 @@
 
 requires_max_content_len 2048
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: client, message just fits" \
             "$P_SRV debug_level=3" \
             "$P_CLI debug_level=3 max_frag_len=2048 request_size=2048" \
@@ -3576,6 +3766,7 @@
 
 requires_max_content_len 2048
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: client, larger message" \
             "$P_SRV debug_level=3" \
             "$P_CLI debug_level=3 max_frag_len=2048 request_size=2345" \
@@ -3594,6 +3785,7 @@
 
 requires_max_content_len 2048
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Max fragment length: DTLS client, larger message" \
             "$P_SRV debug_level=3 dtls=1" \
             "$P_CLI debug_level=3 dtls=1 max_frag_len=2048 request_size=2345" \
@@ -3611,6 +3803,7 @@
 # Tests for renegotiation
 
 # Renegotiation SCSV always added, regardless of SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: none, for reference" \
             "$P_SRV debug_level=3 exchanges=2 auth_mode=optional" \
             "$P_CLI debug_level=3 exchanges=2" \
@@ -3625,6 +3818,7 @@
             -S "write hello request"
 
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: client-initiated" \
             "$P_SRV debug_level=3 exchanges=2 renegotiation=1 auth_mode=optional" \
             "$P_CLI debug_level=3 exchanges=2 renegotiation=1 renegotiate=1" \
@@ -3639,6 +3833,7 @@
             -S "write hello request"
 
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: server-initiated" \
             "$P_SRV debug_level=3 exchanges=2 renegotiation=1 auth_mode=optional renegotiate=1" \
             "$P_CLI debug_level=3 exchanges=2 renegotiation=1" \
@@ -3656,6 +3851,7 @@
 # the server did not parse the Signature Algorithm extension. This test is valid only if an MD
 # algorithm stronger than SHA-1 is enabled in mbedtls_config.h
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: Signature Algorithms parsing, client-initiated" \
             "$P_SRV debug_level=3 exchanges=2 renegotiation=1 auth_mode=optional" \
             "$P_CLI debug_level=3 exchanges=2 renegotiation=1 renegotiate=1" \
@@ -3674,6 +3870,7 @@
 # the server did not parse the Signature Algorithm extension. This test is valid only if an MD
 # algorithm stronger than SHA-1 is enabled in mbedtls_config.h
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: Signature Algorithms parsing, server-initiated" \
             "$P_SRV debug_level=3 exchanges=2 renegotiation=1 auth_mode=optional renegotiate=1" \
             "$P_CLI debug_level=3 exchanges=2 renegotiation=1" \
@@ -3689,6 +3886,7 @@
             -S "client hello v3, signature_algorithm ext: 2" # Is SHA-1 negotiated?
 
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: double" \
             "$P_SRV debug_level=3 exchanges=2 renegotiation=1 auth_mode=optional renegotiate=1" \
             "$P_CLI debug_level=3 exchanges=2 renegotiation=1 renegotiate=1" \
@@ -3705,6 +3903,7 @@
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation with max fragment length: client 2048, server 512" \
             "$P_SRV debug_level=3 exchanges=2 renegotiation=1 auth_mode=optional renegotiate=1 max_frag_len=512" \
             "$P_CLI debug_level=3 exchanges=2 renegotiation=1 renegotiate=1 max_frag_len=2048 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8" \
@@ -3727,6 +3926,7 @@
             -s "write hello request"
 
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: client-initiated, server-rejected" \
             "$P_SRV debug_level=3 exchanges=2 renegotiation=0 auth_mode=optional" \
             "$P_CLI debug_level=3 exchanges=2 renegotiation=1 renegotiate=1" \
@@ -3743,6 +3943,7 @@
             -c "failed"
 
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: server-initiated, client-rejected, default" \
             "$P_SRV debug_level=3 exchanges=2 renegotiation=1 renegotiate=1 auth_mode=optional" \
             "$P_CLI debug_level=3 exchanges=2 renegotiation=0" \
@@ -3759,6 +3960,7 @@
             -S "failed"
 
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: server-initiated, client-rejected, not enforced" \
             "$P_SRV debug_level=3 exchanges=2 renegotiation=1 renegotiate=1 \
              renego_delay=-1 auth_mode=optional" \
@@ -3777,6 +3979,7 @@
 
 # delay 2 for 1 alert record + 1 application data record
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: server-initiated, client-rejected, delay 2" \
             "$P_SRV debug_level=3 exchanges=2 renegotiation=1 renegotiate=1 \
              renego_delay=2 auth_mode=optional" \
@@ -3794,6 +3997,7 @@
             -S "failed"
 
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: server-initiated, client-rejected, delay 0" \
             "$P_SRV debug_level=3 exchanges=2 renegotiation=1 renegotiate=1 \
              renego_delay=0 auth_mode=optional" \
@@ -3810,6 +4014,7 @@
             -s "SSL - An unexpected message was received from our peer"
 
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: server-initiated, client-accepted, delay 0" \
             "$P_SRV debug_level=3 exchanges=2 renegotiation=1 renegotiate=1 \
              renego_delay=0 auth_mode=optional" \
@@ -3827,6 +4032,7 @@
             -S "failed"
 
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: periodic, just below period" \
             "$P_SRV debug_level=3 exchanges=9 renegotiation=1 renego_period=3 auth_mode=optional" \
             "$P_CLI debug_level=3 exchanges=2 renegotiation=1" \
@@ -3845,6 +4051,7 @@
 
 # one extra exchange to be able to complete renego
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: periodic, just above period" \
             "$P_SRV debug_level=3 exchanges=9 renegotiation=1 renego_period=3 auth_mode=optional" \
             "$P_CLI debug_level=3 exchanges=4 renegotiation=1" \
@@ -3862,6 +4069,7 @@
             -S "failed"
 
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: periodic, two times period" \
             "$P_SRV debug_level=3 exchanges=9 renegotiation=1 renego_period=3 auth_mode=optional" \
             "$P_CLI debug_level=3 exchanges=7 renegotiation=1" \
@@ -3879,6 +4087,7 @@
             -S "failed"
 
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: periodic, above period, disabled" \
             "$P_SRV debug_level=3 exchanges=9 renegotiation=0 renego_period=3 auth_mode=optional" \
             "$P_CLI debug_level=3 exchanges=4 renegotiation=1" \
@@ -3896,6 +4105,7 @@
             -S "failed"
 
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: nbio, client-initiated" \
             "$P_SRV debug_level=3 nbio=2 exchanges=2 renegotiation=1 auth_mode=optional" \
             "$P_CLI debug_level=3 nbio=2 exchanges=2 renegotiation=1 renegotiate=1" \
@@ -3910,6 +4120,7 @@
             -S "write hello request"
 
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: nbio, server-initiated" \
             "$P_SRV debug_level=3 nbio=2 exchanges=2 renegotiation=1 renegotiate=1 auth_mode=optional" \
             "$P_CLI debug_level=3 nbio=2 exchanges=2 renegotiation=1" \
@@ -3924,6 +4135,7 @@
             -s "write hello request"
 
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: openssl server, client-initiated" \
             "$O_SRV -www" \
             "$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1" \
@@ -3937,6 +4149,7 @@
 
 requires_gnutls
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: gnutls server strict, client-initiated" \
             "$G_SRV --priority=NORMAL:%SAFE_RENEGOTIATION" \
             "$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1" \
@@ -3950,6 +4163,7 @@
 
 requires_gnutls
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: gnutls server unsafe, client-initiated default" \
             "$G_SRV --priority=NORMAL:%DISABLE_SAFE_RENEGOTIATION" \
             "$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1" \
@@ -3963,6 +4177,7 @@
 
 requires_gnutls
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: gnutls server unsafe, client-inititated no legacy" \
             "$G_SRV --priority=NORMAL:%DISABLE_SAFE_RENEGOTIATION" \
             "$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1 \
@@ -3977,6 +4192,7 @@
 
 requires_gnutls
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: gnutls server unsafe, client-inititated legacy" \
             "$G_SRV --priority=NORMAL:%DISABLE_SAFE_RENEGOTIATION" \
             "$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1 \
@@ -3990,6 +4206,7 @@
             -c "HTTP/1.0 200 [Oo][Kk]"
 
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: DTLS, client-initiated" \
             "$P_SRV debug_level=3 dtls=1 exchanges=2 renegotiation=1" \
             "$P_CLI debug_level=3 dtls=1 exchanges=2 renegotiation=1 renegotiate=1" \
@@ -4004,6 +4221,7 @@
             -S "write hello request"
 
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: DTLS, server-initiated" \
             "$P_SRV debug_level=3 dtls=1 exchanges=2 renegotiation=1 renegotiate=1" \
             "$P_CLI debug_level=3 dtls=1 exchanges=2 renegotiation=1 \
@@ -4019,6 +4237,7 @@
             -s "write hello request"
 
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: DTLS, renego_period overflow" \
             "$P_SRV debug_level=3 dtls=1 exchanges=4 renegotiation=1 renego_period=18446462598732840962 auth_mode=optional" \
             "$P_CLI debug_level=3 dtls=1 exchanges=4 renegotiation=1" \
@@ -4034,6 +4253,7 @@
 
 requires_gnutls
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renegotiation: DTLS, gnutls server, client-initiated" \
             "$G_SRV -u --mtu 4096" \
             "$P_CLI debug_level=3 dtls=1 exchanges=1 renegotiation=1 renegotiate=1" \
@@ -4048,6 +4268,7 @@
 # Test for the "secure renegotation" extension only (no actual renegotiation)
 
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renego ext: gnutls server strict, client default" \
             "$G_SRV --priority=NORMAL:%SAFE_RENEGOTIATION" \
             "$P_CLI debug_level=3" \
@@ -4057,6 +4278,7 @@
             -c "HTTP/1.0 200 [Oo][Kk]"
 
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renego ext: gnutls server unsafe, client default" \
             "$G_SRV --priority=NORMAL:%DISABLE_SAFE_RENEGOTIATION" \
             "$P_CLI debug_level=3" \
@@ -4066,6 +4288,7 @@
             -c "HTTP/1.0 200 [Oo][Kk]"
 
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renego ext: gnutls server unsafe, client break legacy" \
             "$G_SRV --priority=NORMAL:%DISABLE_SAFE_RENEGOTIATION" \
             "$P_CLI debug_level=3 allow_legacy=-1" \
@@ -4075,6 +4298,7 @@
             -C "HTTP/1.0 200 [Oo][Kk]"
 
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renego ext: gnutls client strict, server default" \
             "$P_SRV debug_level=3" \
             "$G_CLI --priority=NORMAL:%SAFE_RENEGOTIATION localhost" \
@@ -4083,6 +4307,7 @@
             -s "server hello, secure renegotiation extension"
 
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renego ext: gnutls client unsafe, server default" \
             "$P_SRV debug_level=3" \
             "$G_CLI --priority=NORMAL:%DISABLE_SAFE_RENEGOTIATION localhost" \
@@ -4091,6 +4316,7 @@
             -S "server hello, secure renegotiation extension"
 
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Renego ext: gnutls client unsafe, server break legacy" \
             "$P_SRV debug_level=3 allow_legacy=-1" \
             "$G_CLI --priority=NORMAL:%DISABLE_SAFE_RENEGOTIATION localhost" \
@@ -4101,6 +4327,7 @@
 # Tests for silently dropping trailing extra bytes in .der certificates
 
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DER format: no trailing bytes" \
             "$P_SRV crt_file=data_files/server5-der0.crt \
              key_file=data_files/server5.key" \
@@ -4109,6 +4336,7 @@
             -c "Handshake was completed" \
 
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DER format: with a trailing zero byte" \
             "$P_SRV crt_file=data_files/server5-der1a.crt \
              key_file=data_files/server5.key" \
@@ -4117,6 +4345,7 @@
             -c "Handshake was completed" \
 
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DER format: with a trailing random byte" \
             "$P_SRV crt_file=data_files/server5-der1b.crt \
              key_file=data_files/server5.key" \
@@ -4125,6 +4354,7 @@
             -c "Handshake was completed" \
 
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DER format: with 2 trailing random bytes" \
             "$P_SRV crt_file=data_files/server5-der2.crt \
              key_file=data_files/server5.key" \
@@ -4133,6 +4363,7 @@
             -c "Handshake was completed" \
 
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DER format: with 4 trailing random bytes" \
             "$P_SRV crt_file=data_files/server5-der4.crt \
              key_file=data_files/server5.key" \
@@ -4141,6 +4372,7 @@
             -c "Handshake was completed" \
 
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DER format: with 8 trailing random bytes" \
             "$P_SRV crt_file=data_files/server5-der8.crt \
              key_file=data_files/server5.key" \
@@ -4149,6 +4381,7 @@
             -c "Handshake was completed" \
 
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DER format: with 9 trailing random bytes" \
             "$P_SRV crt_file=data_files/server5-der9.crt \
              key_file=data_files/server5.key" \
@@ -4159,6 +4392,7 @@
 # Tests for auth_mode, there are duplicated tests using ca callback for authentication
 # When updating these tests, modify the matching authentication tests accordingly
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: server badcert, client required" \
             "$P_SRV crt_file=data_files/server5-badsign.crt \
              key_file=data_files/server5.key" \
@@ -4169,6 +4403,7 @@
             -c "! mbedtls_ssl_handshake returned" \
             -c "X509 - Certificate verification failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: server badcert, client optional" \
             "$P_SRV crt_file=data_files/server5-badsign.crt \
              key_file=data_files/server5.key" \
@@ -4179,6 +4414,7 @@
             -C "! mbedtls_ssl_handshake returned" \
             -C "X509 - Certificate verification failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: server goodcert, client optional, no trusted CA" \
             "$P_SRV" \
             "$P_CLI debug_level=3 auth_mode=optional ca_file=none ca_path=none" \
@@ -4190,6 +4426,7 @@
             -C "X509 - Certificate verification failed" \
             -C "SSL - No CA Chain is set, but required to operate"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: server goodcert, client required, no trusted CA" \
             "$P_SRV" \
             "$P_CLI debug_level=3 auth_mode=required ca_file=none ca_path=none" \
@@ -4208,6 +4445,7 @@
 # different means to have the server ignoring the client's supported curve list.
 
 requires_config_enabled MBEDTLS_ECP_C
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: server ECDH p256v1, client required, p256v1 unsupported" \
             "$P_SRV debug_level=1 key_file=data_files/server5.key \
              crt_file=data_files/server5.ku-ka.crt" \
@@ -4218,6 +4456,7 @@
             -C "bad server certificate (ECDH curve)" # Expect failure at earlier verification stage
 
 requires_config_enabled MBEDTLS_ECP_C
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: server ECDH p256v1, client optional, p256v1 unsupported" \
             "$P_SRV debug_level=1 key_file=data_files/server5.key \
              crt_file=data_files/server5.ku-ka.crt" \
@@ -4227,6 +4466,7 @@
             -c "! Certificate verification flags"\
             -c "bad server certificate (ECDH curve)" # Expect failure only at ECDH params check
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: server badcert, client none" \
             "$P_SRV crt_file=data_files/server5-badsign.crt \
              key_file=data_files/server5.key" \
@@ -4237,6 +4477,7 @@
             -C "! mbedtls_ssl_handshake returned" \
             -C "X509 - Certificate verification failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: client SHA256, server required" \
             "$P_SRV auth_mode=required" \
             "$P_CLI debug_level=3 crt_file=data_files/server6.crt \
@@ -4246,6 +4487,7 @@
             -c "Supported Signature Algorithm found: 4," \
             -c "Supported Signature Algorithm found: 5,"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: client SHA384, server required" \
             "$P_SRV auth_mode=required" \
             "$P_CLI debug_level=3 crt_file=data_files/server6.crt \
@@ -4255,6 +4497,7 @@
             -c "Supported Signature Algorithm found: 4," \
             -c "Supported Signature Algorithm found: 5,"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: client has no cert, server required (TLS)" \
             "$P_SRV debug_level=3 auth_mode=required" \
             "$P_CLI debug_level=3 crt_file=none \
@@ -4271,6 +4514,7 @@
             -c "! mbedtls_ssl_handshake returned" \
             -s "No client certification received from the client, but required by the authentication mode"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: client badcert, server required" \
             "$P_SRV debug_level=3 auth_mode=required" \
             "$P_CLI debug_level=3 crt_file=data_files/server5-badsign.crt \
@@ -4292,6 +4536,7 @@
 # detect that its write end of the connection is closed and abort
 # before reading the alert message.
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: client cert self-signed and trusted, server required" \
             "$P_SRV debug_level=3 auth_mode=required ca_file=data_files/server5-selfsigned.crt" \
             "$P_CLI debug_level=3 crt_file=data_files/server5-selfsigned.crt \
@@ -4307,6 +4552,7 @@
             -S "! The certificate is not correctly signed" \
             -S "X509 - Certificate verification failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: client cert not trusted, server required" \
             "$P_SRV debug_level=3 auth_mode=required" \
             "$P_CLI debug_level=3 crt_file=data_files/server5-selfsigned.crt \
@@ -4324,6 +4570,7 @@
             -c "! mbedtls_ssl_handshake returned" \
             -s "X509 - Certificate verification failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: client badcert, server optional" \
             "$P_SRV debug_level=3 auth_mode=optional" \
             "$P_CLI debug_level=3 crt_file=data_files/server5-badsign.crt \
@@ -4341,6 +4588,7 @@
             -C "! mbedtls_ssl_handshake returned" \
             -S "X509 - Certificate verification failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: client badcert, server none" \
             "$P_SRV debug_level=3 auth_mode=none" \
             "$P_CLI debug_level=3 crt_file=data_files/server5-badsign.crt \
@@ -4358,6 +4606,7 @@
             -C "! mbedtls_ssl_handshake returned" \
             -S "X509 - Certificate verification failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: client no cert, server optional" \
             "$P_SRV debug_level=3 auth_mode=optional" \
             "$P_CLI debug_level=3 crt_file=none key_file=none" \
@@ -4374,6 +4623,7 @@
             -C "! mbedtls_ssl_handshake returned" \
             -S "X509 - Certificate verification failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: openssl client no cert, server optional" \
             "$P_SRV debug_level=3 auth_mode=optional" \
             "$O_CLI" \
@@ -4384,6 +4634,7 @@
             -S "! mbedtls_ssl_handshake returned" \
             -S "X509 - Certificate verification failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: client no cert, openssl server optional" \
             "$O_SRV -verify 10" \
             "$P_CLI debug_level=3 crt_file=none key_file=none" \
@@ -4394,6 +4645,7 @@
             -c "skip write certificate verify" \
             -C "! mbedtls_ssl_handshake returned"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: client no cert, openssl server required" \
             "$O_SRV -Verify 10" \
             "$P_CLI debug_level=3 crt_file=none key_file=none" \
@@ -4416,6 +4668,7 @@
 # are in place so that the semantics are consistent with the test description.
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: server max_int chain, client default" \
             "$P_SRV crt_file=data_files/dir-maxpath/c09.pem \
                     key_file=data_files/dir-maxpath/09.key" \
@@ -4425,6 +4678,7 @@
 
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: server max_int+1 chain, client default" \
             "$P_SRV crt_file=data_files/dir-maxpath/c10.pem \
                     key_file=data_files/dir-maxpath/10.key" \
@@ -4434,6 +4688,7 @@
 
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: server max_int+1 chain, client optional" \
             "$P_SRV crt_file=data_files/dir-maxpath/c10.pem \
                     key_file=data_files/dir-maxpath/10.key" \
@@ -4444,6 +4699,7 @@
 
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: server max_int+1 chain, client none" \
             "$P_SRV crt_file=data_files/dir-maxpath/c10.pem \
                     key_file=data_files/dir-maxpath/10.key" \
@@ -4454,6 +4710,7 @@
 
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: client max_int+1 chain, server default" \
             "$P_SRV ca_file=data_files/dir-maxpath/00.crt" \
             "$P_CLI crt_file=data_files/dir-maxpath/c10.pem \
@@ -4463,6 +4720,7 @@
 
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: client max_int+1 chain, server optional" \
             "$P_SRV ca_file=data_files/dir-maxpath/00.crt auth_mode=optional" \
             "$P_CLI crt_file=data_files/dir-maxpath/c10.pem \
@@ -4472,6 +4730,7 @@
 
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: client max_int+1 chain, server required" \
             "$P_SRV ca_file=data_files/dir-maxpath/00.crt auth_mode=required" \
             "$P_CLI crt_file=data_files/dir-maxpath/c10.pem \
@@ -4481,6 +4740,7 @@
 
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: client max_int chain, server required" \
             "$P_SRV ca_file=data_files/dir-maxpath/00.crt auth_mode=required" \
             "$P_CLI crt_file=data_files/dir-maxpath/c09.pem \
@@ -4490,6 +4750,7 @@
 
 # Tests for CA list in CertificateRequest messages
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: send CA list in CertificateRequest  (default)" \
             "$P_SRV debug_level=3 auth_mode=required" \
             "$P_CLI crt_file=data_files/server6.crt \
@@ -4497,6 +4758,7 @@
             0 \
             -s "requested DN"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: do not send CA list in CertificateRequest" \
             "$P_SRV debug_level=3 auth_mode=required cert_req_ca_list=0" \
             "$P_CLI crt_file=data_files/server6.crt \
@@ -4504,6 +4766,7 @@
             0 \
             -S "requested DN"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication: send CA list in CertificateRequest, client self signed" \
             "$P_SRV debug_level=3 auth_mode=required cert_req_ca_list=0" \
             "$P_CLI debug_level=3 crt_file=data_files/server5-selfsigned.crt \
@@ -4520,6 +4783,7 @@
 # When updating these tests, modify the matching authentication tests accordingly
 
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication, CA callback: server badcert, client required" \
             "$P_SRV crt_file=data_files/server5-badsign.crt \
              key_file=data_files/server5.key" \
@@ -4532,6 +4796,7 @@
             -c "X509 - Certificate verification failed"
 
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication, CA callback: server badcert, client optional" \
             "$P_SRV crt_file=data_files/server5-badsign.crt \
              key_file=data_files/server5.key" \
@@ -4552,6 +4817,7 @@
 
 requires_config_enabled MBEDTLS_ECP_C
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication, CA callback: server ECDH p256v1, client required, p256v1 unsupported" \
             "$P_SRV debug_level=1 key_file=data_files/server5.key \
              crt_file=data_files/server5.ku-ka.crt" \
@@ -4564,6 +4830,7 @@
 
 requires_config_enabled MBEDTLS_ECP_C
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication, CA callback: server ECDH p256v1, client optional, p256v1 unsupported" \
             "$P_SRV debug_level=1 key_file=data_files/server5.key \
              crt_file=data_files/server5.ku-ka.crt" \
@@ -4575,6 +4842,7 @@
             -c "bad server certificate (ECDH curve)" # Expect failure only at ECDH params check
 
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication, CA callback: client SHA256, server required" \
             "$P_SRV ca_callback=1 debug_level=3 auth_mode=required" \
             "$P_CLI debug_level=3 crt_file=data_files/server6.crt \
@@ -4586,6 +4854,7 @@
             -c "Supported Signature Algorithm found: 5,"
 
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication, CA callback: client SHA384, server required" \
             "$P_SRV ca_callback=1 debug_level=3 auth_mode=required" \
             "$P_CLI debug_level=3 crt_file=data_files/server6.crt \
@@ -4597,6 +4866,7 @@
             -c "Supported Signature Algorithm found: 5,"
 
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication, CA callback: client badcert, server required" \
             "$P_SRV ca_callback=1 debug_level=3 auth_mode=required" \
             "$P_CLI debug_level=3 crt_file=data_files/server5-badsign.crt \
@@ -4620,6 +4890,7 @@
 # before reading the alert message.
 
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication, CA callback: client cert not trusted, server required" \
             "$P_SRV ca_callback=1 debug_level=3 auth_mode=required" \
             "$P_CLI debug_level=3 crt_file=data_files/server5-selfsigned.crt \
@@ -4639,6 +4910,7 @@
             -s "X509 - Certificate verification failed"
 
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication, CA callback: client badcert, server optional" \
             "$P_SRV ca_callback=1 debug_level=3 auth_mode=optional" \
             "$P_CLI debug_level=3 crt_file=data_files/server5-badsign.crt \
@@ -4660,6 +4932,7 @@
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication, CA callback: server max_int chain, client default" \
             "$P_SRV crt_file=data_files/dir-maxpath/c09.pem \
                     key_file=data_files/dir-maxpath/09.key" \
@@ -4671,6 +4944,7 @@
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication, CA callback: server max_int+1 chain, client default" \
             "$P_SRV crt_file=data_files/dir-maxpath/c10.pem \
                     key_file=data_files/dir-maxpath/10.key" \
@@ -4682,6 +4956,7 @@
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication, CA callback: server max_int+1 chain, client optional" \
             "$P_SRV crt_file=data_files/dir-maxpath/c10.pem \
                     key_file=data_files/dir-maxpath/10.key" \
@@ -4694,6 +4969,7 @@
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication, CA callback: client max_int+1 chain, server optional" \
             "$P_SRV ca_callback=1 debug_level=3 ca_file=data_files/dir-maxpath/00.crt auth_mode=optional" \
             "$P_CLI crt_file=data_files/dir-maxpath/c10.pem \
@@ -4705,6 +4981,7 @@
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication, CA callback: client max_int+1 chain, server required" \
             "$P_SRV ca_callback=1 debug_level=3 ca_file=data_files/dir-maxpath/00.crt auth_mode=required" \
             "$P_CLI crt_file=data_files/dir-maxpath/c10.pem \
@@ -4716,6 +4993,7 @@
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Authentication, CA callback: client max_int chain, server required" \
             "$P_SRV ca_callback=1 debug_level=3 ca_file=data_files/dir-maxpath/00.crt auth_mode=required" \
             "$P_CLI crt_file=data_files/dir-maxpath/c09.pem \
@@ -4727,6 +5005,7 @@
 # Tests for certificate selection based on SHA verson
 
 requires_config_disabled MBEDTLS_X509_REMOVE_INFO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Certificate hash: client TLS 1.2 -> SHA-2" \
             "$P_SRV crt_file=data_files/server5.crt \
                     key_file=data_files/server5.key \
@@ -4740,6 +5019,7 @@
 # tests for SNI
 
 requires_config_disabled MBEDTLS_X509_REMOVE_INFO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SNI: no SNI callback" \
             "$P_SRV debug_level=3 \
              crt_file=data_files/server5.crt key_file=data_files/server5.key" \
@@ -4750,6 +5030,7 @@
             -c "subject name *: C=NL, O=PolarSSL, CN=localhost"
 
 requires_config_disabled MBEDTLS_X509_REMOVE_INFO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SNI: matching cert 1" \
             "$P_SRV debug_level=3 \
              crt_file=data_files/server5.crt key_file=data_files/server5.key \
@@ -4761,6 +5042,7 @@
             -c "subject name *: C=NL, O=PolarSSL, CN=localhost"
 
 requires_config_disabled MBEDTLS_X509_REMOVE_INFO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SNI: matching cert 2" \
             "$P_SRV debug_level=3 \
              crt_file=data_files/server5.crt key_file=data_files/server5.key \
@@ -4772,6 +5054,7 @@
             -c "subject name *: C=NL, O=PolarSSL, CN=polarssl.example"
 
 requires_config_disabled MBEDTLS_X509_REMOVE_INFO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SNI: no matching cert" \
             "$P_SRV debug_level=3 \
              crt_file=data_files/server5.crt key_file=data_files/server5.key \
@@ -4784,6 +5067,7 @@
             -c "mbedtls_ssl_handshake returned" \
             -c "SSL - A fatal alert message was received from our peer"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SNI: client auth no override: optional" \
             "$P_SRV debug_level=3 auth_mode=optional \
              crt_file=data_files/server5.crt key_file=data_files/server5.key \
@@ -4797,6 +5081,7 @@
             -C "skip write certificate verify" \
             -S "skip parse certificate verify"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SNI: client auth override: none -> optional" \
             "$P_SRV debug_level=3 auth_mode=none \
              crt_file=data_files/server5.crt key_file=data_files/server5.key \
@@ -4810,6 +5095,7 @@
             -C "skip write certificate verify" \
             -S "skip parse certificate verify"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SNI: client auth override: optional -> none" \
             "$P_SRV debug_level=3 auth_mode=optional \
              crt_file=data_files/server5.crt key_file=data_files/server5.key \
@@ -4823,6 +5109,7 @@
             -c "skip write certificate verify" \
             -s "skip parse certificate verify"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SNI: CA no override" \
             "$P_SRV debug_level=3 auth_mode=optional \
              crt_file=data_files/server5.crt key_file=data_files/server5.key \
@@ -4841,6 +5128,7 @@
             -s "! The certificate is not correctly signed by the trusted CA" \
             -S "The certificate has been revoked (is on a CRL)"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SNI: CA override" \
             "$P_SRV debug_level=3 auth_mode=optional \
              crt_file=data_files/server5.crt key_file=data_files/server5.key \
@@ -4859,6 +5147,7 @@
             -S "! The certificate is not correctly signed by the trusted CA" \
             -S "The certificate has been revoked (is on a CRL)"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SNI: CA override with CRL" \
             "$P_SRV debug_level=3 auth_mode=optional \
              crt_file=data_files/server5.crt key_file=data_files/server5.key \
@@ -4880,6 +5169,7 @@
 # Tests for SNI and DTLS
 
 requires_config_disabled MBEDTLS_X509_REMOVE_INFO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SNI: DTLS, no SNI callback" \
             "$P_SRV debug_level=3 dtls=1 \
              crt_file=data_files/server5.crt key_file=data_files/server5.key" \
@@ -4890,6 +5180,7 @@
             -c "subject name *: C=NL, O=PolarSSL, CN=localhost"
 
 requires_config_disabled MBEDTLS_X509_REMOVE_INFO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SNI: DTLS, matching cert 1" \
             "$P_SRV debug_level=3 dtls=1 \
              crt_file=data_files/server5.crt key_file=data_files/server5.key \
@@ -4901,6 +5192,7 @@
             -c "subject name *: C=NL, O=PolarSSL, CN=localhost"
 
 requires_config_disabled MBEDTLS_X509_REMOVE_INFO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SNI: DTLS, matching cert 2" \
             "$P_SRV debug_level=3 dtls=1 \
              crt_file=data_files/server5.crt key_file=data_files/server5.key \
@@ -4911,6 +5203,7 @@
             -c "issuer name *: C=NL, O=PolarSSL, CN=PolarSSL Test CA" \
             -c "subject name *: C=NL, O=PolarSSL, CN=polarssl.example"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SNI: DTLS, no matching cert" \
             "$P_SRV debug_level=3 dtls=1 \
              crt_file=data_files/server5.crt key_file=data_files/server5.key \
@@ -4923,6 +5216,7 @@
             -c "mbedtls_ssl_handshake returned" \
             -c "SSL - A fatal alert message was received from our peer"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SNI: DTLS, client auth no override: optional" \
             "$P_SRV debug_level=3 auth_mode=optional dtls=1 \
              crt_file=data_files/server5.crt key_file=data_files/server5.key \
@@ -4936,6 +5230,7 @@
             -C "skip write certificate verify" \
             -S "skip parse certificate verify"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SNI: DTLS, client auth override: none -> optional" \
             "$P_SRV debug_level=3 auth_mode=none dtls=1 \
              crt_file=data_files/server5.crt key_file=data_files/server5.key \
@@ -4949,6 +5244,7 @@
             -C "skip write certificate verify" \
             -S "skip parse certificate verify"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SNI: DTLS, client auth override: optional -> none" \
             "$P_SRV debug_level=3 auth_mode=optional dtls=1 \
              crt_file=data_files/server5.crt key_file=data_files/server5.key \
@@ -4962,6 +5258,7 @@
             -c "skip write certificate verify" \
             -s "skip parse certificate verify"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SNI: DTLS, CA no override" \
             "$P_SRV debug_level=3 auth_mode=optional dtls=1 \
              crt_file=data_files/server5.crt key_file=data_files/server5.key \
@@ -4980,6 +5277,7 @@
             -s "! The certificate is not correctly signed by the trusted CA" \
             -S "The certificate has been revoked (is on a CRL)"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SNI: DTLS, CA override" \
             "$P_SRV debug_level=3 auth_mode=optional dtls=1 \
              crt_file=data_files/server5.crt key_file=data_files/server5.key \
@@ -4998,6 +5296,7 @@
             -S "! The certificate is not correctly signed by the trusted CA" \
             -S "The certificate has been revoked (is on a CRL)"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SNI: DTLS, CA override with CRL" \
             "$P_SRV debug_level=3 auth_mode=optional \
              crt_file=data_files/server5.crt key_file=data_files/server5.key dtls=1 \
@@ -5018,6 +5317,7 @@
 
 # Tests for non-blocking I/O: exercise a variety of handshake flows
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Non-blocking I/O: basic handshake" \
             "$P_SRV nbio=2 tickets=0 auth_mode=none" \
             "$P_CLI nbio=2 tickets=0" \
@@ -5026,6 +5326,7 @@
             -C "mbedtls_ssl_handshake returned" \
             -c "Read from server: .* bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Non-blocking I/O: client auth" \
             "$P_SRV nbio=2 tickets=0 auth_mode=required" \
             "$P_CLI nbio=2 tickets=0" \
@@ -5034,6 +5335,7 @@
             -C "mbedtls_ssl_handshake returned" \
             -c "Read from server: .* bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Non-blocking I/O: ticket" \
             "$P_SRV nbio=2 tickets=1 auth_mode=none" \
             "$P_CLI nbio=2 tickets=1" \
@@ -5042,6 +5344,7 @@
             -C "mbedtls_ssl_handshake returned" \
             -c "Read from server: .* bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Non-blocking I/O: ticket + client auth" \
             "$P_SRV nbio=2 tickets=1 auth_mode=required" \
             "$P_CLI nbio=2 tickets=1" \
@@ -5050,6 +5353,7 @@
             -C "mbedtls_ssl_handshake returned" \
             -c "Read from server: .* bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Non-blocking I/O: ticket + client auth + resume" \
             "$P_SRV nbio=2 tickets=1 auth_mode=required" \
             "$P_CLI nbio=2 tickets=1 reconnect=1" \
@@ -5058,6 +5362,7 @@
             -C "mbedtls_ssl_handshake returned" \
             -c "Read from server: .* bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Non-blocking I/O: ticket + resume" \
             "$P_SRV nbio=2 tickets=1 auth_mode=none" \
             "$P_CLI nbio=2 tickets=1 reconnect=1" \
@@ -5066,6 +5371,7 @@
             -C "mbedtls_ssl_handshake returned" \
             -c "Read from server: .* bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Non-blocking I/O: session-id resume" \
             "$P_SRV nbio=2 tickets=0 auth_mode=none" \
             "$P_CLI nbio=2 tickets=0 reconnect=1" \
@@ -5076,6 +5382,7 @@
 
 # Tests for event-driven I/O: exercise a variety of handshake flows
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Event-driven I/O: basic handshake" \
             "$P_SRV event=1 tickets=0 auth_mode=none" \
             "$P_CLI event=1 tickets=0" \
@@ -5084,6 +5391,7 @@
             -C "mbedtls_ssl_handshake returned" \
             -c "Read from server: .* bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Event-driven I/O: client auth" \
             "$P_SRV event=1 tickets=0 auth_mode=required" \
             "$P_CLI event=1 tickets=0" \
@@ -5092,6 +5400,7 @@
             -C "mbedtls_ssl_handshake returned" \
             -c "Read from server: .* bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Event-driven I/O: ticket" \
             "$P_SRV event=1 tickets=1 auth_mode=none" \
             "$P_CLI event=1 tickets=1" \
@@ -5100,6 +5409,7 @@
             -C "mbedtls_ssl_handshake returned" \
             -c "Read from server: .* bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Event-driven I/O: ticket + client auth" \
             "$P_SRV event=1 tickets=1 auth_mode=required" \
             "$P_CLI event=1 tickets=1" \
@@ -5108,6 +5418,7 @@
             -C "mbedtls_ssl_handshake returned" \
             -c "Read from server: .* bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Event-driven I/O: ticket + client auth + resume" \
             "$P_SRV event=1 tickets=1 auth_mode=required" \
             "$P_CLI event=1 tickets=1 reconnect=1" \
@@ -5116,6 +5427,7 @@
             -C "mbedtls_ssl_handshake returned" \
             -c "Read from server: .* bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Event-driven I/O: ticket + resume" \
             "$P_SRV event=1 tickets=1 auth_mode=none" \
             "$P_CLI event=1 tickets=1 reconnect=1" \
@@ -5124,6 +5436,7 @@
             -C "mbedtls_ssl_handshake returned" \
             -c "Read from server: .* bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Event-driven I/O: session-id resume" \
             "$P_SRV event=1 tickets=0 auth_mode=none" \
             "$P_CLI event=1 tickets=0 reconnect=1" \
@@ -5132,42 +5445,49 @@
             -C "mbedtls_ssl_handshake returned" \
             -c "Read from server: .* bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Event-driven I/O, DTLS: basic handshake" \
             "$P_SRV dtls=1 event=1 tickets=0 auth_mode=none" \
             "$P_CLI dtls=1 event=1 tickets=0" \
             0 \
             -c "Read from server: .* bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Event-driven I/O, DTLS: client auth" \
             "$P_SRV dtls=1 event=1 tickets=0 auth_mode=required" \
             "$P_CLI dtls=1 event=1 tickets=0" \
             0 \
             -c "Read from server: .* bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Event-driven I/O, DTLS: ticket" \
             "$P_SRV dtls=1 event=1 tickets=1 auth_mode=none" \
             "$P_CLI dtls=1 event=1 tickets=1" \
             0 \
             -c "Read from server: .* bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Event-driven I/O, DTLS: ticket + client auth" \
             "$P_SRV dtls=1 event=1 tickets=1 auth_mode=required" \
             "$P_CLI dtls=1 event=1 tickets=1" \
             0 \
             -c "Read from server: .* bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Event-driven I/O, DTLS: ticket + client auth + resume" \
             "$P_SRV dtls=1 event=1 tickets=1 auth_mode=required" \
             "$P_CLI dtls=1 event=1 tickets=1 reconnect=1 skip_close_notify=1" \
             0 \
             -c "Read from server: .* bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Event-driven I/O, DTLS: ticket + resume" \
             "$P_SRV dtls=1 event=1 tickets=1 auth_mode=none" \
             "$P_CLI dtls=1 event=1 tickets=1 reconnect=1 skip_close_notify=1" \
             0 \
             -c "Read from server: .* bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Event-driven I/O, DTLS: session-id resume" \
             "$P_SRV dtls=1 event=1 tickets=0 auth_mode=none" \
             "$P_CLI dtls=1 event=1 tickets=0 reconnect=1 skip_close_notify=1" \
@@ -5179,6 +5499,7 @@
 # within the same datagram as the Finished messages. In this situation, the
 # server MUST NOT idle on the underlying transport after handshake completion,
 # because the ApplicationData request has already been queued internally.
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Event-driven I/O, DTLS: session-id resume, UDP packing" \
             -p "$P_PXY pack=50" \
             "$P_SRV dtls=1 event=1 tickets=0 auth_mode=required" \
@@ -5188,6 +5509,7 @@
 
 # Tests for version negotiation
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Version check: all -> 1.2" \
             "$P_SRV" \
             "$P_CLI" \
@@ -5197,6 +5519,7 @@
             -s "Protocol is TLSv1.2" \
             -c "Protocol is TLSv1.2"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Not supported version check: cli TLS 1.0" \
             "$P_SRV" \
             "$G_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.0" \
@@ -5206,6 +5529,7 @@
             -S "Protocol is TLSv1.0" \
             -C "Handshake was completed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Not supported version check: cli TLS 1.1" \
             "$P_SRV" \
             "$G_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.1" \
@@ -5215,6 +5539,7 @@
             -S "Protocol is TLSv1.1" \
             -C "Handshake was completed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Not supported version check: srv max TLS 1.0" \
             "$G_SRV --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0" \
             "$P_CLI" \
@@ -5224,6 +5549,7 @@
             -S "Version: TLS1.0" \
             -C "Protocol is TLSv1.0"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Not supported version check: srv max TLS 1.1" \
             "$G_SRV --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.1" \
             "$P_CLI" \
@@ -5235,6 +5561,7 @@
 
 # Tests for ALPN extension
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "ALPN: none" \
             "$P_SRV debug_level=3" \
             "$P_CLI debug_level=3" \
@@ -5247,6 +5574,7 @@
             -C "Application Layer Protocol is" \
             -S "Application Layer Protocol is"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "ALPN: client only" \
             "$P_SRV debug_level=3" \
             "$P_CLI debug_level=3 alpn=abc,1234" \
@@ -5259,6 +5587,7 @@
             -c "Application Layer Protocol is (none)" \
             -S "Application Layer Protocol is"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "ALPN: server only" \
             "$P_SRV debug_level=3 alpn=abc,1234" \
             "$P_CLI debug_level=3" \
@@ -5271,6 +5600,7 @@
             -C "Application Layer Protocol is" \
             -s "Application Layer Protocol is (none)"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "ALPN: both, common cli1-srv1" \
             "$P_SRV debug_level=3 alpn=abc,1234" \
             "$P_CLI debug_level=3 alpn=abc,1234" \
@@ -5283,6 +5613,7 @@
             -c "Application Layer Protocol is abc" \
             -s "Application Layer Protocol is abc"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "ALPN: both, common cli2-srv1" \
             "$P_SRV debug_level=3 alpn=abc,1234" \
             "$P_CLI debug_level=3 alpn=1234,abc" \
@@ -5295,6 +5626,7 @@
             -c "Application Layer Protocol is abc" \
             -s "Application Layer Protocol is abc"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "ALPN: both, common cli1-srv2" \
             "$P_SRV debug_level=3 alpn=abc,1234" \
             "$P_CLI debug_level=3 alpn=1234,abcde" \
@@ -5307,6 +5639,7 @@
             -c "Application Layer Protocol is 1234" \
             -s "Application Layer Protocol is 1234"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "ALPN: both, no common" \
             "$P_SRV debug_level=3 alpn=abc,123" \
             "$P_CLI debug_level=3 alpn=1234,abcde" \
@@ -5323,6 +5656,7 @@
 # Tests for keyUsage in leaf certificates, part 1:
 # server-side certificate/suite selection
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "keyUsage srv: RSA, digitalSignature -> (EC)DHE-RSA" \
             "$P_SRV key_file=data_files/server2.key \
              crt_file=data_files/server2.ku-ds.crt" \
@@ -5331,6 +5665,7 @@
             -c "Ciphersuite is TLS-[EC]*DHE-RSA-WITH-"
 
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "keyUsage srv: RSA, keyEncipherment -> RSA" \
             "$P_SRV key_file=data_files/server2.key \
              crt_file=data_files/server2.ku-ke.crt" \
@@ -5338,6 +5673,7 @@
             0 \
             -c "Ciphersuite is TLS-RSA-WITH-"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "keyUsage srv: RSA, keyAgreement -> fail" \
             "$P_SRV key_file=data_files/server2.key \
              crt_file=data_files/server2.ku-ka.crt" \
@@ -5345,6 +5681,7 @@
             1 \
             -C "Ciphersuite is "
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "keyUsage srv: ECDSA, digitalSignature -> ECDHE-ECDSA" \
             "$P_SRV key_file=data_files/server5.key \
              crt_file=data_files/server5.ku-ds.crt" \
@@ -5353,6 +5690,7 @@
             -c "Ciphersuite is TLS-ECDHE-ECDSA-WITH-"
 
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "keyUsage srv: ECDSA, keyAgreement -> ECDH-" \
             "$P_SRV key_file=data_files/server5.key \
              crt_file=data_files/server5.ku-ka.crt" \
@@ -5360,6 +5698,7 @@
             0 \
             -c "Ciphersuite is TLS-ECDH-"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "keyUsage srv: ECDSA, keyEncipherment -> fail" \
             "$P_SRV key_file=data_files/server5.key \
              crt_file=data_files/server5.ku-ke.crt" \
@@ -5370,6 +5709,7 @@
 # Tests for keyUsage in leaf certificates, part 2:
 # client-side checking of server cert
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "keyUsage cli: DigitalSignature+KeyEncipherment, RSA: OK" \
             "$O_SRV -key data_files/server2.key \
              -cert data_files/server2.ku-ds_ke.crt" \
@@ -5380,6 +5720,7 @@
             -C "Processing of the Certificate handshake message failed" \
             -c "Ciphersuite is TLS-"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "keyUsage cli: DigitalSignature+KeyEncipherment, DHE-RSA: OK" \
             "$O_SRV -key data_files/server2.key \
              -cert data_files/server2.ku-ds_ke.crt" \
@@ -5390,6 +5731,7 @@
             -C "Processing of the Certificate handshake message failed" \
             -c "Ciphersuite is TLS-"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "keyUsage cli: KeyEncipherment, RSA: OK" \
             "$O_SRV -key data_files/server2.key \
              -cert data_files/server2.ku-ke.crt" \
@@ -5400,6 +5742,7 @@
             -C "Processing of the Certificate handshake message failed" \
             -c "Ciphersuite is TLS-"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "keyUsage cli: KeyEncipherment, DHE-RSA: fail" \
             "$O_SRV -key data_files/server2.key \
              -cert data_files/server2.ku-ke.crt" \
@@ -5410,6 +5753,7 @@
             -c "Processing of the Certificate handshake message failed" \
             -C "Ciphersuite is TLS-"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "keyUsage cli: KeyEncipherment, DHE-RSA: fail, soft" \
             "$O_SRV -key data_files/server2.key \
              -cert data_files/server2.ku-ke.crt" \
@@ -5421,6 +5765,7 @@
             -c "Ciphersuite is TLS-" \
             -c "! Usage does not match the keyUsage extension"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "keyUsage cli: DigitalSignature, DHE-RSA: OK" \
             "$O_SRV -key data_files/server2.key \
              -cert data_files/server2.ku-ds.crt" \
@@ -5431,6 +5776,7 @@
             -C "Processing of the Certificate handshake message failed" \
             -c "Ciphersuite is TLS-"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "keyUsage cli: DigitalSignature, RSA: fail" \
             "$O_SRV -key data_files/server2.key \
              -cert data_files/server2.ku-ds.crt" \
@@ -5441,6 +5787,7 @@
             -c "Processing of the Certificate handshake message failed" \
             -C "Ciphersuite is TLS-"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "keyUsage cli: DigitalSignature, RSA: fail, soft" \
             "$O_SRV -key data_files/server2.key \
              -cert data_files/server2.ku-ds.crt" \
@@ -5455,6 +5802,7 @@
 # Tests for keyUsage in leaf certificates, part 3:
 # server-side checking of client cert
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "keyUsage cli-auth: RSA, DigitalSignature: OK" \
             "$P_SRV debug_level=1 auth_mode=optional" \
             "$O_CLI -key data_files/server2.key \
@@ -5463,6 +5811,7 @@
             -S "bad certificate (usage extensions)" \
             -S "Processing of the Certificate handshake message failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "keyUsage cli-auth: RSA, KeyEncipherment: fail (soft)" \
             "$P_SRV debug_level=1 auth_mode=optional" \
             "$O_CLI -key data_files/server2.key \
@@ -5471,6 +5820,7 @@
             -s "bad certificate (usage extensions)" \
             -S "Processing of the Certificate handshake message failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "keyUsage cli-auth: RSA, KeyEncipherment: fail (hard)" \
             "$P_SRV debug_level=1 auth_mode=required" \
             "$O_CLI -key data_files/server2.key \
@@ -5479,6 +5829,7 @@
             -s "bad certificate (usage extensions)" \
             -s "Processing of the Certificate handshake message failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "keyUsage cli-auth: ECDSA, DigitalSignature: OK" \
             "$P_SRV debug_level=1 auth_mode=optional" \
             "$O_CLI -key data_files/server5.key \
@@ -5487,6 +5838,7 @@
             -S "bad certificate (usage extensions)" \
             -S "Processing of the Certificate handshake message failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "keyUsage cli-auth: ECDSA, KeyAgreement: fail (soft)" \
             "$P_SRV debug_level=1 auth_mode=optional" \
             "$O_CLI -key data_files/server5.key \
@@ -5497,24 +5849,28 @@
 
 # Tests for extendedKeyUsage, part 1: server-side certificate/suite selection
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "extKeyUsage srv: serverAuth -> OK" \
             "$P_SRV key_file=data_files/server5.key \
              crt_file=data_files/server5.eku-srv.crt" \
             "$P_CLI" \
             0
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "extKeyUsage srv: serverAuth,clientAuth -> OK" \
             "$P_SRV key_file=data_files/server5.key \
              crt_file=data_files/server5.eku-srv.crt" \
             "$P_CLI" \
             0
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "extKeyUsage srv: codeSign,anyEKU -> OK" \
             "$P_SRV key_file=data_files/server5.key \
              crt_file=data_files/server5.eku-cs_any.crt" \
             "$P_CLI" \
             0
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "extKeyUsage srv: codeSign -> fail" \
             "$P_SRV key_file=data_files/server5.key \
              crt_file=data_files/server5.eku-cli.crt" \
@@ -5523,6 +5879,7 @@
 
 # Tests for extendedKeyUsage, part 2: client-side checking of server cert
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "extKeyUsage cli: serverAuth -> OK" \
             "$O_SRV -key data_files/server5.key \
              -cert data_files/server5.eku-srv.crt" \
@@ -5532,6 +5889,7 @@
             -C "Processing of the Certificate handshake message failed" \
             -c "Ciphersuite is TLS-"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "extKeyUsage cli: serverAuth,clientAuth -> OK" \
             "$O_SRV -key data_files/server5.key \
              -cert data_files/server5.eku-srv_cli.crt" \
@@ -5541,6 +5899,7 @@
             -C "Processing of the Certificate handshake message failed" \
             -c "Ciphersuite is TLS-"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "extKeyUsage cli: codeSign,anyEKU -> OK" \
             "$O_SRV -key data_files/server5.key \
              -cert data_files/server5.eku-cs_any.crt" \
@@ -5550,6 +5909,7 @@
             -C "Processing of the Certificate handshake message failed" \
             -c "Ciphersuite is TLS-"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "extKeyUsage cli: codeSign -> fail" \
             "$O_SRV -key data_files/server5.key \
              -cert data_files/server5.eku-cs.crt" \
@@ -5561,6 +5921,7 @@
 
 # Tests for extendedKeyUsage, part 3: server-side checking of client cert
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "extKeyUsage cli-auth: clientAuth -> OK" \
             "$P_SRV debug_level=1 auth_mode=optional" \
             "$O_CLI -key data_files/server5.key \
@@ -5569,6 +5930,7 @@
             -S "bad certificate (usage extensions)" \
             -S "Processing of the Certificate handshake message failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "extKeyUsage cli-auth: serverAuth,clientAuth -> OK" \
             "$P_SRV debug_level=1 auth_mode=optional" \
             "$O_CLI -key data_files/server5.key \
@@ -5577,6 +5939,7 @@
             -S "bad certificate (usage extensions)" \
             -S "Processing of the Certificate handshake message failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "extKeyUsage cli-auth: codeSign,anyEKU -> OK" \
             "$P_SRV debug_level=1 auth_mode=optional" \
             "$O_CLI -key data_files/server5.key \
@@ -5585,6 +5948,7 @@
             -S "bad certificate (usage extensions)" \
             -S "Processing of the Certificate handshake message failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "extKeyUsage cli-auth: codeSign -> fail (soft)" \
             "$P_SRV debug_level=1 auth_mode=optional" \
             "$O_CLI -key data_files/server5.key \
@@ -5593,6 +5957,7 @@
             -s "bad certificate (usage extensions)" \
             -S "Processing of the Certificate handshake message failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "extKeyUsage cli-auth: codeSign -> fail (hard)" \
             "$P_SRV debug_level=1 auth_mode=required" \
             "$O_CLI -key data_files/server5.key \
@@ -5603,6 +5968,7 @@
 
 # Tests for DHM parameters loading
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DHM parameters: reference" \
             "$P_SRV" \
             "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
@@ -5611,6 +5977,7 @@
             -c "value of 'DHM: P ' (2048 bits)" \
             -c "value of 'DHM: G ' (2 bits)"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DHM parameters: other parameters" \
             "$P_SRV dhm_file=data_files/dhparams.pem" \
             "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
@@ -5621,6 +5988,7 @@
 
 # Tests for DHM client-side size checking
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DHM size: server default, client default, OK" \
             "$P_SRV" \
             "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
@@ -5628,6 +5996,7 @@
             0 \
             -C "DHM prime too short:"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DHM size: server default, client 2048, OK" \
             "$P_SRV" \
             "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
@@ -5635,6 +6004,7 @@
             0 \
             -C "DHM prime too short:"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DHM size: server 1024, client default, OK" \
             "$P_SRV dhm_file=data_files/dhparams.pem" \
             "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
@@ -5642,6 +6012,7 @@
             0 \
             -C "DHM prime too short:"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DHM size: server 999, client 999, OK" \
             "$P_SRV dhm_file=data_files/dh.999.pem" \
             "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
@@ -5649,6 +6020,7 @@
             0 \
             -C "DHM prime too short:"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DHM size: server 1000, client 1000, OK" \
             "$P_SRV dhm_file=data_files/dh.1000.pem" \
             "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
@@ -5656,6 +6028,7 @@
             0 \
             -C "DHM prime too short:"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DHM size: server 1000, client default, rejected" \
             "$P_SRV dhm_file=data_files/dh.1000.pem" \
             "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
@@ -5663,6 +6036,7 @@
             1 \
             -c "DHM prime too short:"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DHM size: server 1000, client 1001, rejected" \
             "$P_SRV dhm_file=data_files/dh.1000.pem" \
             "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
@@ -5670,6 +6044,7 @@
             1 \
             -c "DHM prime too short:"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DHM size: server 999, client 1000, rejected" \
             "$P_SRV dhm_file=data_files/dh.999.pem" \
             "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
@@ -5677,6 +6052,7 @@
             1 \
             -c "DHM prime too short:"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DHM size: server 998, client 999, rejected" \
             "$P_SRV dhm_file=data_files/dh.998.pem" \
             "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
@@ -5684,6 +6060,7 @@
             1 \
             -c "DHM prime too short:"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DHM size: server default, client 2049, rejected" \
             "$P_SRV" \
             "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
@@ -5693,6 +6070,7 @@
 
 # Tests for PSK callback
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: psk, no callback" \
             "$P_SRV psk=abc123 psk_identity=foo" \
             "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
@@ -5703,6 +6081,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: opaque psk on client, no callback" \
             "$P_SRV extended_ms=0 debug_level=1 psk=abc123 psk_identity=foo" \
             "$P_CLI extended_ms=0 debug_level=1 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
@@ -5717,6 +6096,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: opaque psk on client, no callback, SHA-384" \
             "$P_SRV extended_ms=0 debug_level=1 psk=abc123 psk_identity=foo" \
             "$P_CLI extended_ms=0 debug_level=1 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384 \
@@ -5731,6 +6111,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: opaque psk on client, no callback, EMS" \
             "$P_SRV extended_ms=1 debug_level=3 psk=abc123 psk_identity=foo" \
             "$P_CLI extended_ms=1 debug_level=3 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
@@ -5745,6 +6126,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: opaque psk on client, no callback, SHA-384, EMS" \
             "$P_SRV extended_ms=1 debug_level=3 psk=abc123 psk_identity=foo" \
             "$P_CLI extended_ms=1 debug_level=3 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384 \
@@ -5759,6 +6141,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: raw psk on client, static opaque on server, no callback" \
             "$P_SRV extended_ms=0 debug_level=1 psk=abc123 psk_identity=foo psk_opaque=1 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA" \
             "$P_CLI extended_ms=0 debug_level=1 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
@@ -5773,6 +6156,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: raw psk on client, static opaque on server, no callback, SHA-384" \
             "$P_SRV extended_ms=0 debug_level=1 psk=abc123 psk_identity=foo psk_opaque=1 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384" \
             "$P_CLI extended_ms=0 debug_level=1 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384 \
@@ -5787,6 +6171,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: raw psk on client, static opaque on server, no callback, EMS" \
             "$P_SRV debug_level=3 psk=abc123 psk_identity=foo psk_opaque=1 min_version=tls12 \
             force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA extended_ms=1" \
@@ -5802,6 +6187,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: raw psk on client, static opaque on server, no callback, EMS, SHA384" \
             "$P_SRV debug_level=3 psk=abc123 psk_identity=foo psk_opaque=1 min_version=tls12 \
             force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384 extended_ms=1" \
@@ -5817,6 +6203,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: raw psk on client, no static PSK on server, opaque PSK from callback" \
             "$P_SRV extended_ms=0 debug_level=3 psk_list=abc,dead,def,beef psk_list_opaque=1 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA" \
             "$P_CLI extended_ms=0 debug_level=3 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
@@ -5831,6 +6218,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: raw psk on client, no static PSK on server, opaque PSK from callback, SHA-384" \
             "$P_SRV extended_ms=0 debug_level=3 psk_list=abc,dead,def,beef psk_list_opaque=1 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384" \
             "$P_CLI extended_ms=0 debug_level=3 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384 \
@@ -5845,6 +6233,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: raw psk on client, no static PSK on server, opaque PSK from callback, EMS" \
             "$P_SRV debug_level=3 psk_list=abc,dead,def,beef psk_list_opaque=1 min_version=tls12 \
             force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA extended_ms=1" \
@@ -5860,6 +6249,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: raw psk on client, no static PSK on server, opaque PSK from callback, EMS, SHA384" \
             "$P_SRV debug_level=3 psk_list=abc,dead,def,beef psk_list_opaque=1 min_version=tls12 \
             force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384 extended_ms=1" \
@@ -5875,6 +6265,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: raw psk on client, mismatching static raw PSK on server, opaque PSK from callback" \
             "$P_SRV extended_ms=0 psk_identity=foo psk=abc123 debug_level=3 psk_list=abc,dead,def,beef psk_list_opaque=1 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA" \
             "$P_CLI extended_ms=0 debug_level=3 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
@@ -5889,6 +6280,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: raw psk on client, mismatching static opaque PSK on server, opaque PSK from callback" \
             "$P_SRV extended_ms=0 psk_opaque=1 psk_identity=foo psk=abc123 debug_level=3 psk_list=abc,dead,def,beef psk_list_opaque=1 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA" \
             "$P_CLI extended_ms=0 debug_level=3 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
@@ -5903,6 +6295,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: raw psk on client, mismatching static opaque PSK on server, raw PSK from callback" \
             "$P_SRV extended_ms=0 psk_opaque=1 psk_identity=foo psk=abc123 debug_level=3 psk_list=abc,dead,def,beef min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA" \
             "$P_CLI extended_ms=0 debug_level=3 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
@@ -5916,6 +6309,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: raw psk on client, id-matching but wrong raw PSK on server, opaque PSK from callback" \
             "$P_SRV extended_ms=0 psk_opaque=1 psk_identity=def psk=abc123 debug_level=3 psk_list=abc,dead,def,beef min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA" \
             "$P_CLI extended_ms=0 debug_level=3 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
@@ -5929,6 +6323,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: raw psk on client, matching opaque PSK on server, wrong opaque PSK from callback" \
             "$P_SRV extended_ms=0 psk_opaque=1 psk_identity=def psk=beef debug_level=3 psk_list=abc,dead,def,abc123 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA" \
             "$P_CLI extended_ms=0 debug_level=3 min_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
@@ -5936,6 +6331,7 @@
             1 \
             -s "SSL - Verification of the message MAC failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: no psk, no callback" \
             "$P_SRV" \
             "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
@@ -5945,6 +6341,7 @@
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: callback overrides other settings" \
             "$P_SRV psk=abc123 psk_identity=foo psk_list=abc,dead,def,beef" \
             "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
@@ -5954,6 +6351,7 @@
             -s "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: first id matches" \
             "$P_SRV psk_list=abc,dead,def,beef" \
             "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
@@ -5963,6 +6361,7 @@
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: second id matches" \
             "$P_SRV psk_list=abc,dead,def,beef" \
             "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
@@ -5972,6 +6371,7 @@
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: no match" \
             "$P_SRV psk_list=abc,dead,def,beef" \
             "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
@@ -5981,6 +6381,7 @@
             -s "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "PSK callback: wrong key" \
             "$P_SRV psk_list=abc,dead,def,beef" \
             "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
@@ -5993,6 +6394,7 @@
 # Tests for EC J-PAKE
 
 requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "ECJPAKE: client not configured" \
             "$P_SRV debug_level=3" \
             "$P_CLI debug_level=3" \
@@ -6007,6 +6409,7 @@
             -S "SSL - The handshake negotiation failed"
 
 requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "ECJPAKE: server not configured" \
             "$P_SRV debug_level=3" \
             "$P_CLI debug_level=3 ecjpake_pw=bla \
@@ -6022,6 +6425,7 @@
             -s "SSL - The handshake negotiation failed"
 
 requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "ECJPAKE: working, TLS" \
             "$P_SRV debug_level=3 ecjpake_pw=bla" \
             "$P_CLI debug_level=3 ecjpake_pw=bla \
@@ -6040,6 +6444,7 @@
 
 server_needs_more_time 1
 requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "ECJPAKE: password mismatch, TLS" \
             "$P_SRV debug_level=3 ecjpake_pw=bla" \
             "$P_CLI debug_level=3 ecjpake_pw=bad \
@@ -6049,6 +6454,7 @@
             -s "SSL - Verification of the message MAC failed"
 
 requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "ECJPAKE: working, DTLS" \
             "$P_SRV debug_level=3 dtls=1 ecjpake_pw=bla" \
             "$P_CLI debug_level=3 dtls=1 ecjpake_pw=bla \
@@ -6058,6 +6464,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "ECJPAKE: working, DTLS, no cookie" \
             "$P_SRV debug_level=3 dtls=1 ecjpake_pw=bla cookies=0" \
             "$P_CLI debug_level=3 dtls=1 ecjpake_pw=bla \
@@ -6068,6 +6475,7 @@
 
 server_needs_more_time 1
 requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "ECJPAKE: password mismatch, DTLS" \
             "$P_SRV debug_level=3 dtls=1 ecjpake_pw=bla" \
             "$P_CLI debug_level=3 dtls=1 ecjpake_pw=bad \
@@ -6078,6 +6486,7 @@
 
 # for tests with configs/config-thread.h
 requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "ECJPAKE: working, DTLS, nolog" \
             "$P_SRV dtls=1 ecjpake_pw=bla" \
             "$P_CLI dtls=1 ecjpake_pw=bla \
@@ -6087,6 +6496,7 @@
 # Test for ClientHello without extensions
 
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "ClientHello without extensions" \
             "$P_SRV debug_level=3" \
             "$G_CLI --priority=NORMAL:%NO_EXTENSIONS:%DISABLE_SAFE_RENEGOTIATION localhost" \
@@ -6095,12 +6505,14 @@
 
 # Tests for mbedtls_ssl_get_bytes_avail()
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "mbedtls_ssl_get_bytes_avail: no extra data" \
             "$P_SRV" \
             "$P_CLI request_size=100" \
             0 \
             -s "Read from client: 100 bytes read$"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "mbedtls_ssl_get_bytes_avail: extra data" \
             "$P_SRV" \
             "$P_CLI request_size=500" \
@@ -6109,6 +6521,7 @@
 
 # Tests for small client packets
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Small client packet TLS 1.2 BlockCipher" \
             "$P_SRV" \
             "$P_CLI request_size=1 force_version=tls12 \
@@ -6116,6 +6529,7 @@
             0 \
             -s "Read from client: 1 bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Small client packet TLS 1.2 BlockCipher, without EtM" \
             "$P_SRV" \
             "$P_CLI request_size=1 force_version=tls12 \
@@ -6123,6 +6537,7 @@
             0 \
             -s "Read from client: 1 bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Small client packet TLS 1.2 BlockCipher larger MAC" \
             "$P_SRV" \
             "$P_CLI request_size=1 force_version=tls12 \
@@ -6130,6 +6545,7 @@
             0 \
             -s "Read from client: 1 bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Small client packet TLS 1.2 AEAD" \
             "$P_SRV" \
             "$P_CLI request_size=1 force_version=tls12 \
@@ -6137,6 +6553,7 @@
             0 \
             -s "Read from client: 1 bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Small client packet TLS 1.2 AEAD shorter tag" \
             "$P_SRV" \
             "$P_CLI request_size=1 force_version=tls12 \
@@ -6147,6 +6564,7 @@
 # Tests for small client packets in DTLS
 
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Small client packet DTLS 1.2" \
             "$P_SRV dtls=1 force_version=dtls12" \
             "$P_CLI dtls=1 request_size=1 \
@@ -6155,6 +6573,7 @@
             -s "Read from client: 1 bytes read"
 
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Small client packet DTLS 1.2, without EtM" \
             "$P_SRV dtls=1 force_version=dtls12 etm=0" \
             "$P_CLI dtls=1 request_size=1 \
@@ -6164,6 +6583,7 @@
 
 # Tests for small server packets
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Small server packet TLS 1.2 BlockCipher" \
             "$P_SRV response_size=1" \
             "$P_CLI force_version=tls12 \
@@ -6171,6 +6591,7 @@
             0 \
             -c "Read from server: 1 bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Small server packet TLS 1.2 BlockCipher, without EtM" \
             "$P_SRV response_size=1" \
             "$P_CLI force_version=tls12 \
@@ -6178,6 +6599,7 @@
             0 \
             -c "Read from server: 1 bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Small server packet TLS 1.2 BlockCipher larger MAC" \
             "$P_SRV response_size=1" \
             "$P_CLI force_version=tls12 \
@@ -6185,6 +6607,7 @@
             0 \
             -c "Read from server: 1 bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Small server packet TLS 1.2 AEAD" \
             "$P_SRV response_size=1" \
             "$P_CLI force_version=tls12 \
@@ -6192,6 +6615,7 @@
             0 \
             -c "Read from server: 1 bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Small server packet TLS 1.2 AEAD shorter tag" \
             "$P_SRV response_size=1" \
             "$P_CLI force_version=tls12 \
@@ -6202,6 +6626,7 @@
 # Tests for small server packets in DTLS
 
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Small server packet DTLS 1.2" \
             "$P_SRV dtls=1 response_size=1 force_version=dtls12" \
             "$P_CLI dtls=1 \
@@ -6210,6 +6635,7 @@
             -c "Read from server: 1 bytes read"
 
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Small server packet DTLS 1.2, without EtM" \
             "$P_SRV dtls=1 response_size=1 force_version=dtls12 etm=0" \
             "$P_CLI dtls=1 \
@@ -6224,6 +6650,7 @@
     echo "$(( ( $1 + $MAX_OUT_LEN - 1 ) / $MAX_OUT_LEN ))"
 }
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Large client packet TLS 1.2 BlockCipher" \
             "$P_SRV" \
             "$P_CLI request_size=16384 force_version=tls12 \
@@ -6232,6 +6659,7 @@
             -c "16384 bytes written in $(fragments_for_write 16384) fragments" \
             -s "Read from client: $MAX_CONTENT_LEN bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Large client packet TLS 1.2 BlockCipher, without EtM" \
             "$P_SRV" \
             "$P_CLI request_size=16384 force_version=tls12 etm=0 \
@@ -6239,6 +6667,7 @@
             0 \
             -s "Read from client: $MAX_CONTENT_LEN bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Large client packet TLS 1.2 BlockCipher larger MAC" \
             "$P_SRV" \
             "$P_CLI request_size=16384 force_version=tls12 \
@@ -6247,6 +6676,7 @@
             -c "16384 bytes written in $(fragments_for_write 16384) fragments" \
             -s "Read from client: $MAX_CONTENT_LEN bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Large client packet TLS 1.2 AEAD" \
             "$P_SRV" \
             "$P_CLI request_size=16384 force_version=tls12 \
@@ -6255,6 +6685,7 @@
             -c "16384 bytes written in $(fragments_for_write 16384) fragments" \
             -s "Read from client: $MAX_CONTENT_LEN bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Large client packet TLS 1.2 AEAD shorter tag" \
             "$P_SRV" \
             "$P_CLI request_size=16384 force_version=tls12 \
@@ -6264,6 +6695,7 @@
             -s "Read from client: $MAX_CONTENT_LEN bytes read"
 
 # The tests below fail when the server's OUT_CONTENT_LEN is less than 16384.
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Large server packet TLS 1.2 BlockCipher" \
             "$P_SRV response_size=16384" \
             "$P_CLI force_version=tls12 \
@@ -6271,6 +6703,7 @@
             0 \
             -c "Read from server: 16384 bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Large server packet TLS 1.2 BlockCipher, without EtM" \
             "$P_SRV response_size=16384" \
             "$P_CLI force_version=tls12 etm=0 \
@@ -6279,6 +6712,7 @@
             -s "16384 bytes written in 1 fragments" \
             -c "Read from server: 16384 bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Large server packet TLS 1.2 BlockCipher larger MAC" \
             "$P_SRV response_size=16384" \
             "$P_CLI force_version=tls12 \
@@ -6286,6 +6720,7 @@
             0 \
             -c "Read from server: 16384 bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Large server packet TLS 1.2 BlockCipher, without EtM, truncated MAC" \
             "$P_SRV response_size=16384 trunc_hmac=1" \
             "$P_CLI force_version=tls12 \
@@ -6294,6 +6729,7 @@
             -s "16384 bytes written in 1 fragments" \
             -c "Read from server: 16384 bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Large server packet TLS 1.2 AEAD" \
             "$P_SRV response_size=16384" \
             "$P_CLI force_version=tls12 \
@@ -6301,6 +6737,7 @@
             0 \
             -c "Read from server: 16384 bytes read"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Large server packet TLS 1.2 AEAD shorter tag" \
             "$P_SRV response_size=16384" \
             "$P_CLI force_version=tls12 \
@@ -6314,6 +6751,7 @@
 
 requires_config_enabled MBEDTLS_ECP_RESTARTABLE
 requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "EC restart: TLS, default" \
             "$P_SRV curves=secp256r1 auth_mode=required" \
             "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
@@ -6327,6 +6765,7 @@
 
 requires_config_enabled MBEDTLS_ECP_RESTARTABLE
 requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "EC restart: TLS, max_ops=0" \
             "$P_SRV curves=secp256r1 auth_mode=required" \
             "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
@@ -6340,6 +6779,7 @@
 
 requires_config_enabled MBEDTLS_ECP_RESTARTABLE
 requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "EC restart: TLS, max_ops=65535" \
             "$P_SRV curves=secp256r1 auth_mode=required" \
             "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
@@ -6353,6 +6793,7 @@
 
 requires_config_enabled MBEDTLS_ECP_RESTARTABLE
 requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "EC restart: TLS, max_ops=1000" \
             "$P_SRV curves=secp256r1 auth_mode=required" \
             "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
@@ -6366,6 +6807,7 @@
 
 requires_config_enabled MBEDTLS_ECP_RESTARTABLE
 requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "EC restart: TLS, max_ops=1000, badsign" \
             "$P_SRV curves=secp256r1 auth_mode=required \
              crt_file=data_files/server5-badsign.crt \
@@ -6384,6 +6826,7 @@
 
 requires_config_enabled MBEDTLS_ECP_RESTARTABLE
 requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "EC restart: TLS, max_ops=1000, auth_mode=optional badsign" \
             "$P_SRV curves=secp256r1 auth_mode=required \
              crt_file=data_files/server5-badsign.crt \
@@ -6402,6 +6845,7 @@
 
 requires_config_enabled MBEDTLS_ECP_RESTARTABLE
 requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "EC restart: TLS, max_ops=1000, auth_mode=none badsign" \
             "$P_SRV curves=secp256r1 auth_mode=required \
              crt_file=data_files/server5-badsign.crt \
@@ -6420,6 +6864,7 @@
 
 requires_config_enabled MBEDTLS_ECP_RESTARTABLE
 requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "EC restart: DTLS, max_ops=1000" \
             "$P_SRV curves=secp256r1 auth_mode=required dtls=1" \
             "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
@@ -6433,6 +6878,7 @@
 
 requires_config_enabled MBEDTLS_ECP_RESTARTABLE
 requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "EC restart: TLS, max_ops=1000 no client auth" \
             "$P_SRV curves=secp256r1" \
             "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
@@ -6445,6 +6891,7 @@
 
 requires_config_enabled MBEDTLS_ECP_RESTARTABLE
 requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "EC restart: TLS, max_ops=1000, ECDHE-PSK" \
             "$P_SRV curves=secp256r1 psk=abc123" \
             "$P_CLI force_ciphersuite=TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256 \
@@ -6458,6 +6905,7 @@
 # Tests of asynchronous private key support in SSL
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: sign, delay=0" \
             "$P_SRV \
              async_operations=s async_private_delay1=0 async_private_delay2=0" \
@@ -6467,6 +6915,7 @@
             -s "Async resume (slot [0-9]): sign done, status=0"
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: sign, delay=1" \
             "$P_SRV \
              async_operations=s async_private_delay1=1 async_private_delay2=1" \
@@ -6477,6 +6926,7 @@
             -s "Async resume (slot [0-9]): sign done, status=0"
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: sign, delay=2" \
             "$P_SRV \
              async_operations=s async_private_delay1=2 async_private_delay2=2" \
@@ -6490,6 +6940,7 @@
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
 requires_config_disabled MBEDTLS_X509_REMOVE_INFO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: sign, SNI" \
             "$P_SRV debug_level=3 \
              async_operations=s async_private_delay1=0 async_private_delay2=0 \
@@ -6504,6 +6955,7 @@
             -c "subject name *: C=NL, O=PolarSSL, CN=polarssl.example"
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: decrypt, delay=0" \
             "$P_SRV \
              async_operations=d async_private_delay1=0 async_private_delay2=0" \
@@ -6513,6 +6965,7 @@
             -s "Async resume (slot [0-9]): decrypt done, status=0"
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: decrypt, delay=1" \
             "$P_SRV \
              async_operations=d async_private_delay1=1 async_private_delay2=1" \
@@ -6523,6 +6976,7 @@
             -s "Async resume (slot [0-9]): decrypt done, status=0"
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: decrypt RSA-PSK, delay=0" \
             "$P_SRV psk=abc123 \
              async_operations=d async_private_delay1=0 async_private_delay2=0" \
@@ -6533,6 +6987,7 @@
             -s "Async resume (slot [0-9]): decrypt done, status=0"
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: decrypt RSA-PSK, delay=1" \
             "$P_SRV psk=abc123 \
              async_operations=d async_private_delay1=1 async_private_delay2=1" \
@@ -6544,6 +6999,7 @@
             -s "Async resume (slot [0-9]): decrypt done, status=0"
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: sign callback not present" \
             "$P_SRV \
              async_operations=d async_private_delay1=1 async_private_delay2=1" \
@@ -6557,6 +7013,7 @@
             -s "Successful connection"
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: decrypt callback not present" \
             "$P_SRV debug_level=1 \
              async_operations=s async_private_delay1=1 async_private_delay2=1" \
@@ -6571,6 +7028,7 @@
 
 # key1: ECDSA, key2: RSA; use key1 from slot 0
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: slot 0 used with key1" \
             "$P_SRV \
              async_operations=s async_private_delay1=1 \
@@ -6584,6 +7042,7 @@
 
 # key1: ECDSA, key2: RSA; use key2 from slot 0
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: slot 0 used with key2" \
             "$P_SRV \
              async_operations=s async_private_delay2=1 \
@@ -6597,6 +7056,7 @@
 
 # key1: ECDSA, key2: RSA; use key2 from slot 1
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: slot 1 used with key2" \
             "$P_SRV \
              async_operations=s async_private_delay1=1 async_private_delay2=1 \
@@ -6610,6 +7070,7 @@
 
 # key1: ECDSA, key2: RSA; use key2 directly
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: fall back to transparent key" \
             "$P_SRV \
              async_operations=s async_private_delay1=1 \
@@ -6620,6 +7081,7 @@
             -s "Async sign callback: no key matches this certificate."
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: sign, error in start" \
             "$P_SRV \
              async_operations=s async_private_delay1=1 async_private_delay2=1 \
@@ -6632,6 +7094,7 @@
             -s "! mbedtls_ssl_handshake returned"
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: sign, cancel after start" \
             "$P_SRV \
              async_operations=s async_private_delay1=1 async_private_delay2=1 \
@@ -6643,6 +7106,7 @@
             -s "Async cancel"
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: sign, error in resume" \
             "$P_SRV \
              async_operations=s async_private_delay1=1 async_private_delay2=1 \
@@ -6655,6 +7119,7 @@
             -s "! mbedtls_ssl_handshake returned"
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: decrypt, error in start" \
             "$P_SRV \
              async_operations=d async_private_delay1=1 async_private_delay2=1 \
@@ -6667,6 +7132,7 @@
             -s "! mbedtls_ssl_handshake returned"
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: decrypt, cancel after start" \
             "$P_SRV \
              async_operations=d async_private_delay1=1 async_private_delay2=1 \
@@ -6678,6 +7144,7 @@
             -s "Async cancel"
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: decrypt, error in resume" \
             "$P_SRV \
              async_operations=d async_private_delay1=1 async_private_delay2=1 \
@@ -6690,6 +7157,7 @@
             -s "! mbedtls_ssl_handshake returned"
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: cancel after start then operate correctly" \
             "$P_SRV \
              async_operations=s async_private_delay1=1 async_private_delay2=1 \
@@ -6702,6 +7170,7 @@
             -s "Successful connection"
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: error in resume then operate correctly" \
             "$P_SRV \
              async_operations=s async_private_delay1=1 async_private_delay2=1 \
@@ -6714,6 +7183,7 @@
 
 # key1: ECDSA, key2: RSA; use key1 through async, then key2 directly
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: cancel after start then fall back to transparent key" \
             "$P_SRV \
              async_operations=s async_private_delay1=1 async_private_error=-2 \
@@ -6732,6 +7202,7 @@
 
 # key1: ECDSA, key2: RSA; use key1 through async, then key2 directly
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: sign, error in resume then fall back to transparent key" \
             "$P_SRV \
              async_operations=s async_private_delay1=1 async_private_error=-3 \
@@ -6748,6 +7219,7 @@
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: renegotiation: client-initiated, sign" \
             "$P_SRV \
              async_operations=s async_private_delay1=1 async_private_delay2=1 \
@@ -6759,6 +7231,7 @@
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: renegotiation: server-initiated, sign" \
             "$P_SRV \
              async_operations=s async_private_delay1=1 async_private_delay2=1 \
@@ -6770,6 +7243,7 @@
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: renegotiation: client-initiated, decrypt" \
             "$P_SRV \
              async_operations=d async_private_delay1=1 async_private_delay2=1 \
@@ -6782,6 +7256,7 @@
 
 requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "SSL async private: renegotiation: server-initiated, decrypt" \
             "$P_SRV \
              async_operations=d async_private_delay1=1 async_private_delay2=1 \
@@ -6798,6 +7273,7 @@
 requires_config_enabled MBEDTLS_CIPHER_MODE_CBC
 requires_config_enabled MBEDTLS_SHA256_C
 requires_config_enabled MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Force a non ECC ciphersuite in the client side" \
             "$P_SRV debug_level=3" \
             "$P_CLI debug_level=3 force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA256" \
@@ -6811,6 +7287,7 @@
 requires_config_enabled MBEDTLS_CIPHER_MODE_CBC
 requires_config_enabled MBEDTLS_SHA256_C
 requires_config_enabled MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Force a non ECC ciphersuite in the server side" \
             "$P_SRV debug_level=3 force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA256" \
             "$P_CLI debug_level=3" \
@@ -6822,6 +7299,7 @@
 requires_config_enabled MBEDTLS_CIPHER_MODE_CBC
 requires_config_enabled MBEDTLS_SHA256_C
 requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Force an ECC ciphersuite in the client side" \
             "$P_SRV debug_level=3" \
             "$P_CLI debug_level=3 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256" \
@@ -6835,6 +7313,7 @@
 requires_config_enabled MBEDTLS_CIPHER_MODE_CBC
 requires_config_enabled MBEDTLS_SHA256_C
 requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "Force an ECC ciphersuite in the server side" \
             "$P_SRV debug_level=3 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256" \
             "$P_CLI debug_level=3" \
@@ -6844,6 +7323,7 @@
 
 # Tests for DTLS HelloVerifyRequest
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS cookie: enabled" \
             "$P_SRV dtls=1 debug_level=2" \
             "$P_CLI dtls=1 debug_level=2" \
@@ -6855,6 +7335,7 @@
             -s "hello verification requested" \
             -S "SSL - The requested feature is not available"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS cookie: disabled" \
             "$P_SRV dtls=1 debug_level=2 cookies=0" \
             "$P_CLI dtls=1 debug_level=2" \
@@ -6866,6 +7347,7 @@
             -S "hello verification requested" \
             -S "SSL - The requested feature is not available"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS cookie: default (failing)" \
             "$P_SRV dtls=1 debug_level=2 cookies=-1" \
             "$P_CLI dtls=1 debug_level=2 hs_timeout=100-400" \
@@ -6878,6 +7360,7 @@
             -s "SSL - The requested feature is not available"
 
 requires_ipv6
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS cookie: enabled, IPv6" \
             "$P_SRV dtls=1 debug_level=2 server_addr=::1" \
             "$P_CLI dtls=1 debug_level=2 server_addr=::1" \
@@ -6889,6 +7372,7 @@
             -s "hello verification requested" \
             -S "SSL - The requested feature is not available"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS cookie: enabled, nbio" \
             "$P_SRV dtls=1 nbio=2 debug_level=2" \
             "$P_CLI dtls=1 nbio=2 debug_level=2" \
@@ -6903,6 +7387,7 @@
 # Tests for client reconnecting from the same port with DTLS
 
 not_with_valgrind # spurious resend
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS client reconnect from same port: reference" \
             "$P_SRV dtls=1 exchanges=2 read_timeout=20000 hs_timeout=10000-20000" \
             "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=10000-20000" \
@@ -6912,6 +7397,7 @@
             -S "Client initiated reconnection from same port"
 
 not_with_valgrind # spurious resend
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS client reconnect from same port: reconnect" \
             "$P_SRV dtls=1 exchanges=2 read_timeout=20000 hs_timeout=10000-20000" \
             "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=10000-20000 reconnect_hard=1" \
@@ -6921,6 +7407,7 @@
             -s "Client initiated reconnection from same port"
 
 not_with_valgrind # server/client too slow to respond in time (next test has higher timeouts)
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS client reconnect from same port: reconnect, nbio, no valgrind" \
             "$P_SRV dtls=1 exchanges=2 read_timeout=1000 nbio=2" \
             "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=500-1000 reconnect_hard=1" \
@@ -6929,6 +7416,7 @@
             -s "Client initiated reconnection from same port"
 
 only_with_valgrind # Only with valgrind, do previous test but with higher read_timeout and hs_timeout
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS client reconnect from same port: reconnect, nbio, valgrind" \
             "$P_SRV dtls=1 exchanges=2 read_timeout=2000 nbio=2 hs_timeout=1500-6000" \
             "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=1500-3000 reconnect_hard=1" \
@@ -6936,6 +7424,7 @@
             -S "The operation timed out" \
             -s "Client initiated reconnection from same port"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS client reconnect from same port: no cookies" \
             "$P_SRV dtls=1 exchanges=2 read_timeout=1000 cookies=0" \
             "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=500-8000 reconnect_hard=1" \
@@ -6943,6 +7432,7 @@
             -s "The operation timed out" \
             -S "Client initiated reconnection from same port"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS client reconnect from same port: attacker-injected" \
             -p "$P_PXY inject_clihlo=1" \
             "$P_SRV dtls=1 exchanges=2 debug_level=1" \
@@ -6954,18 +7444,21 @@
 # Tests for various cases of client authentication with DTLS
 # (focused on handshake flows and message parsing)
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS client auth: required" \
             "$P_SRV dtls=1 auth_mode=required" \
             "$P_CLI dtls=1" \
             0 \
             -s "Verifying peer X.509 certificate... ok"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS client auth: optional, client has no cert" \
             "$P_SRV dtls=1 auth_mode=optional" \
             "$P_CLI dtls=1 crt_file=none key_file=none" \
             0 \
             -s "! Certificate was missing"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS client auth: none, client has no cert" \
             "$P_SRV dtls=1 auth_mode=none" \
             "$P_CLI dtls=1 crt_file=none key_file=none debug_level=2" \
@@ -6973,6 +7466,7 @@
             -c "skip write certificate$" \
             -s "! Certificate verification was skipped"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS wrong PSK: badmac alert" \
             "$P_SRV dtls=1 psk=abc123 force_ciphersuite=TLS-PSK-WITH-AES-128-GCM-SHA256" \
             "$P_CLI dtls=1 psk=abc124" \
@@ -6983,6 +7477,7 @@
 # Tests for receiving fragmented handshake messages with DTLS
 
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS reassembly: no fragmentation (gnutls server)" \
             "$G_SRV -u --mtu 2048 -a" \
             "$P_CLI dtls=1 debug_level=2" \
@@ -6991,6 +7486,7 @@
             -C "error"
 
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS reassembly: some fragmentation (gnutls server)" \
             "$G_SRV -u --mtu 512" \
             "$P_CLI dtls=1 debug_level=2" \
@@ -6999,6 +7495,7 @@
             -C "error"
 
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS reassembly: more fragmentation (gnutls server)" \
             "$G_SRV -u --mtu 128" \
             "$P_CLI dtls=1 debug_level=2" \
@@ -7007,6 +7504,7 @@
             -C "error"
 
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS reassembly: more fragmentation, nbio (gnutls server)" \
             "$G_SRV -u --mtu 128" \
             "$P_CLI dtls=1 nbio=2 debug_level=2" \
@@ -7016,6 +7514,7 @@
 
 requires_gnutls
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS reassembly: fragmentation, renego (gnutls server)" \
             "$G_SRV -u --mtu 256" \
             "$P_CLI debug_level=3 dtls=1 renegotiation=1 renegotiate=1" \
@@ -7030,6 +7529,7 @@
 
 requires_gnutls
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS reassembly: fragmentation, nbio, renego (gnutls server)" \
             "$G_SRV -u --mtu 256" \
             "$P_CLI debug_level=3 nbio=2 dtls=1 renegotiation=1 renegotiate=1" \
@@ -7042,6 +7542,7 @@
             -C "error" \
             -s "Extra-header:"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS reassembly: no fragmentation (openssl server)" \
             "$O_SRV -dtls -mtu 2048" \
             "$P_CLI dtls=1 debug_level=2" \
@@ -7049,6 +7550,7 @@
             -C "found fragmented DTLS handshake message" \
             -C "error"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS reassembly: some fragmentation (openssl server)" \
             "$O_SRV -dtls -mtu 768" \
             "$P_CLI dtls=1 debug_level=2" \
@@ -7056,6 +7558,7 @@
             -c "found fragmented DTLS handshake message" \
             -C "error"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS reassembly: more fragmentation (openssl server)" \
             "$O_SRV -dtls -mtu 256" \
             "$P_CLI dtls=1 debug_level=2" \
@@ -7063,6 +7566,7 @@
             -c "found fragmented DTLS handshake message" \
             -C "error"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS reassembly: fragmentation, nbio (openssl server)" \
             "$O_SRV -dtls -mtu 256" \
             "$P_CLI dtls=1 nbio=2 debug_level=2" \
@@ -7087,6 +7591,7 @@
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
 requires_max_content_len 4096
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: none (for reference)" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
@@ -7108,6 +7613,7 @@
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: server only (max_frag_len)" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
@@ -7133,6 +7639,7 @@
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
 requires_max_content_len 4096
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: server only (more) (max_frag_len)" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
@@ -7154,6 +7661,7 @@
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: client-initiated, server only (max_frag_len)" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=none \
              crt_file=data_files/server7_int-ca.crt \
@@ -7182,6 +7690,7 @@
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: client-initiated, server only (max_frag_len), proxy MTU" \
             -p "$P_PXY mtu=1110" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=none \
@@ -7204,6 +7713,7 @@
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: client-initiated, both (max_frag_len)" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
@@ -7232,6 +7742,7 @@
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: client-initiated, both (max_frag_len), proxy MTU" \
             -p "$P_PXY mtu=1110" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -7253,6 +7764,7 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_max_content_len 4096
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: none (for reference) (MTU)" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
@@ -7273,6 +7785,7 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_max_content_len 4096
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: client (MTU)" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
@@ -7293,6 +7806,7 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: server (MTU)" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
@@ -7313,6 +7827,7 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: both (MTU=1024)" \
             -p "$P_PXY mtu=1024" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -7339,6 +7854,7 @@
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_GCM_C
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: both (MTU=512)" \
             -p "$P_PXY mtu=512" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -7371,6 +7887,7 @@
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_GCM_C
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: proxy MTU: auto-reduction (not valgrind)" \
             -p "$P_PXY mtu=508" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -7396,6 +7913,7 @@
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_GCM_C
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: proxy MTU: auto-reduction (with valgrind)" \
             -p "$P_PXY mtu=508" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -7420,6 +7938,7 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: proxy MTU, simple handshake (MTU=1024)" \
             -p "$P_PXY mtu=1024" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -7450,6 +7969,7 @@
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_GCM_C
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: proxy MTU, simple handshake (MTU=512)" \
             -p "$P_PXY mtu=512" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -7474,6 +7994,7 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: proxy MTU, simple handshake, nbio (MTU=1024)" \
             -p "$P_PXY mtu=1024" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -7501,6 +8022,7 @@
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_GCM_C
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: proxy MTU, simple handshake, nbio (MTU=512)" \
             -p "$P_PXY mtu=512" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -7538,6 +8060,7 @@
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_GCM_C
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: proxy MTU, resumed handshake" \
             -p "$P_PXY mtu=1450" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -7568,6 +8091,7 @@
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 requires_config_enabled MBEDTLS_CHACHAPOLY_C
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: proxy MTU, ChachaPoly renego" \
             -p "$P_PXY mtu=512" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -7601,6 +8125,7 @@
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_GCM_C
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: proxy MTU, AES-GCM renego" \
             -p "$P_PXY mtu=512" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -7634,6 +8159,7 @@
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_CCM_C
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: proxy MTU, AES-CCM renego" \
             -p "$P_PXY mtu=1024" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -7668,6 +8194,7 @@
 requires_config_enabled MBEDTLS_CIPHER_MODE_CBC
 requires_config_enabled MBEDTLS_SSL_ENCRYPT_THEN_MAC
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: proxy MTU, AES-CBC EtM renego" \
             -p "$P_PXY mtu=1024" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -7701,6 +8228,7 @@
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_CIPHER_MODE_CBC
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: proxy MTU, AES-CBC non-EtM renego" \
             -p "$P_PXY mtu=1024" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -7731,6 +8259,7 @@
 requires_config_enabled MBEDTLS_GCM_C
 client_needs_more_time 2
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: proxy MTU + 3d" \
             -p "$P_PXY mtu=512 drop=8 delay=8 duplicate=8" \
             "$P_SRV dgram_packing=0 dtls=1 debug_level=2 auth_mode=required \
@@ -7756,6 +8285,7 @@
 requires_config_enabled MBEDTLS_GCM_C
 client_needs_more_time 2
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: proxy MTU + 3d, nbio" \
             -p "$P_PXY mtu=512 drop=8 delay=8 duplicate=8" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -7782,6 +8312,7 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_gnutls
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: gnutls server, DTLS 1.2" \
             "$G_SRV -u" \
             "$P_CLI dtls=1 debug_level=2 \
@@ -7806,6 +8337,7 @@
 requires_gnutls
 requires_not_i686
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: gnutls client, DTLS 1.2" \
             "$P_SRV dtls=1 debug_level=2 \
              crt_file=data_files/server7_int-ca.crt \
@@ -7820,6 +8352,7 @@
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: openssl server, DTLS 1.2" \
             "$O_SRV -dtls1_2 -verify 10" \
             "$P_CLI dtls=1 debug_level=2 \
@@ -7835,6 +8368,7 @@
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: openssl client, DTLS 1.2" \
             "$P_SRV dtls=1 debug_level=2 \
              crt_file=data_files/server7_int-ca.crt \
@@ -7855,6 +8389,7 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 client_needs_more_time 4
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: 3d, gnutls server, DTLS 1.2" \
             -p "$P_PXY drop=8 delay=8 duplicate=8" \
             "$G_NEXT_SRV -u" \
@@ -7873,6 +8408,7 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 client_needs_more_time 4
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: 3d, gnutls client, DTLS 1.2" \
             -p "$P_PXY drop=8 delay=8 duplicate=8" \
             "$P_SRV dtls=1 debug_level=2 \
@@ -7895,6 +8431,7 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 client_needs_more_time 4
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: 3d, openssl server, DTLS 1.2" \
             -p "$P_PXY drop=8 delay=8 duplicate=8" \
             "$O_SRV -dtls1_2 -verify 10" \
@@ -7913,6 +8450,7 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 client_needs_more_time 4
 requires_max_content_len 2048
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS fragmenting: 3d, openssl client, DTLS 1.2" \
             -p "$P_PXY drop=8 delay=8 duplicate=8" \
             "$P_SRV dtls=1 debug_level=2 \
@@ -7925,6 +8463,7 @@
 
 # Tests for DTLS-SRTP (RFC 5764)
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP all profiles supported" \
           "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
           "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
@@ -7944,6 +8483,7 @@
 
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server supports all profiles. Client supports one profile." \
           "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
           "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=5 debug_level=3" \
@@ -7962,6 +8502,7 @@
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server supports one profile. Client supports all profiles." \
           "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \
           "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
@@ -7980,6 +8521,7 @@
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server and Client support only one matching profile." \
           "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
           "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
@@ -7998,6 +8540,7 @@
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server and Client support only one different profile." \
           "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
           "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \
@@ -8015,6 +8558,7 @@
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server doesn't support use_srtp extension." \
           "$P_SRV dtls=1 debug_level=3" \
           "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
@@ -8030,6 +8574,7 @@
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP all profiles supported. mki used" \
           "$P_SRV dtls=1 use_srtp=1 support_mki=1 debug_level=3" \
           "$P_CLI dtls=1 use_srtp=1 mki=542310ab34290481 debug_level=3" \
@@ -8052,6 +8597,7 @@
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP all profiles supported. server doesn't support mki." \
           "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
           "$P_CLI dtls=1 use_srtp=1 mki=542310ab34290481 debug_level=3" \
@@ -8075,6 +8621,7 @@
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP all profiles supported. openssl client." \
           "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
           "$O_CLI -dtls -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
@@ -8088,6 +8635,7 @@
           -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_80"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. openssl client." \
           "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
           "$O_CLI -dtls -use_srtp SRTP_AES128_CM_SHA1_32:SRTP_AES128_CM_SHA1_80 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
@@ -8101,6 +8649,7 @@
           -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server supports all profiles. Client supports one profile. openssl client." \
           "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
           "$O_CLI -dtls -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
@@ -8114,6 +8663,7 @@
           -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server supports one profile. Client supports all profiles. openssl client." \
           "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
           "$O_CLI -dtls -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
@@ -8127,6 +8677,7 @@
           -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server and Client support only one matching profile. openssl client." \
           "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
           "$O_CLI -dtls -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
@@ -8140,6 +8691,7 @@
           -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server and Client support only one different profile. openssl client." \
           "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=1 debug_level=3" \
           "$O_CLI -dtls -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
@@ -8152,6 +8704,7 @@
           -C "SRTP Extension negotiated, profile"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server doesn't support use_srtp extension. openssl client" \
           "$P_SRV dtls=1 debug_level=3" \
           "$O_CLI -dtls -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
@@ -8162,6 +8715,7 @@
           -C "SRTP Extension negotiated, profile"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP all profiles supported. openssl server" \
           "$O_SRV -dtls -verify 0 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
@@ -8174,6 +8728,7 @@
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. openssl server." \
           "$O_SRV -dtls -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32:SRTP_AES128_CM_SHA1_80 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
@@ -8186,6 +8741,7 @@
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server supports all profiles. Client supports one profile. openssl server." \
           "$O_SRV -dtls -verify 0 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
@@ -8198,6 +8754,7 @@
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server supports one profile. Client supports all profiles. openssl server." \
           "$O_SRV -dtls -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
@@ -8210,6 +8767,7 @@
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server and Client support only one matching profile. openssl server." \
           "$O_SRV -dtls -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
@@ -8222,6 +8780,7 @@
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server and Client support only one different profile. openssl server." \
           "$O_SRV -dtls -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \
@@ -8234,6 +8793,7 @@
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server doesn't support use_srtp extension. openssl server" \
           "$O_SRV -dtls" \
           "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
@@ -8246,6 +8806,7 @@
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP all profiles supported. server doesn't support mki. openssl server." \
           "$O_SRV -dtls -verify 0 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           "$P_CLI dtls=1 use_srtp=1 mki=542310ab34290481 debug_level=3" \
@@ -8262,6 +8823,7 @@
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP all profiles supported. gnutls client." \
           "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
           "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32 --insecure 127.0.0.1" \
@@ -8275,6 +8837,7 @@
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. gnutls client." \
           "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
           "$G_CLI -u --srtp-profiles=SRTP_NULL_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_80:SRTP_NULL_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_32 --insecure 127.0.0.1" \
@@ -8288,6 +8851,7 @@
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server supports all profiles. Client supports one profile. gnutls client." \
           "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
           "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32 --insecure 127.0.0.1" \
@@ -8301,6 +8865,7 @@
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server supports one profile. Client supports all profiles. gnutls client." \
           "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \
           "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32 --insecure 127.0.0.1" \
@@ -8314,6 +8879,7 @@
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server and Client support only one matching profile. gnutls client." \
           "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
           "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32 --insecure 127.0.0.1" \
@@ -8327,6 +8893,7 @@
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server and Client support only one different profile. gnutls client." \
           "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=1 debug_level=3" \
           "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32 --insecure 127.0.0.1" \
@@ -8340,6 +8907,7 @@
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server doesn't support use_srtp extension. gnutls client" \
           "$P_SRV dtls=1 debug_level=3" \
           "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32 --insecure 127.0.0.1" \
@@ -8351,6 +8919,7 @@
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP all profiles supported. gnutls server" \
           "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
           "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
@@ -8364,6 +8933,7 @@
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. gnutls server." \
           "$G_SRV -u --srtp-profiles=SRTP_NULL_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_80:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
           "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
@@ -8377,6 +8947,7 @@
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server supports all profiles. Client supports one profile. gnutls server." \
           "$G_SRV -u --srtp-profiles=SRTP_NULL_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_80:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
           "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
@@ -8390,6 +8961,7 @@
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server supports one profile. Client supports all profiles. gnutls server." \
           "$G_SRV -u --srtp-profiles=SRTP_NULL_HMAC_SHA1_80" \
           "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
@@ -8403,6 +8975,7 @@
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server and Client support only one matching profile. gnutls server." \
           "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32" \
           "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
@@ -8416,6 +8989,7 @@
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server and Client support only one different profile. gnutls server." \
           "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32" \
           "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \
@@ -8429,6 +9003,7 @@
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP server doesn't support use_srtp extension. gnutls server" \
           "$G_SRV -u" \
           "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
@@ -8442,6 +9017,7 @@
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test  "DTLS-SRTP all profiles supported. mki used. gnutls server." \
           "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
           "$P_CLI dtls=1 use_srtp=1 mki=542310ab34290481 debug_level=3" \
@@ -8459,6 +9035,7 @@
 # Tests for specific things with "unreliable" UDP connection
 
 not_with_valgrind # spurious resend due to timeout
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: reference" \
             -p "$P_PXY" \
             "$P_SRV dtls=1 debug_level=2 hs_timeout=10000-20000" \
@@ -8477,6 +9054,7 @@
             -c "HTTP/1.0 200 OK"
 
 not_with_valgrind # spurious resend due to timeout
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: duplicate every packet" \
             -p "$P_PXY duplicate=1" \
             "$P_SRV dtls=1 dgram_packing=0 debug_level=2 hs_timeout=10000-20000" \
@@ -8490,6 +9068,7 @@
             -s "Extra-header:" \
             -c "HTTP/1.0 200 OK"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: duplicate every packet, server anti-replay off" \
             -p "$P_PXY duplicate=1" \
             "$P_SRV dtls=1 dgram_packing=0 debug_level=2 anti_replay=0" \
@@ -8504,6 +9083,7 @@
             -s "Extra-header:" \
             -c "HTTP/1.0 200 OK"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: multiple records in same datagram" \
             -p "$P_PXY pack=50" \
             "$P_SRV dtls=1 dgram_packing=0 debug_level=2" \
@@ -8512,6 +9092,7 @@
             -c "next record in same datagram" \
             -s "next record in same datagram"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: multiple records in same datagram, duplicate every packet" \
             -p "$P_PXY pack=50 duplicate=1" \
             "$P_SRV dtls=1 dgram_packing=0 debug_level=2" \
@@ -8520,6 +9101,7 @@
             -c "next record in same datagram" \
             -s "next record in same datagram"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: inject invalid AD record, default badmac_limit" \
             -p "$P_PXY bad_ad=1" \
             "$P_SRV dtls=1 dgram_packing=0 debug_level=1" \
@@ -8532,6 +9114,7 @@
             -S "too many records with bad MAC" \
             -S "Verification of the message MAC failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: inject invalid AD record, badmac_limit 1" \
             -p "$P_PXY bad_ad=1" \
             "$P_SRV dtls=1 dgram_packing=0 debug_level=1 badmac_limit=1" \
@@ -8544,6 +9127,7 @@
             -s "too many records with bad MAC" \
             -s "Verification of the message MAC failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: inject invalid AD record, badmac_limit 2" \
             -p "$P_PXY bad_ad=1" \
             "$P_SRV dtls=1 dgram_packing=0 debug_level=1 badmac_limit=2" \
@@ -8556,6 +9140,7 @@
             -S "too many records with bad MAC" \
             -S "Verification of the message MAC failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: inject invalid AD record, badmac_limit 2, exchanges 2"\
             -p "$P_PXY bad_ad=1" \
             "$P_SRV dtls=1 dgram_packing=0 debug_level=1 badmac_limit=2 exchanges=2" \
@@ -8568,6 +9153,7 @@
             -s "too many records with bad MAC" \
             -s "Verification of the message MAC failed"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: delay ChangeCipherSpec" \
             -p "$P_PXY delay_ccs=1" \
             "$P_SRV dtls=1 debug_level=1 dgram_packing=0" \
@@ -8580,6 +9166,7 @@
 
 # Tests for reordering support with DTLS
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS reordering: Buffer out-of-order handshake message on client" \
             -p "$P_PXY delay_srv=ServerHello" \
             "$P_SRV dgram_packing=0 cookies=0 dtls=1 debug_level=2 \
@@ -8596,6 +9183,7 @@
             -S "Injecting buffered CCS message" \
             -S "Remember CCS message"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS reordering: Buffer out-of-order handshake message fragment on client" \
             -p "$P_PXY delay_srv=ServerHello" \
             "$P_SRV mtu=512 dgram_packing=0 cookies=0 dtls=1 debug_level=2 \
@@ -8619,6 +9207,7 @@
 # in size, so that the bound below ensures that the certificate can be reassembled
 # while keeping the ServerKeyExchange.
 requires_config_value_at_least "MBEDTLS_SSL_DTLS_MAX_BUFFERING" 1300
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS reordering: Buffer out-of-order hs msg before reassembling next" \
             -p "$P_PXY delay_srv=Certificate delay_srv=Certificate" \
             "$P_SRV mtu=512 dgram_packing=0 cookies=0 dtls=1 debug_level=2 \
@@ -8641,6 +9230,7 @@
 # when dropping it first.
 requires_config_value_at_least "MBEDTLS_SSL_DTLS_MAX_BUFFERING" 900
 requires_config_value_at_most "MBEDTLS_SSL_DTLS_MAX_BUFFERING" 1299
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS reordering: Buffer out-of-order hs msg before reassembling next, free buffered msg" \
             -p "$P_PXY delay_srv=Certificate delay_srv=Certificate" \
             "$P_SRV mtu=512 dgram_packing=0 cookies=0 dtls=1 debug_level=2 \
@@ -8658,6 +9248,7 @@
             -S "Injecting buffered CCS message" \
             -S "Remember CCS message"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS reordering: Buffer out-of-order handshake message on server" \
             -p "$P_PXY delay_cli=Certificate" \
             "$P_SRV dgram_packing=0 auth_mode=required cookies=0 dtls=1 debug_level=2 \
@@ -8674,6 +9265,7 @@
             -S "Injecting buffered CCS message" \
             -S "Remember CCS message"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS reordering: Buffer out-of-order CCS message on client"\
             -p "$P_PXY delay_srv=NewSessionTicket" \
             "$P_SRV dgram_packing=0 cookies=0 dtls=1 debug_level=2 \
@@ -8690,6 +9282,7 @@
             -S "Injecting buffered CCS message" \
             -S "Remember CCS message"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS reordering: Buffer out-of-order CCS message on server"\
             -p "$P_PXY delay_cli=ClientKeyExchange" \
             "$P_SRV dgram_packing=0 cookies=0 dtls=1 debug_level=2 \
@@ -8706,6 +9299,7 @@
             -s "Injecting buffered CCS message" \
             -s "Remember CCS message"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS reordering: Buffer encrypted Finished message" \
             -p "$P_PXY delay_ccs=1" \
             "$P_SRV dgram_packing=0 cookies=0 dtls=1 debug_level=2 \
@@ -8735,6 +9329,7 @@
 #   handshake, omitting CRTs.
 requires_config_value_at_least "MBEDTLS_SSL_DTLS_MAX_BUFFERING" 190
 requires_config_value_at_most "MBEDTLS_SSL_DTLS_MAX_BUFFERING" 230
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS reordering: Buffer encrypted Finished message, drop for fragmented NewSessionTicket" \
             -p "$P_PXY delay_srv=NewSessionTicket delay_srv=NewSessionTicket delay_ccs=1" \
             "$P_SRV mtu=140 response_size=90 dgram_packing=0 psk=abc123 psk_identity=foo cookies=0 dtls=1 debug_level=2" \
@@ -8749,6 +9344,7 @@
 # Tests for "randomly unreliable connection": try a variety of flows and peers
 
 client_needs_more_time 2
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: 3d (drop, delay, duplicate), \"short\" PSK handshake" \
             -p "$P_PXY drop=5 delay=5 duplicate=5" \
             "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 auth_mode=none \
@@ -8760,6 +9356,7 @@
             -c "HTTP/1.0 200 OK"
 
 client_needs_more_time 2
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: 3d, \"short\" RSA handshake" \
             -p "$P_PXY drop=5 delay=5 duplicate=5" \
             "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 auth_mode=none" \
@@ -8770,6 +9367,7 @@
             -c "HTTP/1.0 200 OK"
 
 client_needs_more_time 2
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: 3d, \"short\" (no ticket, no cli_auth) FS handshake" \
             -p "$P_PXY drop=5 delay=5 duplicate=5" \
             "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 auth_mode=none" \
@@ -8779,6 +9377,7 @@
             -c "HTTP/1.0 200 OK"
 
 client_needs_more_time 2
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: 3d, FS, client auth" \
             -p "$P_PXY drop=5 delay=5 duplicate=5" \
             "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 auth_mode=required" \
@@ -8788,6 +9387,7 @@
             -c "HTTP/1.0 200 OK"
 
 client_needs_more_time 2
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: 3d, FS, ticket" \
             -p "$P_PXY drop=5 delay=5 duplicate=5" \
             "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=1 auth_mode=none" \
@@ -8797,6 +9397,7 @@
             -c "HTTP/1.0 200 OK"
 
 client_needs_more_time 2
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: 3d, max handshake (FS, ticket + client auth)" \
             -p "$P_PXY drop=5 delay=5 duplicate=5" \
             "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=1 auth_mode=required" \
@@ -8806,6 +9407,7 @@
             -c "HTTP/1.0 200 OK"
 
 client_needs_more_time 2
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: 3d, max handshake, nbio" \
             -p "$P_PXY drop=5 delay=5 duplicate=5" \
             "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 nbio=2 tickets=1 \
@@ -8816,6 +9418,7 @@
             -c "HTTP/1.0 200 OK"
 
 client_needs_more_time 4
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: 3d, min handshake, resumption" \
             -p "$P_PXY drop=5 delay=5 duplicate=5" \
             "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 auth_mode=none \
@@ -8830,6 +9433,7 @@
             -c "HTTP/1.0 200 OK"
 
 client_needs_more_time 4
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: 3d, min handshake, resumption, nbio" \
             -p "$P_PXY drop=5 delay=5 duplicate=5" \
             "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 auth_mode=none \
@@ -8845,6 +9449,7 @@
 
 client_needs_more_time 4
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: 3d, min handshake, client-initiated renego" \
             -p "$P_PXY drop=5 delay=5 duplicate=5" \
             "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 auth_mode=none \
@@ -8860,6 +9465,7 @@
 
 client_needs_more_time 4
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: 3d, min handshake, client-initiated renego, nbio" \
             -p "$P_PXY drop=5 delay=5 duplicate=5" \
             "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 auth_mode=none \
@@ -8875,6 +9481,7 @@
 
 client_needs_more_time 4
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: 3d, min handshake, server-initiated renego" \
             -p "$P_PXY drop=5 delay=5 duplicate=5" \
             "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 auth_mode=none \
@@ -8891,6 +9498,7 @@
 
 client_needs_more_time 4
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: 3d, min handshake, server-initiated renego, nbio" \
             -p "$P_PXY drop=5 delay=5 duplicate=5" \
             "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 auth_mode=none \
@@ -8913,6 +9521,7 @@
 skip_next_test
 client_needs_more_time 6
 not_with_valgrind # risk of non-mbedtls peer timing out
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: 3d, openssl server" \
             -p "$P_PXY drop=5 delay=5 duplicate=5 protect_hvr=1" \
             "$O_SRV -dtls1 -mtu 2048" \
@@ -8923,6 +9532,7 @@
 skip_next_test # see above
 client_needs_more_time 8
 not_with_valgrind # risk of non-mbedtls peer timing out
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: 3d, openssl server, fragmentation" \
             -p "$P_PXY drop=5 delay=5 duplicate=5 protect_hvr=1" \
             "$O_SRV -dtls1 -mtu 768" \
@@ -8933,6 +9543,7 @@
 skip_next_test # see above
 client_needs_more_time 8
 not_with_valgrind # risk of non-mbedtls peer timing out
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: 3d, openssl server, fragmentation, nbio" \
             -p "$P_PXY drop=5 delay=5 duplicate=5 protect_hvr=1" \
             "$O_SRV -dtls1 -mtu 768" \
@@ -8943,6 +9554,7 @@
 requires_gnutls
 client_needs_more_time 6
 not_with_valgrind # risk of non-mbedtls peer timing out
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: 3d, gnutls server" \
             -p "$P_PXY drop=5 delay=5 duplicate=5" \
             "$G_SRV -u --mtu 2048 -a" \
@@ -8954,6 +9566,7 @@
 requires_gnutls_next
 client_needs_more_time 8
 not_with_valgrind # risk of non-mbedtls peer timing out
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: 3d, gnutls server, fragmentation" \
             -p "$P_PXY drop=5 delay=5 duplicate=5" \
             "$G_NEXT_SRV -u --mtu 512" \
@@ -8965,6 +9578,7 @@
 requires_gnutls_next
 client_needs_more_time 8
 not_with_valgrind # risk of non-mbedtls peer timing out
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "DTLS proxy: 3d, gnutls server, fragmentation, nbio" \
             -p "$P_PXY drop=5 delay=5 duplicate=5" \
             "$G_NEXT_SRV -u --mtu 512" \
@@ -8973,6 +9587,7 @@
             -s "Extra-header:" \
             -c "Extra-header:"
 
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 run_test    "export keys functionality" \
             "$P_SRV eap_tls=1 debug_level=3" \
             "$P_CLI eap_tls=1 debug_level=3" \
@@ -9016,7 +9631,6 @@
             -s "Hybrid TLS 1.2 + TLS 1.3 configurations are not yet supported" \
             -c "Hybrid TLS 1.2 + TLS 1.3 configurations are not yet supported"
 
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
 run_test    "TLS 1.3: handshake dispatch test: tls13 only" \
             "$P_SRV debug_level=2 min_version=tls13 max_version=tls13" \
@@ -9030,7 +9644,6 @@
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 run_test    "TLS 1.3: minimal feature sets - openssl" \
             "$O_NEXT_SRV -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
             "$P_CLI debug_level=3 min_version=tls13 max_version=tls13" \
@@ -9063,7 +9676,6 @@
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 run_test    "TLS 1.3: minimal feature sets - gnutls" \
             "$G_NEXT_SRV --debug=4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:%NO_TICKETS --disable-client-cert" \
             "$P_CLI debug_level=3 min_version=tls13 max_version=tls13" \
@@ -9180,12 +9792,13 @@
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 run_test    "TLS 1.3: CertificateRequest check - openssl" \
             "$O_NEXT_SRV -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache -Verify 10" \
             "$P_CLI debug_level=4 force_version=tls13 " \
             1 \
-            -c "CertificateRequest not supported"
+            -c "=> parse certificate request" \
+            -c "got a certificate request" \
+            -c "<= parse certificate request"
 
 requires_gnutls_tls1_3
 requires_gnutls_next_no_ticket
@@ -9193,18 +9806,18 @@
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 run_test    "TLS 1.3: CertificateRequest check - gnutls" \
             "$G_NEXT_SRV --debug=4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:%NO_TICKETS" \
             "$P_CLI debug_level=3 min_version=tls13 max_version=tls13" \
             1 \
-            -c "CertificateRequest not supported"
+            -c "=> parse certificate request" \
+            -c "got a certificate request" \
+            -c "<= parse certificate request"
 
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_openssl_tls1_3
 run_test    "TLS 1.3: HelloRetryRequest check, ciphersuite TLS_AES_128_GCM_SHA256 - openssl" \
             "$O_NEXT_SRV -ciphersuites TLS_AES_128_GCM_SHA256  -sigalgs ecdsa_secp256r1_sha256 -groups P-256 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -9219,7 +9832,6 @@
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 requires_openssl_tls1_3
 run_test    "TLS 1.3: HelloRetryRequest check, ciphersuite TLS_AES_256_GCM_SHA384 - openssl" \
             "$O_NEXT_SRV -ciphersuites TLS_AES_256_GCM_SHA384  -sigalgs ecdsa_secp256r1_sha256 -groups P-256 -msg -tls1_3 -num_tickets 0 -no_resume_ephemeral -no_cache" \
@@ -9236,7 +9848,6 @@
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 run_test    "TLS 1.3: HelloRetryRequest check, ciphersuite TLS_AES_128_GCM_SHA256 - gnutls" \
             "$G_NEXT_SRV -d 4 --priority=NONE:+GROUP-SECP256R1:+AES-128-GCM:+SHA256:+AEAD:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS --disable-client-cert" \
             "$P_CLI debug_level=4 force_version=tls13" \
@@ -9252,7 +9863,6 @@
 requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 run_test    "TLS 1.3: HelloRetryRequest check, ciphersuite TLS_AES_256_GCM_SHA384 - gnutls" \
             "$G_NEXT_SRV -d 4 --priority=NONE:+GROUP-SECP256R1:+AES-256-GCM:+SHA384:+AEAD:+SIGN-ECDSA-SECP256R1-SHA256:+VERS-TLS1.3:%NO_TICKETS --disable-client-cert" \
             "$P_CLI debug_level=4 force_version=tls13" \
@@ -9262,17 +9872,19 @@
             -c "tls13 client state: MBEDTLS_SSL_CLIENT_HELLO" \
             -c "HTTP/1.0 200 OK"
 
-for i in $(ls opt-testcases/*.sh)
+for i in opt-testcases/*.sh
 do
-    . $i
+    TEST_SUITE_NAME=${i##*/}
+    TEST_SUITE_NAME=${TEST_SUITE_NAME%.*}
+    . "$i"
 done
+unset TEST_SUITE_NAME
 
 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
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 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 min_version=tls13 max_version=tls13" \
@@ -9284,7 +9896,6 @@
 requires_config_disabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 run_test    "TLS 1.3 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 min_version=tls13 max_version=tls13" \
@@ -9298,7 +9909,6 @@
 requires_config_disabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 run_test    "TLS 1.3 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 min_version=tls13 max_version=tls13" \
@@ -9311,7 +9921,6 @@
 requires_config_disabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
 requires_config_enabled MBEDTLS_DEBUG_C
 requires_config_enabled MBEDTLS_SSL_CLI_C
-requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
 run_test    "TLS 1.3 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 min_version=tls13 max_version=tls13" \
@@ -9319,6 +9928,7 @@
             -c "ChangeCipherSpec invalid in TLS 1.3 without compatibility mode"
 
 # Test heap memory usage after handshake
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_config_enabled MBEDTLS_MEMORY_DEBUG
 requires_config_enabled MBEDTLS_MEMORY_BUFFER_ALLOC_C
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
diff --git a/tests/suites/test_suite_hkdf.function b/tests/suites/test_suite_hkdf.function
index 6cb1118..feb1717 100644
--- a/tests/suites/test_suite_hkdf.function
+++ b/tests/suites/test_suite_hkdf.function
@@ -78,7 +78,7 @@
     const mbedtls_md_info_t *md = mbedtls_md_info_from_type( md_alg );
     TEST_ASSERT( md != NULL );
 
-    output_okm = mbedtls_calloc( OKM_LEN, 1 );
+    ASSERT_ALLOC( output_okm, OKM_LEN );
 
     prk = mbedtls_test_unhexify_alloc( hex_prk_string, &prk_len );
     info = mbedtls_test_unhexify_alloc( hex_info_string, &info_len );
@@ -143,10 +143,10 @@
     info_len = 0;
 
     if (prk_len > 0)
-        prk = mbedtls_calloc( prk_len, 1 );
+        ASSERT_ALLOC( prk, prk_len );
 
     if (okm_len > 0)
-        okm = mbedtls_calloc( okm_len, 1 );
+        ASSERT_ALLOC( okm, okm_len );
 
     output_ret = mbedtls_hkdf_expand( &fake_md_info, prk, prk_len,
                                       info, info_len, okm, okm_len );
diff --git a/tests/suites/test_suite_pem.data b/tests/suites/test_suite_pem.data
index 77546c5..59884e5 100644
--- a/tests/suites/test_suite_pem.data
+++ b/tests/suites/test_suite_pem.data
@@ -16,23 +16,26 @@
 PEM write (exactly two lines + 1)
 mbedtls_pem_write_buffer:"-----START TEST-----\n":"-----END TEST-----\n":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F00":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAA==\n-----END TEST-----\n"
 
+PEM read (unencrypted, valid)
+mbedtls_pem_read_buffer:"^":"$":"^\nTWJlZCBUTFM=\n$":"":0:"4d62656420544c53"
+
 PEM read (DES-EDE3-CBC + invalid iv)
-mbedtls_pem_read_buffer:"^":"$":"^\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: DES-EDE3-CBC,00$":"pwd":MBEDTLS_ERR_PEM_INVALID_ENC_IV
+mbedtls_pem_read_buffer:"^":"$":"^\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: DES-EDE3-CBC,00$":"pwd":MBEDTLS_ERR_PEM_INVALID_ENC_IV:""
 
 PEM read (DES-CBC + invalid iv)
-mbedtls_pem_read_buffer:"^":"$":"^\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: DES-CBC,00$":"pwd":MBEDTLS_ERR_PEM_INVALID_ENC_IV
+mbedtls_pem_read_buffer:"^":"$":"^\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: DES-CBC,00$":"pwd":MBEDTLS_ERR_PEM_INVALID_ENC_IV:""
 
 PEM read (unknown encryption algorithm)
-mbedtls_pem_read_buffer:"^":"$":"^\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: AES-,00$":"pwd":MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG
+mbedtls_pem_read_buffer:"^":"$":"^\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: AES-,00$":"pwd":MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG:""
 
 PEM read (malformed PEM DES-CBC)
 depends_on:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
-mbedtls_pem_read_buffer:"-----BEGIN EC PRIVATE KEY-----":"-----END EC PRIVATE KEY-----":"-----BEGIN EC PRIVATE KEY-----\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: DES-CBC,AA94892A169FA426\n\nMAAA\n-----END EC PRIVATE KEY-----":"pwd":MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH
+mbedtls_pem_read_buffer:"-----BEGIN EC PRIVATE KEY-----":"-----END EC PRIVATE KEY-----":"-----BEGIN EC PRIVATE KEY-----\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: DES-CBC,AA94892A169FA426\n\nMAAA\n-----END EC PRIVATE KEY-----":"pwd":MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:""
 
 PEM read (malformed PEM DES-EDE3-CBC)
 depends_on:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
-mbedtls_pem_read_buffer:"-----BEGIN EC PRIVATE KEY-----":"-----END EC PRIVATE KEY-----":"-----BEGIN EC PRIVATE KEY-----\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: DES-EDE3-CBC,AA94892A169FA426\n\nMAAA\n-----END EC PRIVATE KEY-----":"pwd":MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH
+mbedtls_pem_read_buffer:"-----BEGIN EC PRIVATE KEY-----":"-----END EC PRIVATE KEY-----":"-----BEGIN EC PRIVATE KEY-----\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: DES-EDE3-CBC,AA94892A169FA426\n\nMAAA\n-----END EC PRIVATE KEY-----":"pwd":MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:""
 
 PEM read (malformed PEM AES-128-CBC)
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
-mbedtls_pem_read_buffer:"-----BEGIN EC PRIVATE KEY-----":"-----END EC PRIVATE KEY-----":"-----BEGIN EC PRIVATE KEY-----\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: AES-128-CBC,AA94892A169FA426AA94892A169FA426\n\nMAAA\n-----END EC PRIVATE KEY-----":"pwd":MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
+mbedtls_pem_read_buffer:"-----BEGIN EC PRIVATE KEY-----":"-----END EC PRIVATE KEY-----":"-----BEGIN EC PRIVATE KEY-----\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: AES-128-CBC,AA94892A169FA426AA94892A169FA426\n\nMAAA\n-----END EC PRIVATE KEY-----":"pwd":MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:""
diff --git a/tests/suites/test_suite_pem.function b/tests/suites/test_suite_pem.function
index 947f1fb..bf5ac73 100644
--- a/tests/suites/test_suite_pem.function
+++ b/tests/suites/test_suite_pem.function
@@ -34,18 +34,26 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_AES_C:MBEDTLS_DES_C:MBEDTLS_MD5_C:MBEDTLS_CIPHER_MODE_CBC */
 void mbedtls_pem_read_buffer( char *header, char *footer, char *data,
-                              char *pwd, int res )
+                              char *pwd, int res, data_t *out )
 {
     mbedtls_pem_context ctx;
     int ret;
     size_t use_len = 0;
     size_t pwd_len = strlen( pwd );
+    const unsigned char *buf;
 
     mbedtls_pem_init( &ctx );
 
     ret = mbedtls_pem_read_buffer( &ctx, header, footer, (unsigned char *)data,
                 (unsigned char *)pwd, pwd_len, &use_len );
     TEST_ASSERT( ret == res );
+    if( ret != 0 )
+        goto exit;
+
+    use_len = 0;
+    buf = mbedtls_pem_get_buffer( &ctx, &use_len );
+    TEST_EQUAL( use_len, out->len );
+    TEST_ASSERT( memcmp( out->x, buf, out->len ) == 0 );
 
 exit:
     mbedtls_pem_free( &ctx );
diff --git a/tests/suites/test_suite_psa_its.data b/tests/suites/test_suite_psa_its.data
index 9057a1a..06aed07 100644
--- a/tests/suites/test_suite_psa_its.data
+++ b/tests/suites/test_suite_psa_its.data
@@ -1,71 +1,74 @@
 Set/get/remove 0 bytes
-set_get_remove:0:0:""
+set_get_remove:1:0:""
 
 Set/get/remove 42 bytes
-set_get_remove:0:0:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223242526272829"
+set_get_remove:1:0:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223242526272829"
 
 Set/get/remove 1000 bytes
-set_get_remove:0:0:"6a07ecfcc7c7bfe0129d56d2dcf2955a12845b9e6e0034b0ed7226764261c6222a07b9f654deb682130eb1cd07ed298324e60a46f9c76c8a5a0be000c69e93dd81054ca21fbc6190cef7745e9d5436f70e20e10cbf111d1d40c9ceb83be108775199d81abaf0fecfe30eaa08e7ed82517cba939de4449f7ac5c730fcbbf56e691640b0129db0e178045dd2034262de9138873d9bdca57685146a3d516ff13c29e6628a00097435a8e10fef7faff62d2963c303a93793e2211d8604556fec08cd59c0f5bd1f22eea64be13e88b3f454781e83fe6e771d3d81eb2fbe2021e276f42a93db5343d767d854115e74f5e129a8036b1e81aced9872709d515e00bcf2098ccdee23006b0e836b27dc8aaf30f53fe58a31a6408abb79b13098c22e262a98040f9b09809a3b43bd42eb01cf1d17bbc8b4dfe51fa6573d4d8741943e3ae71a649e194c1218f2e20556c7d8cfe8c64d8cc1aa94531fbf638768c7d19b3c079299cf4f26ed3f964efb8fd23d82b4157a51f46da11156c74e2d6e2fd788869ebb52429e12a82da2ba083e2e74565026162f29ca22582da72a2698e7c5d958b919bc2cdfe12f50364ccfed30efd5cd120a7d5f196b2bd7f911bb44d5871eb3dedcd70ece7faf464988f9fe361f23d7244b1e08bee921d0f28bdb4912675809d099876d4d15b7d13ece356e1f2a5dce64feb3d6749a07a4f2b7721190e17a9ab2966e48b6d25187070b81eb45b1c44608b2f0e175958ba57fcf1b2cd145eea5fd4de858d157ddac69dfbb5d5d6f0c1691b0fae5a143b6e58cdf5000f28d74b3322670ed11e740c828c7bfad4e2f392012da3ac931ea26ed15fd003e604071f5900c6e1329d021805d50da9f1e732a49bcc292d9f8e07737cfd59442e8d7aaa813b18183a68e22bf6b4519545dd7d2d519db3652be4131bad4f4b0625dbaa749e979f6ee8c1b97803cb50a2fa20dc883eac932a824b777b226e15294de6a80be3ddef41478fe18172d64407a004de6bae18bc60e90c902c1cbb0e1633395b42391f5011be0d480541987609b0cd8d902ea29f86f73e7362340119323eb0ea4f672b70d6e9a9df5235f9f1965f5cb0c2998c5a7f4754e83eeda5d95fefbbaaa0875fe37b7ca461e7281cc5479162627c5a709b45fd9ddcde4dfb40659e1d70fa7361d9fc7de24f9b8b13259423fdae4dbb98d691db687467a5a7eb027a4a0552a03e430ac8a32de0c30160ba60a036d6b9db2d6182193283337b92e7438dc5d6eb4fa00200d8efa9127f1c3a32ac8e202262773aaa5a965c6b8035b2e5706c32a55511560429ddf1df4ac34076b7eedd9cf94b6915a894fdd9084ffe3db0e7040f382c3cd04f0484595de95865c36b6bf20f46a78cdfb37228acbeb218de798b9586f6d99a0cbae47e80d"
+set_get_remove:1:0:"6a07ecfcc7c7bfe0129d56d2dcf2955a12845b9e6e0034b0ed7226764261c6222a07b9f654deb682130eb1cd07ed298324e60a46f9c76c8a5a0be000c69e93dd81054ca21fbc6190cef7745e9d5436f70e20e10cbf111d1d40c9ceb83be108775199d81abaf0fecfe30eaa08e7ed82517cba939de4449f7ac5c730fcbbf56e691640b0129db0e178045dd2034262de9138873d9bdca57685146a3d516ff13c29e6628a00097435a8e10fef7faff62d2963c303a93793e2211d8604556fec08cd59c0f5bd1f22eea64be13e88b3f454781e83fe6e771d3d81eb2fbe2021e276f42a93db5343d767d854115e74f5e129a8036b1e81aced9872709d515e00bcf2098ccdee23006b0e836b27dc8aaf30f53fe58a31a6408abb79b13098c22e262a98040f9b09809a3b43bd42eb01cf1d17bbc8b4dfe51fa6573d4d8741943e3ae71a649e194c1218f2e20556c7d8cfe8c64d8cc1aa94531fbf638768c7d19b3c079299cf4f26ed3f964efb8fd23d82b4157a51f46da11156c74e2d6e2fd788869ebb52429e12a82da2ba083e2e74565026162f29ca22582da72a2698e7c5d958b919bc2cdfe12f50364ccfed30efd5cd120a7d5f196b2bd7f911bb44d5871eb3dedcd70ece7faf464988f9fe361f23d7244b1e08bee921d0f28bdb4912675809d099876d4d15b7d13ece356e1f2a5dce64feb3d6749a07a4f2b7721190e17a9ab2966e48b6d25187070b81eb45b1c44608b2f0e175958ba57fcf1b2cd145eea5fd4de858d157ddac69dfbb5d5d6f0c1691b0fae5a143b6e58cdf5000f28d74b3322670ed11e740c828c7bfad4e2f392012da3ac931ea26ed15fd003e604071f5900c6e1329d021805d50da9f1e732a49bcc292d9f8e07737cfd59442e8d7aaa813b18183a68e22bf6b4519545dd7d2d519db3652be4131bad4f4b0625dbaa749e979f6ee8c1b97803cb50a2fa20dc883eac932a824b777b226e15294de6a80be3ddef41478fe18172d64407a004de6bae18bc60e90c902c1cbb0e1633395b42391f5011be0d480541987609b0cd8d902ea29f86f73e7362340119323eb0ea4f672b70d6e9a9df5235f9f1965f5cb0c2998c5a7f4754e83eeda5d95fefbbaaa0875fe37b7ca461e7281cc5479162627c5a709b45fd9ddcde4dfb40659e1d70fa7361d9fc7de24f9b8b13259423fdae4dbb98d691db687467a5a7eb027a4a0552a03e430ac8a32de0c30160ba60a036d6b9db2d6182193283337b92e7438dc5d6eb4fa00200d8efa9127f1c3a32ac8e202262773aaa5a965c6b8035b2e5706c32a55511560429ddf1df4ac34076b7eedd9cf94b6915a894fdd9084ffe3db0e7040f382c3cd04f0484595de95865c36b6bf20f46a78cdfb37228acbeb218de798b9586f6d99a0cbae47e80d"
 
 Set/get/remove with flags
-set_get_remove:0:0x12345678:"abcdef"
+set_get_remove:1:0x12345678:"abcdef"
 
 Overwrite 0 -> 3
-set_overwrite:0:0x12345678:"":0x01020304:"abcdef"
+set_overwrite:1:0x12345678:"":0x01020304:"abcdef"
 
 Overwrite 3 -> 0
-set_overwrite:0:0x12345678:"abcdef":0x01020304:""
+set_overwrite:1:0x12345678:"abcdef":0x01020304:""
 
 Overwrite 3 -> 3
-set_overwrite:0:0x12345678:"123456":0x01020304:"abcdef"
+set_overwrite:1:0x12345678:"123456":0x01020304:"abcdef"
 
 Overwrite 3 -> 18
-set_overwrite:0:0x12345678:"abcdef":0x01020304:"404142434445464748494a4b4c4d4e4f5051"
+set_overwrite:1:0x12345678:"abcdef":0x01020304:"404142434445464748494a4b4c4d4e4f5051"
 
 Overwrite 18 -> 3
-set_overwrite:0:0x12345678:"404142434445464748494a4b4c4d4e4f5051":0x01020304:"abcdef"
+set_overwrite:1:0x12345678:"404142434445464748494a4b4c4d4e4f5051":0x01020304:"abcdef"
 
 Multiple files
-set_multiple:0:5
+set_multiple:1:5
+
+Set UID 0
+set_fail:0:"40414243444546474849":PSA_ERROR_INVALID_HANDLE
 
 Non-existent file
-nonexistent:0:0
+nonexistent:1:0
 
 Removed file
-nonexistent:0:1
+nonexistent:1:1
 
 Get 0 bytes of 10 at 10
-get_at:0:"40414243444546474849":10:0:PSA_SUCCESS
+get_at:1:"40414243444546474849":10:0:PSA_SUCCESS
 
 Get 1 byte of 10 at 9
-get_at:0:"40414243444546474849":9:1:PSA_SUCCESS
+get_at:1:"40414243444546474849":9:1:PSA_SUCCESS
 
 Get 0 bytes of 10 at 0
-get_at:0:"40414243444546474849":0:0:PSA_SUCCESS
+get_at:1:"40414243444546474849":0:0:PSA_SUCCESS
 
 Get 1 byte of 10 at 0
-get_at:0:"40414243444546474849":0:1:PSA_SUCCESS
+get_at:1:"40414243444546474849":0:1:PSA_SUCCESS
 
 Get 2 bytes of 10 at 1
-get_at:0:"40414243444546474849":1:2:PSA_SUCCESS
+get_at:1:"40414243444546474849":1:2:PSA_SUCCESS
 
 Get 1 byte of 10 at 10: out of range
-get_at:0:"40414243444546474849":10:1:PSA_ERROR_INVALID_ARGUMENT
+get_at:1:"40414243444546474849":10:1:PSA_ERROR_INVALID_ARGUMENT
 
 Get 1 byte of 10 at 11: out of range
-get_at:0:"40414243444546474849":11:1:PSA_ERROR_INVALID_ARGUMENT
+get_at:1:"40414243444546474849":11:1:PSA_ERROR_INVALID_ARGUMENT
 
 Get 0 bytes of 10 at 11: out of range
-get_at:0:"40414243444546474849":11:0:PSA_ERROR_INVALID_ARGUMENT
+get_at:1:"40414243444546474849":11:0:PSA_ERROR_INVALID_ARGUMENT
 
 Get -1 byte of 10 at 10: out of range
-get_at:0:"40414243444546474849":10:-1:PSA_ERROR_INVALID_ARGUMENT
+get_at:1:"40414243444546474849":10:-1:PSA_ERROR_INVALID_ARGUMENT
 
 Get 1 byte of 10 at -1: out of range
-get_at:0:"40414243444546474849":-1:1:PSA_ERROR_INVALID_ARGUMENT
+get_at:1:"40414243444546474849":-1:1:PSA_ERROR_INVALID_ARGUMENT
 
 Overwrite ITS header magic
-get_fail:0:"40414243444546474849":1:0:PSA_ERROR_DATA_CORRUPT
+get_fail:1:"40414243444546474849":1:0:PSA_ERROR_DATA_CORRUPT
 
 Truncate ITS header
-get_fail:0:"40414243444546474849":0:1:PSA_ERROR_DATA_CORRUPT
+get_fail:1:"40414243444546474849":0:1:PSA_ERROR_DATA_CORRUPT
diff --git a/tests/suites/test_suite_psa_its.function b/tests/suites/test_suite_psa_its.function
index fb9ce07..e16c050 100644
--- a/tests/suites/test_suite_psa_its.function
+++ b/tests/suites/test_suite_psa_its.function
@@ -285,3 +285,16 @@
     cleanup( );
 }
 /* END_CASE */
+
+/* BEGIN_CASE */
+void set_fail( int uid_arg, data_t *data,
+               int expected_status )
+{
+    psa_storage_uid_t uid = uid_arg;
+    TEST_ASSERT( psa_its_set_wrap( uid, data->len, data->x, 0 ) ==
+                 (psa_status_t) expected_status );
+
+    exit:
+    cleanup( );
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data
index 4400afa..eb1b8f4 100644
--- a/tests/suites/test_suite_ssl.data
+++ b/tests/suites/test_suite_ssl.data
@@ -104,111 +104,147 @@
 mbedtls_endpoint_sanity:MBEDTLS_SSL_IS_SERVER
 
 Test moving clients handshake to state: HELLO_REQUEST
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_HELLO_REQUEST:1
 
 Test moving clients handshake to state: CLIENT_HELLO
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_CLIENT_HELLO:1
 
 Test moving clients handshake to state: SERVER_HELLO
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_SERVER_HELLO:1
 
 Test moving clients handshake to state: SERVER_CERTIFICATE
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_SERVER_CERTIFICATE:1
 
 Test moving clients handshake to state: SERVER_KEY_EXCHANGE
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_SERVER_KEY_EXCHANGE:1
 
 Test moving clients handshake to state: CERTIFICATE_REQUEST
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_CERTIFICATE_REQUEST:1
 
 Test moving clients handshake to state: SERVER_HELLO_DONE
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_SERVER_HELLO_DONE:1
 
 Test moving clients handshake to state: CLIENT_CERTIFICATE
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_CLIENT_CERTIFICATE:1
 
 Test moving clients handshake to state: CLIENT_KEY_EXCHANGE
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:1
 
 Test moving clients handshake to state: CERTIFICATE_VERIFY
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_CERTIFICATE_VERIFY:1
 
 Test moving clients handshake to state: CLIENT_CHANGE_CIPHER_SPEC
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:1
 
 Test moving clients handshake to state: CLIENT_FINISHED
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_CLIENT_FINISHED:1
 
 Test moving clients handshake to state: SERVER_CHANGE_CIPHER_SPEC
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:1
 
 Test moving clients handshake to state: SERVER_FINISHED
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_SERVER_FINISHED:1
 
 Test moving clients handshake to state: FLUSH_BUFFERS
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_FLUSH_BUFFERS:1
 
 Test moving clients handshake to state: HANDSHAKE_WRAPUP
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_HANDSHAKE_WRAPUP:1
 
 Test moving clients handshake to state: HANDSHAKE_OVER
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_HANDSHAKE_OVER:1
 
 Test moving servers handshake to state: HELLO_REQUEST
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_HELLO_REQUEST:1
 
 Test moving servers handshake to state: CLIENT_HELLO
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_CLIENT_HELLO:1
 
 Test moving servers handshake to state: SERVER_HELLO
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_SERVER_HELLO:1
 
 Test moving servers handshake to state: SERVER_CERTIFICATE
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_SERVER_CERTIFICATE:1
 
 Test moving servers handshake to state: SERVER_KEY_EXCHANGE
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_SERVER_KEY_EXCHANGE:1
 
 Test moving servers handshake to state: CERTIFICATE_REQUEST
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_CERTIFICATE_REQUEST:1
 
 Test moving servers handshake to state: SERVER_HELLO_DONE
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_SERVER_HELLO_DONE:1
 
 Test moving servers handshake to state: CLIENT_CERTIFICATE
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_CLIENT_CERTIFICATE:1
 
 Test moving servers handshake to state: CLIENT_KEY_EXCHANGE
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:1
 
 Test moving servers handshake to state: CERTIFICATE_VERIFY
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_CERTIFICATE_VERIFY:1
 
 Test moving servers handshake to state: CLIENT_CHANGE_CIPHER_SPEC
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:1
 
 Test moving servers handshake to state: CLIENT_FINISHED
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_CLIENT_FINISHED:1
 
 Test moving servers handshake to state: SERVER_CHANGE_CIPHER_SPEC
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:1
 
 Test moving servers handshake to state: SERVER_FINISHED
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_SERVER_FINISHED:1
 
 Test moving servers handshake to state: FLUSH_BUFFERS
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_FLUSH_BUFFERS:1
 
 Test moving servers handshake to state: HANDSHAKE_WRAPUP
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_HANDSHAKE_WRAPUP:1
 
 Test moving servers handshake to state: HANDSHAKE_OVER
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_HANDSHAKE_OVER:1
 
 Negative test moving clients ssl to state: VERIFY_REQUEST_SENT
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT:0
 
 Negative test moving servers ssl to state: NEW_SESSION_TICKET
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET:0
 
 Handshake, tls1_2
@@ -272,9 +308,11 @@
 handshake_serialization
 
 DTLS Handshake fragmentation, MFL=512
+depends_on:MBEDTLS_SSL_PROTO_DTLS
 handshake_fragmentation:MBEDTLS_SSL_MAX_FRAG_LEN_512:1:1
 
 DTLS Handshake fragmentation, MFL=1024
+depends_on:MBEDTLS_SSL_PROTO_DTLS
 handshake_fragmentation:MBEDTLS_SSL_MAX_FRAG_LEN_1024:0:1
 
 Handshake min/max version check, all -> 1.2
@@ -619,15 +657,19 @@
 ssl_set_hostname_twice:"server0":"server1"
 
 SSL session serialization: Wrong major version
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 ssl_session_serialize_version_check:1:0:0:0
 
 SSL session serialization: Wrong minor version
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 ssl_session_serialize_version_check:0:1:0:0
 
 SSL session serialization: Wrong patch version
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 ssl_session_serialize_version_check:0:0:1:0
 
 SSL session serialization: Wrong config
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 ssl_session_serialize_version_check:0:0:0:1
 
 Record crypt, AES-128-CBC, 1.2, SHA-384
@@ -4350,6 +4392,56 @@
 # Handshake secret to Master Secret
 ssl_tls13_key_evolution:MBEDTLS_MD_SHA256:"fb9fc80689b3a5d02c33243bf69a1b1b20705588a794304a6e7120155edf149a":"":"7f2882bb9b9a46265941653e9c2f19067118151e21d12e57a7b6aca1f8150c8d"
 
+SSL TLS 1.3 Key schedule: HKDF RFC5869 Test Vector #1 Expand
+depends_on:PSA_WANT_ALG_SHA_256
+psa_hkdf_expand:PSA_ALG_HMAC(PSA_ALG_SHA_256):"f0f1f2f3f4f5f6f7f8f9":"077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5":"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"
+
+SSL TLS 1.3 Key schedule: HKDF RFC5869 Test Vector #2 Expand
+depends_on:PSA_WANT_ALG_SHA_256
+psa_hkdf_expand:PSA_ALG_HMAC(PSA_ALG_SHA_256):"b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244":"b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87"
+
+SSL TLS 1.3 Key schedule: HKDF RFC5869 Test Vector #3 Expand
+depends_on:PSA_WANT_ALG_SHA_256
+psa_hkdf_expand:PSA_ALG_HMAC(PSA_ALG_SHA_256):"":"19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04":"8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8"
+
+SSL TLS 1.3 Key schedule: HKDF RFC5869 Test Vector #4 Expand
+depends_on:PSA_WANT_ALG_SHA_1
+psa_hkdf_expand:PSA_ALG_HMAC(PSA_ALG_SHA_1):"f0f1f2f3f4f5f6f7f8f9":"9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243":"085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896"
+
+SSL TLS 1.3 Key schedule: HKDF RFC5869 Test Vector #5 Expand
+depends_on:PSA_WANT_ALG_SHA_1
+psa_hkdf_expand:PSA_ALG_HMAC(PSA_ALG_SHA_1):"b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"8adae09a2a307059478d309b26c4115a224cfaf6":"0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4"
+
+SSL TLS 1.3 Key schedule: HKDF RFC5869 Test Vector #6 Expand
+depends_on:PSA_WANT_ALG_SHA_1
+psa_hkdf_expand:PSA_ALG_HMAC(PSA_ALG_SHA_1):"":"da8c8a73c7fa77288ec6f5e7c297786aa0d32d01":"0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918"
+
+SSL TLS 1.3 Key schedule: HKDF RFC5869 Test Vector #7 Expand
+depends_on:PSA_WANT_ALG_SHA_1
+psa_hkdf_expand:PSA_ALG_HMAC(PSA_ALG_SHA_1):"":"2adccada18779e7c2077ad2eb19d3f3e731385dd":"2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48"
+
+SSL TLS 1.3 Key schedule: HKDF expand fails with NULL okm
+depends_on:PSA_WANT_ALG_SHA_256
+psa_hkdf_expand_ret:PSA_ALG_HMAC(PSA_ALG_SHA_256):32:0:PSA_ERROR_INVALID_ARGUMENT
+
+SSL TLS 1.3 Key schedule: HKDF expand fails with invalid alg
+psa_hkdf_expand_ret:0:32:32:PSA_ERROR_INVALID_ARGUMENT
+
+SSL TLS 1.3 Key schedule: HKDF expand fails with incompatible alg
+depends_on:PSA_WANT_ALG_SHA_256
+psa_hkdf_expand_ret:PSA_ALG_SHA_256:32:32:PSA_ERROR_INVALID_ARGUMENT
+
+SSL TLS 1.3 Key schedule: HKDF expand fails with prk_len < hash_len
+depends_on:PSA_WANT_ALG_SHA_256
+psa_hkdf_expand_ret:PSA_ALG_HMAC(PSA_ALG_SHA_256):16:32:PSA_ERROR_INVALID_ARGUMENT
+
+SSL TLS 1.3 Key schedule: HKDF expand fails with okm_len / hash_len > 255
+psa_hkdf_expand_ret:PSA_ALG_HMAC(PSA_ALG_SHA_256):32:8192:PSA_ERROR_INVALID_ARGUMENT
+
+SSL TLS 1.3 Key schedule: HKDF expand fails with key import
+depends_on:PSA_WANT_ALG_SHA_256
+psa_hkdf_expand_ret:PSA_ALG_HMAC(PSA_ALG_SHA_256):32:32:PSA_ERROR_INSUFFICIENT_MEMORY
+
 SSL TLS 1.3 Key schedule: HKDF Expand Label #1
 # Vector from TLS 1.3 Byte by Byte (https://tls13.ulfheim.net/)
 # Server handshake traffic secret -> Server traffic key
@@ -4559,95 +4651,99 @@
 ssl_tls_prf:MBEDTLS_SSL_TLS_PRF_SHA256:"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"test tls_prf label":"7f9998393198a02c8d731ccc2ef90b2c":MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE
 
 Session serialization, save-load: no ticket, no cert
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 ssl_serialize_session_save_load:0:""
 
 Session serialization, save-load: small ticket, no cert
-depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C
+depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_PROTO_TLS1_2
 ssl_serialize_session_save_load:42:""
 
 Session serialization, save-load: large ticket, no cert
-depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C
+depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_PROTO_TLS1_2
 ssl_serialize_session_save_load:1023:""
 
 Session serialization, save-load: no ticket, cert
-depends_on:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
+depends_on:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO:MBEDTLS_SSL_PROTO_TLS1_2
 ssl_serialize_session_save_load:0:"data_files/server5.crt"
 
 Session serialization, save-load: small ticket, cert
-depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
+depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO:MBEDTLS_SSL_PROTO_TLS1_2
 ssl_serialize_session_save_load:42:"data_files/server5.crt"
 
 Session serialization, save-load: large ticket, cert
-depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
+depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO:MBEDTLS_SSL_PROTO_TLS1_2
 ssl_serialize_session_save_load:1023:"data_files/server5.crt"
 
 Session serialization, load-save: no ticket, no cert
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 ssl_serialize_session_load_save:0:""
 
 Session serialization, load-save: small ticket, no cert
-depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C
+depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_PROTO_TLS1_2
 ssl_serialize_session_load_save:42:""
 
 Session serialization, load-save: large ticket, no cert
-depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C
+depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_PROTO_TLS1_2
 ssl_serialize_session_load_save:1023:""
 
 Session serialization, load-save: no ticket, cert
-depends_on:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
+depends_on:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO:MBEDTLS_SSL_PROTO_TLS1_2
 ssl_serialize_session_load_save:0:"data_files/server5.crt"
 
 Session serialization, load-save: small ticket, cert
-depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
 ssl_serialize_session_load_save:42:"data_files/server5.crt"
 
 Session serialization, load-save: large ticket, cert
-depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
 ssl_serialize_session_load_save:1023:"data_files/server5.crt"
 
 Session serialization, save buffer size: no ticket, no cert
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 ssl_serialize_session_save_buf_size:0:""
 
 Session serialization, save buffer size: small ticket, no cert
-depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C
+depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_PROTO_TLS1_2
 ssl_serialize_session_save_buf_size:42:""
 
 Session serialization, save buffer size: large ticket, no cert
-depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C
+depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_PROTO_TLS1_2
 ssl_serialize_session_save_buf_size:1023:""
 
 Session serialization, save buffer size: no ticket, cert
-depends_on:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
+depends_on:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO:MBEDTLS_SSL_PROTO_TLS1_2
 ssl_serialize_session_save_buf_size:0:"data_files/server5.crt"
 
 Session serialization, save buffer size: small ticket, cert
-depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
 ssl_serialize_session_save_buf_size:42:"data_files/server5.crt"
 
 Session serialization, save buffer size: large ticket, cert
-depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
 ssl_serialize_session_save_buf_size:1023:"data_files/server5.crt"
 
 Session serialization, load buffer size: no ticket, no cert
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
 ssl_serialize_session_load_buf_size:0:""
 
 Session serialization, load buffer size: small ticket, no cert
-depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C
 ssl_serialize_session_load_buf_size:42:""
 
 Session serialization, load buffer size: large ticket, no cert
-depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C
 ssl_serialize_session_load_buf_size:1023:""
 
 Session serialization, load buffer size: no ticket, cert
-depends_on:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
 ssl_serialize_session_load_buf_size:0:"data_files/server5.crt"
 
 Session serialization, load buffer size: small ticket, cert
-depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
 ssl_serialize_session_load_buf_size:42:"data_files/server5.crt"
 
 Session serialization, load buffer size: large ticket, cert
-depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
 ssl_serialize_session_load_buf_size:1023:"data_files/server5.crt"
 
 Constant-flow HMAC: MD5
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index 53f541f..cb66f3a 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -6,6 +6,7 @@
 #include <mbedtls/timing.h>
 #include <mbedtls/debug.h>
 #include <ssl_tls13_keys.h>
+#include <ssl_tls13_invasive.h>
 #include "test/certs.h"
 
 #include <psa/crypto.h>
@@ -1186,6 +1187,7 @@
 #define SSL_CID_LEN_MIN MBEDTLS_SSL_CID_OUT_LEN_MAX
 #endif
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 static int psa_cipher_encrypt_helper( mbedtls_ssl_transform *transform,
                     const unsigned char *iv, size_t iv_len,
                     const unsigned char *input, size_t ilen,
@@ -1226,6 +1228,7 @@
                             iv, iv_len, input, ilen, output, olen );
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
 static int build_transforms( mbedtls_ssl_transform *t_in,
                              mbedtls_ssl_transform *t_out,
@@ -3803,6 +3806,108 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_SSL_PROTO_TLS1_3 */
+void psa_hkdf_expand( int alg, char *hex_info_string,
+                      char *hex_prk_string, char *hex_okm_string )
+{
+    enum { OKM_LEN  = 1024 };
+    unsigned char *info = NULL;
+    unsigned char *prk = NULL;
+    unsigned char *okm = NULL;
+    unsigned char *output_okm = NULL;
+    size_t info_len, prk_len, okm_len;
+
+    PSA_INIT( );
+
+    ASSERT_ALLOC( output_okm, OKM_LEN );
+
+    prk = mbedtls_test_unhexify_alloc( hex_prk_string, &prk_len );
+    info = mbedtls_test_unhexify_alloc( hex_info_string, &info_len );
+    okm = mbedtls_test_unhexify_alloc( hex_okm_string, &okm_len );
+    TEST_ASSERT( prk_len == PSA_HASH_LENGTH( alg ) );
+    TEST_ASSERT( okm_len < OKM_LEN );
+
+    PSA_ASSERT( mbedtls_psa_hkdf_expand( alg, prk, prk_len, info, info_len,
+                                         output_okm, OKM_LEN ) );
+
+    ASSERT_COMPARE( output_okm, okm_len, okm, okm_len );
+
+exit:
+    mbedtls_free( info );
+    mbedtls_free( prk );
+    mbedtls_free( okm );
+    mbedtls_free( output_okm );
+
+    PSA_DONE( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_SSL_PROTO_TLS1_3 */
+void psa_hkdf_expand_ret( int alg, int prk_len, int okm_len, int ret )
+{
+    int output_ret;
+    unsigned char *info = NULL;
+    unsigned char *prk = NULL;
+    unsigned char *okm = NULL;
+    size_t info_len;
+    size_t i;
+    mbedtls_svc_key_id_t *keys = NULL;
+
+    PSA_INIT( );
+
+    info_len = 0;
+
+    if( prk_len > 0 )
+        ASSERT_ALLOC( prk, prk_len );
+
+    if( okm_len > 0 )
+        ASSERT_ALLOC( okm, okm_len );
+
+    if( ret == PSA_ERROR_INSUFFICIENT_MEMORY )
+    {
+        psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+        /* Reserve all key slot to make the key import fail. */
+        psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_MESSAGE );
+        psa_set_key_algorithm( &attributes, alg );
+        psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC );
+
+        ASSERT_ALLOC( keys, MBEDTLS_PSA_KEY_SLOT_COUNT );
+
+        for( i = 0; i < MBEDTLS_PSA_KEY_SLOT_COUNT; i++ )
+        {
+            /* Do not use the 0 value because it will be passed to
+               mbedtls_psa_hkdf_expand */
+            prk[0] = i + 1;
+            keys[i] = MBEDTLS_SVC_KEY_ID_INIT;
+            psa_import_key( &attributes, prk, prk_len, &keys[i] );
+        }
+
+        /* reset prk buffer */
+        prk[0] = 0;
+    }
+
+    output_ret = mbedtls_psa_hkdf_expand( alg, prk, prk_len,
+                                          info, info_len,
+                                          okm, okm_len );
+    TEST_ASSERT( output_ret == ret );
+
+exit:
+    mbedtls_free( prk );
+    mbedtls_free( okm );
+
+   if( ret == PSA_ERROR_INSUFFICIENT_MEMORY )
+   {
+        for( i = 0; i < MBEDTLS_PSA_KEY_SLOT_COUNT; i++ )
+            psa_destroy_key( keys[i] );
+
+        mbedtls_free( keys );
+   }
+
+    PSA_DONE( );
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3 */
 void ssl_tls13_hkdf_expand_label( int hash_alg,
                                   data_t *secret,
@@ -4198,7 +4303,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_2 */
 void ssl_tls_prf( int type, data_t * secret, data_t * random,
                   char *label, data_t *result_str, int exp_ret )
 {
@@ -5036,9 +5141,13 @@
 
     mbedtls_ssl_config conf;
     mbedtls_ssl_config_init( &conf );
-
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
     mbedtls_ssl_conf_max_version( &conf, 3, 3 );
     mbedtls_ssl_conf_min_version( &conf, 3, 3 );
+#else
+    mbedtls_ssl_conf_max_version( &conf, 3, 4 );
+    mbedtls_ssl_conf_min_version( &conf, 3, 4 );
+#endif
     mbedtls_ssl_conf_curves( &conf, curve_list );
 
     mbedtls_ssl_context ssl;