Merge pull request #6938 from aditya-deshpande-arm/check-names-exclusions

check_names.py: Compare identifiers in excluded files against symbols parsed by nm
diff --git a/ChangeLog.d/crypto_config_ccm_star.txt b/ChangeLog.d/crypto_config_ccm_star.txt
new file mode 100644
index 0000000..947014a
--- /dev/null
+++ b/ChangeLog.d/crypto_config_ccm_star.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * List PSA_WANT_ALG_CCM_STAR_NO_TAG in psa/crypto_config.h so that it can
+     be toggled with config.py.
diff --git a/ChangeLog.d/fix-rsaalt-test-guards.txt b/ChangeLog.d/fix-rsaalt-test-guards.txt
new file mode 100644
index 0000000..f4f39c9
--- /dev/null
+++ b/ChangeLog.d/fix-rsaalt-test-guards.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Fix compile error where MBEDTLS_RSA_C and MBEDTLS_X509_CRT_WRITE_C are
+     defined, but MBEDTLS_PK_RSA_ALT_SUPPORT is not defined. Fixes #3174.
diff --git a/ChangeLog.d/psa_alg_tls12_ecjpake_to_pms-reject_ka.txt b/ChangeLog.d/psa_alg_tls12_ecjpake_to_pms-reject_ka.txt
new file mode 100644
index 0000000..cfea661
--- /dev/null
+++ b/ChangeLog.d/psa_alg_tls12_ecjpake_to_pms-reject_ka.txt
@@ -0,0 +1,4 @@
+Bugfix
+   * The key derivation algorithm PSA_ALG_TLS12_ECJPAKE_TO_PMS cannot be
+     used on a shared secret from a key agreement since its input must be
+     an ECC public key. Reject this properly.
diff --git a/docs/architecture/psa-migration/outcome-analysis.sh b/docs/architecture/psa-migration/outcome-analysis.sh
index 9084685..b26963b 100755
--- a/docs/architecture/psa-migration/outcome-analysis.sh
+++ b/docs/architecture/psa-migration/outcome-analysis.sh
@@ -1,42 +1,30 @@
 #!/bin/sh
 
-# This script runs tests in various revisions and configurations and analyses
-# the results in order to highlight any difference in the set of tests skipped
-# in the test suites of interest.
+# This script runs tests before and after a PR and analyzes the results in
+# order to highlight any difference in the set of tests skipped.
 #
-# It can be used to ensure the testing criteria mentioned in strategy.md,
+# It can be used to check the first testing criterion mentioned in strategy.md,
 # end of section "Supporting builds with drivers without the software
-# implementation" are met, namely:
+# implementation", namely: the sets of tests skipped in the default config and
+# the full config must be the same before and after the PR.
 #
-# - the sets of tests skipped in the default config and the full config must be
-#   the same before and after the PR that implements step 3;
-# - the set of tests skipped in the driver-only build is the same as in an
-#   equivalent software-based configuration, or the difference is small enough,
-#   justified, and a github issue is created to track it.
-#   This part is verified by tests/scripts/analyze_outcomes.py
+# USAGE:
+# - First, commit any uncommited changes. (Also, see warning below.)
+# - Then launch --> [SKIP_SSL_OPT=1] docs/architecture/psa-migration/outcome-analysis.sh
+#     - SKIP_SSL_OPT=1 can optionally be set to skip ssl-opt.sh tests
 #
 # WARNING: this script checks out a commit other than the head of the current
 # branch; it checks out the current branch again when running successfully,
 # but while the script is running, or if it terminates early in error, you
 # should be aware that you might be at a different commit than expected.
 #
-# NOTE: This is only an example/template script, you should make a copy and
-# edit it to suit your needs. The part that needs editing is at the top.
-#
-# Also, you can comment out parts that don't need to be re-done when
+# NOTE: you can comment out parts that don't need to be re-done when
 # re-running this script (for example "get numbers before this PR").
 
-# ----- BEGIN edit this -----
-# Space-separated list of test suites to ignore:
-# if SSS is in that list, test_suite_SSS and test_suite_SSS.* are ignored.
-IGNORE="md mdx shax" # accelerated
-IGNORE="$IGNORE entropy hmac_drbg random" # disabled (ext. RNG)
-IGNORE="$IGNORE psa_crypto_init" # needs internal RNG
-IGNORE="$IGNORE hkdf" # disabled in the all.sh component tested
-# ----- END edit this -----
-
 set -eu
 
+: ${SKIP_SSL_OPT:=0}
+
 cleanup() {
     make clean
     git checkout -- include/mbedtls/mbedtls_config.h include/psa/crypto_config.h
@@ -45,7 +33,14 @@
 record() {
     export MBEDTLS_TEST_OUTCOME_FILE="$PWD/outcome-$1.csv"
     rm -f $MBEDTLS_TEST_OUTCOME_FILE
+
     make check
+
+    if [ $SKIP_SSL_OPT -eq 0 ]; then
+        make -C programs ssl/ssl_server2 ssl/ssl_client2 \
+            test/udp_proxy test/query_compile_time_config
+        tests/ssl-opt.sh
+    fi
 }
 
 # save current HEAD
@@ -54,21 +49,26 @@
 # get the numbers before this PR for default and full
 cleanup
 git checkout $(git merge-base HEAD development)
+
 record "before-default"
 
 cleanup
+
 scripts/config.py full
 record "before-full"
 
 # get the numbers now for default and full
 cleanup
 git checkout $HEAD
+
 record "after-default"
 
 cleanup
+
 scripts/config.py full
 record "after-full"
 
+cleanup
 
 # analysis
 
@@ -77,15 +77,19 @@
     make generated_files >/dev/null
     data_files=$(cd tests/suites && echo *.data)
     for data in $data_files; do
-        suite=${data#test_suite_}
-        suite=${suite%.data}
-        suite_base=${suite%%.*}
-        case " $IGNORE " in
-            *" $suite_base "*) :;;
-            *) SUITES="$SUITES $suite";;
-        esac
+        suite=${data%.data}
+        SUITES="$SUITES $suite"
     done
     make neat
+
+    if [ $SKIP_SSL_OPT -eq 0 ]; then
+        SUITES="$SUITES ssl-opt"
+        extra_files=$(cd tests/opt-testcases && echo *.sh)
+        for extra in $extra_files; do
+            suite=${extra%.sh}
+            SUITES="$SUITES $suite"
+        done
+    fi
 }
 
 compare_suite () {
@@ -93,7 +97,7 @@
     new="outcome-$2.csv"
     suite="$3"
 
-    pattern_suite=";test_suite_$suite;"
+    pattern_suite=";$suite;"
     total=$(grep -c "$pattern_suite" "$ref")
     sed_cmd="s/^.*$pattern_suite\(.*\);SKIP.*/\1/p"
     sed -n "$sed_cmd" "$ref" > skipped-ref
@@ -101,8 +105,9 @@
     nb_ref=$(wc -l <skipped-ref)
     nb_new=$(wc -l <skipped-new)
 
-    printf "%36s: total %4d; skipped %4d -> %4d\n" \
-            $suite      $total       $nb_ref $nb_new
+    name=${suite#test_suite_}
+    printf "%40s: total %4d; skipped %4d -> %4d\n" \
+            $name       $total       $nb_ref $nb_new
     if diff skipped-ref skipped-new | grep '^> '; then
         ret=1
     else
diff --git a/docs/architecture/psa-migration/strategy.md b/docs/architecture/psa-migration/strategy.md
index 0ad5fa0..1542324 100644
--- a/docs/architecture/psa-migration/strategy.md
+++ b/docs/architecture/psa-migration/strategy.md
@@ -386,15 +386,16 @@
 result in more tests being skipped, which is easy to miss. Care must be
 taken to ensure this does not happen. The following criteria can be used:
 
-- the sets of tests skipped in the default config and the full config must be
-  the same before and after the PR that implements step 3;
-- the set of tests skipped in the driver-only build is the same as in an
-  equivalent software-based configuration, or the difference is small enough,
-  justified, and a github issue is created to track it.
-
-Note that the favourable case is when the number of tests skipped is 0 in the
-driver-only build. In other cases, analysis of the outcome files is needed,
-see the example script `outcome-analysis.sh` in the same directory.
+1. The sets of tests skipped in the default config and the full config must be
+  the same before and after the PR that implements step 3. This is tested
+manually for each PR that changes dependency declarations by using the script
+`outcome-analysis.sh` in the present directory.
+2. The set of tests skipped in the driver-only build is the same as in an
+  equivalent software-based configuration. This is tested automatically by the
+CI in the "Results analysis" stage, by running
+`tests/scripts/analyze_outcomes.py`. See the
+`analyze_driver_vs_reference_xxx` actions in the script and the comments above
+their declaration for how to do that locally.
 
 
 Migrating away from the legacy API
diff --git a/docs/getting_started.md b/docs/getting_started.md
index fdbf0e9..507afa1 100644
--- a/docs/getting_started.md
+++ b/docs/getting_started.md
@@ -1,8 +1,9 @@
-## Getting started with Mbed Crypto
+## Getting started with Mbed TLS
 
-### What is Mbed Crypto?
+### What is Mbed TLS?
 
-Mbed Crypto is an open source cryptographic library that supports a wide range of cryptographic operations, including:
+Mbed TLS is an open source cryptographic library that supports a wide range of
+cryptographic operations, including:
 * Key management
 * Hashing
 * Symmetric cryptography
@@ -11,20 +12,25 @@
 * Key generation and derivation
 * Authenticated encryption with associated data (AEAD)
 
-The Mbed Crypto library is a reference implementation of the cryptography interface of the Arm Platform Security Architecture (PSA). It is written in portable C.
+Mbed TLS provides a reference implementation of the cryptography interface of
+the Arm Platform Security Architecture (PSA). It is written in portable C.
 
-The Mbed Crypto library is distributed under the Apache License, version 2.0.
+Mbed TLS is distributed under the Apache License, version 2.0.
 
 #### Platform Security Architecture (PSA)
 
 Arm's Platform Security Architecture (PSA) is a holistic set of threat models,
-security analyses, hardware and firmware architecture specifications, and an open source firmware reference implementation. PSA provides a recipe, based on industry best practice, that enables you to design security into both hardware and firmware consistently. Part of the API provided by PSA is the cryptography interface, which provides access to a set of primitives.
+security analyses, hardware and firmware architecture specifications, and an
+open source firmware reference implementation. PSA provides a recipe, based on
+industry best practice, that enables you to design security into both hardware
+and firmware consistently. Part of the API provided by PSA is the cryptography
+interface, which provides access to a set of primitives.
 
-### Using Mbed Crypto
+### Using Mbed TLS
 
-* [Getting the Mbed Crypto library](#getting-the-mbed-crypto-library)
-* [Building the Mbed Crypto library](#building-the-mbed-crypto-library)
-* [Using the Mbed Crypto library](#using-the-mbed-crypto-library)
+* [Getting the Mbed TLS library](#getting-the-mbed-tls-library)
+* [Building the Mbed TLS library](#building-the-mbed-tls-library)
+* [Using the PSA Crypto API](#using-the-psa-crypto-api)
 * [Importing a key](#importing-a-key)
 * [Signing a message using RSA](#signing-a-message-using-RSA)
 * [Encrypting or decrypting using symmetric ciphers](#encrypting-or-decrypting-using-symmetric-ciphers)
@@ -33,37 +39,45 @@
 * [Generating a random value](#generating-a-random-value)
 * [Authenticating and encrypting or decrypting a message](#authenticating-and-encrypting-or-decrypting-a-message)
 * [Generating and exporting keys](#generating-and-exporting-keys)
-* [More about the Mbed Crypto library](#more-about-the-mbed-crypto-library)
+* [More about the PSA Crypto API](#more-about-the-psa-crypto-api)
 
-### Getting the Mbed Crypto library
+### Getting the Mbed TLS library
 
-Mbed Crypto releases are available in the [public GitHub repository](https://github.com/ARMmbed/mbed-crypto).
+Mbed TLS releases are available in the [public GitHub repository](https://github.com/Mbed-TLS/mbedtls).
 
-### Building the Mbed Crypto library
+### Building the Mbed TLS library
 
 **Prerequisites to building the library with the provided makefiles:**
 * GNU Make.
-* A C toolchain (compiler, linker, archiver).
-* Python 2 or Python 3 (either works) to generate the test code.
+* A C toolchain (compiler, linker, archiver) that supports C99.
+* Python 3.6 to generate the test code.
 * Perl to run the tests.
 
-If you have a C compiler such as GCC or Clang, just run `make` in the top-level directory to build the library, a set of unit tests and some sample programs.
+If you have a C compiler such as GCC or Clang, just run `make` in the top-level
+directory to build the library, a set of unit tests and some sample programs.
 
-To select a different compiler, set the `CC` variable to the name or path of the compiler and linker (default: `cc`) and set `AR` to a compatible archiver (default: `ar`); for example:
+To select a different compiler, set the `CC` variable to the name or path of the
+compiler and linker (default: `cc`) and set `AR` to a compatible archiver
+(default: `ar`); for example:
 ```
 make CC=arm-linux-gnueabi-gcc AR=arm-linux-gnueabi-ar
 ```
-The provided makefiles pass options to the compiler that assume a GCC-like command line syntax. To use a different compiler, you may need to pass different values for `CFLAGS`, `WARNINGS_CFLAGS` and `LDFLAGS`.
+The provided makefiles pass options to the compiler that assume a GCC-like
+command line syntax. To use a different compiler, you may need to pass different
+values for `CFLAGS`, `WARNINGS_CFLAGS` and `LDFLAGS`.
 
-To run the unit tests on the host machine, run `make test` from the top-level directory. If you are cross-compiling, copy the test executable from the `tests` directory to the target machine.
+To run the unit tests on the host machine, run `make test` from the top-level
+directory. If you are cross-compiling, copy the test executable from the `tests`
+directory to the target machine.
 
-### Using the Mbed Crypto library
+### Using the PSA Crypto API
 
-To use the Mbed Crypto APIs, call `psa_crypto_init()` before calling any other API. This initializes the library.
+If using PSA Crypto, you must initialize the library by calling
+`psa_crypto_init()` before any other PSA API.
 
 ### Importing a key
 
-To use a key for cryptography operations in Mbed Crypto, you need to first
+To use a key for cryptography operations in PSA, you need to first
 import it. The import operation returns the identifier of the key for use
 with other function calls.
 
@@ -114,7 +128,8 @@
 
 ### Signing a message using RSA
 
-Mbed Crypto supports encrypting, decrypting, signing and verifying messages using public key signature algorithms, such as RSA or ECDSA.
+The PSA Crypto API supports encrypting, decrypting, signing and verifying
+messages using public key signature algorithms, such as RSA or ECDSA.
 
 **Prerequisites to performing asymmetric signature operations:**
 * Initialize the library with a successful call to `psa_crypto_init()`.
@@ -184,21 +199,33 @@
 
 ### Using symmetric ciphers
 
-Mbed Crypto supports encrypting and decrypting messages using various symmetric cipher algorithms (both block and stream ciphers).
+The PSA Crypto API supports encrypting and decrypting messages using various
+symmetric cipher algorithms (both block and stream ciphers).
 
 **Prerequisites to working with the symmetric cipher API:**
 * Initialize the library with a successful call to `psa_crypto_init()`.
-* Have a symmetric key. This key's usage flags must include `PSA_KEY_USAGE_ENCRYPT` to allow encryption or `PSA_KEY_USAGE_DECRYPT` to allow decryption.
+* Have a symmetric key. This key's usage flags must include
+  `PSA_KEY_USAGE_ENCRYPT` to allow encryption or `PSA_KEY_USAGE_DECRYPT` to
+  allow decryption.
 
 **To encrypt a message with a symmetric cipher:**
-1. Allocate an operation (`psa_cipher_operation_t`) structure to pass to the cipher functions.
+1. Allocate an operation (`psa_cipher_operation_t`) structure to pass to the
+   cipher functions.
 1. Initialize the operation structure to zero or to `PSA_CIPHER_OPERATION_INIT`.
-1. Call `psa_cipher_encrypt_setup()` to specify the algorithm and the key to be used.
-1. Call either `psa_cipher_generate_iv()` or `psa_cipher_set_iv()` to generate or set the initialization vector (IV). We recommend calling `psa_cipher_generate_iv()`, unless you require a specific IV value.
-1. Call `psa_cipher_update()` with the message to encrypt. You may call this function multiple times, passing successive fragments of the message on successive calls.
-1. Call `psa_cipher_finish()` to end the operation and output the encrypted message.
+1. Call `psa_cipher_encrypt_setup()` to specify the algorithm and the key to be
+   used.
+1. Call either `psa_cipher_generate_iv()` or `psa_cipher_set_iv()` to generate
+   or set the initialization vector (IV). We recommend calling
+   `psa_cipher_generate_iv()`, unless you require a specific IV value.
+1. Call `psa_cipher_update()` with the message to encrypt. You may call this
+   function multiple times, passing successive fragments of the message on
+   successive calls.
+1. Call `psa_cipher_finish()` to end the operation and output the encrypted
+   message.
 
-This example shows how to encrypt data using an AES (Advanced Encryption Standard) key in CBC (Cipher Block Chaining) mode with no padding (assuming all prerequisites have been fulfilled):
+This example shows how to encrypt data using an AES (Advanced Encryption
+Standard) key in CBC (Cipher Block Chaining) mode with no padding (assuming all
+prerequisites have been fulfilled):
 ```c
 void encrypt_with_symmetric_ciphers(const uint8_t *key, size_t key_len)
 {
@@ -275,15 +302,20 @@
 ```
 
 **To decrypt a message with a symmetric cipher:**
-1. Allocate an operation (`psa_cipher_operation_t`) structure to pass to the cipher functions.
+1. Allocate an operation (`psa_cipher_operation_t`) structure to pass to the
+   cipher functions.
 1. Initialize the operation structure to zero or to `PSA_CIPHER_OPERATION_INIT`.
-1. Call `psa_cipher_decrypt_setup()` to specify the algorithm and the key to be used.
+1. Call `psa_cipher_decrypt_setup()` to specify the algorithm and the key to be
+   used.
 1. Call `psa_cipher_set_iv()` with the IV for the decryption.
-1. Call `psa_cipher_update()` with the message to encrypt. You may call this function multiple times, passing successive fragments of the message on successive calls.
-1. Call `psa_cipher_finish()` to end the operation and output the decrypted message.
+1. Call `psa_cipher_update()` with the message to encrypt. You may call this
+   function multiple times, passing successive fragments of the message on
+   successive calls.
+1. Call `psa_cipher_finish()` to end the operation and output the decrypted
+   message.
 
-This example shows how to decrypt encrypted data using an AES key in CBC mode with no padding
-(assuming all prerequisites have been fulfilled):
+This example shows how to decrypt encrypted data using an AES key in CBC mode
+with no padding (assuming all prerequisites have been fulfilled):
 ```c
 void decrypt_with_symmetric_ciphers(const uint8_t *key, size_t key_len)
 {
@@ -360,34 +392,49 @@
 
 #### Handling cipher operation contexts
 
-After you've initialized the operation structure with a successful call to `psa_cipher_encrypt_setup()` or `psa_cipher_decrypt_setup()`, you can terminate the operation at any time by calling `psa_cipher_abort()`.
+After you've initialized the operation structure with a successful call to
+`psa_cipher_encrypt_setup()` or `psa_cipher_decrypt_setup()`, you can terminate
+the operation at any time by calling `psa_cipher_abort()`.
 
-The call to `psa_cipher_abort()` frees any resources associated with the operation, except for the operation structure itself.
+The call to `psa_cipher_abort()` frees any resources associated with the
+operation, except for the operation structure itself.
 
-Mbed Crypto implicitly calls `psa_cipher_abort()` when:
-* A call to `psa_cipher_generate_iv()`, `psa_cipher_set_iv()` or `psa_cipher_update()` fails (returning any status other than `PSA_SUCCESS`).
+The PSA Crypto API implicitly calls `psa_cipher_abort()` when:
+* A call to `psa_cipher_generate_iv()`, `psa_cipher_set_iv()` or
+  `psa_cipher_update()` fails (returning any status other than `PSA_SUCCESS`).
 * A call to `psa_cipher_finish()` succeeds or fails.
 
-After an implicit or explicit call to `psa_cipher_abort()`, the operation structure is invalidated; in other words, you cannot reuse the operation structure for the same operation. You can, however, reuse the operation structure for a different operation by calling either `psa_cipher_encrypt_setup()` or `psa_cipher_decrypt_setup()` again.
+After an implicit or explicit call to `psa_cipher_abort()`, the operation
+structure is invalidated; in other words, you cannot reuse the operation
+structure for the same operation. You can, however, reuse the operation
+structure for a different operation by calling either
+`psa_cipher_encrypt_setup()` or `psa_cipher_decrypt_setup()` again.
 
-You must call `psa_cipher_abort()` at some point for any operation that is initialized successfully (by a successful call to `psa_cipher_encrypt_setup()` or `psa_cipher_decrypt_setup()`).
+You must call `psa_cipher_abort()` at some point for any operation that is
+initialized successfully (by a successful call to `psa_cipher_encrypt_setup()`
+or `psa_cipher_decrypt_setup()`).
 
-Making multiple sequential calls to `psa_cipher_abort()` on an operation that is terminated (either implicitly or explicitly) is safe and has no effect.
+Making multiple sequential calls to `psa_cipher_abort()` on an operation that
+is terminated (either implicitly or explicitly) is safe and has no effect.
 
 ### Hashing a message
 
-Mbed Crypto lets you compute and verify hashes using various hashing
+The PSA Crypto API lets you compute and verify hashes using various hashing
 algorithms.
 
 **Prerequisites to working with the hash APIs:**
 * Initialize the library with a successful call to `psa_crypto_init()`.
 
 **To calculate a hash:**
-1. Allocate an operation structure (`psa_hash_operation_t`) to pass to the hash functions.
+1. Allocate an operation structure (`psa_hash_operation_t`) to pass to the hash
+   functions.
 1. Initialize the operation structure to zero or to `PSA_HASH_OPERATION_INIT`.
 1. Call `psa_hash_setup()` to specify the hash algorithm.
-1. Call `psa_hash_update()` with the message to encrypt. You may call this function multiple times, passing successive fragments of the message on successive calls.
-1. Call `psa_hash_finish()` to calculate the hash, or `psa_hash_verify()` to compare the computed hash with an expected hash value.
+1. Call `psa_hash_update()` with the message to encrypt. You may call this
+   function multiple times, passing successive fragments of the message on
+   successive calls.
+1. Call `psa_hash_finish()` to calculate the hash, or `psa_hash_verify()` to
+   compare the computed hash with an expected hash value.
 
 This example shows how to calculate the SHA-256 hash of a message:
 ```c
@@ -482,33 +529,46 @@
     mbedtls_psa_crypto_free();
 ```
 
-The API provides the macro `PSA_HASH_LENGTH`, which returns the expected hash length (in bytes) for the specified algorithm.
+The API provides the macro `PSA_HASH_LENGTH`, which returns the expected hash
+length (in bytes) for the specified algorithm.
 
 #### Handling hash operation contexts
 
-After a successful call to `psa_hash_setup()`, you can terminate the operation at any time by calling `psa_hash_abort()`. The call to `psa_hash_abort()` frees any resources associated with the operation, except for the operation structure itself.
+After a successful call to `psa_hash_setup()`, you can terminate the operation
+at any time by calling `psa_hash_abort()`. The call to `psa_hash_abort()` frees
+any resources associated with the operation, except for the operation structure
+itself.
 
-Mbed Crypto implicitly calls `psa_hash_abort()` when:
-1. A call to `psa_hash_update()` fails (returning any status other than `PSA_SUCCESS`).
+The PSA Crypto API implicitly calls `psa_hash_abort()` when:
+1. A call to `psa_hash_update()` fails (returning any status other than
+   `PSA_SUCCESS`).
 1. A call to `psa_hash_finish()` succeeds or fails.
 1. A call to `psa_hash_verify()` succeeds or fails.
 
-After an implicit or explicit call to `psa_hash_abort()`, the operation structure is invalidated; in other words, you cannot reuse the operation structure for the same operation. You can, however, reuse the operation structure for a different operation by calling `psa_hash_setup()` again.
+After an implicit or explicit call to `psa_hash_abort()`, the operation
+structure is invalidated; in other words, you cannot reuse the operation
+structure for the same operation. You can, however, reuse the operation
+structure for a different operation by calling `psa_hash_setup()` again.
 
-You must call `psa_hash_abort()` at some point for any operation that is initialized successfully (by a successful call to `psa_hash_setup()`) .
+You must call `psa_hash_abort()` at some point for any operation that is
+initialized successfully (by a successful call to `psa_hash_setup()`) .
 
-Making multiple sequential calls to `psa_hash_abort()` on an operation that has already been terminated (either implicitly or explicitly) is safe and has no effect.
+Making multiple sequential calls to `psa_hash_abort()` on an operation that has
+already been terminated (either implicitly or explicitly) is safe and has no
+effect.
 
 ### Generating a random value
 
-Mbed Crypto can generate random data.
+The PSA Crypto API can generate random data.
 
 **Prerequisites to generating random data:**
 * Initialize the library with a successful call to `psa_crypto_init()`.
 
-<span class="notes">**Note:** To generate a random key, use `psa_generate_key()` instead of `psa_generate_random()`.</span>
+<span class="notes">**Note:** To generate a random key, use `psa_generate_key()`
+instead of `psa_generate_random()`.</span>
 
-This example shows how to generate ten bytes of random data by calling `psa_generate_random()`:
+This example shows how to generate ten bytes of random data by calling
+`psa_generate_random()`:
 ```C
     psa_status_t status;
     uint8_t random[10] = { 0 };
@@ -537,16 +597,19 @@
 
 ### Deriving a new key from an existing key
 
-Mbed Crypto provides a key derivation API that lets you derive new keys from
-existing ones. The key derivation API has functions to take inputs, including
-other keys and data, and functions to generate outputs, such as new keys or
-other data.
+The PSA Crypto API provides a key derivation API that lets you derive new keys
+from existing ones. The key derivation API has functions to take inputs,
+including other keys and data, and functions to generate outputs, such as
+new keys or other data.
 
 You must first initialize and set up a key derivation context,
-provided with a key and, optionally, other data. Then, use the key derivation context to either read derived data to a buffer or send derived data directly to a key slot.
+provided with a key and, optionally, other data. Then, use the key derivation
+context to either read derived data to a buffer or send derived data directly
+to a key slot.
 
-See the documentation for the particular algorithm (such as HKDF or the TLS1.2 PRF) for
-information about which inputs to pass when, and when you can obtain which outputs.
+See the documentation for the particular algorithm (such as HKDF or the
+TLS 1.2 PRF) for information about which inputs to pass when, and when you can
+obtain which outputs.
 
 **Prerequisites to working with the key derivation APIs:**
 * Initialize the library with a successful call to `psa_crypto_init()`.
@@ -563,11 +626,11 @@
 function, specifying the derivation algorithm `PSA_ALG_HKDF(PSA_ALG_SHA_256)`.
 1. Provide an optional salt with `psa_key_derivation_input_bytes()`.
 1. Provide info with `psa_key_derivation_input_bytes()`.
-1. Provide a secret with `psa_key_derivation_input_key()`, referencing a key that
-   can be used for key derivation.
+1. Provide a secret with `psa_key_derivation_input_key()`, referencing a key
+   that can be used for key derivation.
 1. Set the key attributes desired for the new derived key. We'll set
-   the `PSA_KEY_USAGE_ENCRYPT` usage flag and the `PSA_ALG_CTR` algorithm for this
-   example.
+   the `PSA_KEY_USAGE_ENCRYPT` usage flag and the `PSA_ALG_CTR` algorithm for
+   this example.
 1. Derive the key by calling `psa_key_derivation_output_key()`.
 1. Clean up the key derivation context.
 
@@ -675,11 +738,13 @@
 
 ### Authenticating and encrypting or decrypting a message
 
-Mbed Crypto provides a simple way to authenticate and encrypt with associated data (AEAD), supporting the `PSA_ALG_CCM` algorithm.
+The PSA Crypto API provides a simple way to authenticate and encrypt with
+associated data (AEAD), supporting the `PSA_ALG_CCM` algorithm.
 
 **Prerequisites to working with the AEAD cipher APIs:**
 * Initialize the library with a successful call to `psa_crypto_init()`.
-* The key attributes for the key used for derivation must have the `PSA_KEY_USAGE_ENCRYPT` or `PSA_KEY_USAGE_DECRYPT` usage flags.
+* The key attributes for the key used for derivation must have the
+  `PSA_KEY_USAGE_ENCRYPT` or `PSA_KEY_USAGE_DECRYPT` usage flags.
 
 This example shows how to authenticate and encrypt a message:
 ```C
@@ -829,7 +894,7 @@
 
 ### Generating and exporting keys
 
-Mbed Crypto provides a simple way to generate a key or key pair.
+The PSA Crypto API provides a simple way to generate a key or key pair.
 
 **Prerequisites to using key generation and export APIs:**
 * Initialize the library with a successful call to `psa_crypto_init()`.
@@ -837,7 +902,9 @@
 **To generate an ECDSA key:**
 1. Set the desired key attributes for key generation by calling
    `psa_set_key_algorithm()` with the chosen ECDSA algorithm (such as
-   `PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)`). You only want to export the public key, not the key pair (or private key); therefore, do not set `PSA_KEY_USAGE_EXPORT`.
+   `PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)`). You only want to export the
+   public key, not the key pair (or private key); therefore, do not
+   set `PSA_KEY_USAGE_EXPORT`.
 1. Generate a key by calling `psa_generate_key()`.
 1. Export the generated public key by calling `psa_export_public_key()`:
 ```C
@@ -891,4 +958,5 @@
 
 ### More about the PSA Crypto API
 
-For more information about the PSA Crypto API, please see the [PSA Cryptography API Specification](https://armmbed.github.io/mbed-crypto/html/index.html).
+For more information about the PSA Crypto API, please see the
+[PSA Cryptography API Specification](https://arm-software.github.io/psa-api/crypto/).
diff --git a/include/mbedtls/config_psa.h b/include/mbedtls/config_psa.h
index 09bc32c..48b2d32 100644
--- a/include/mbedtls/config_psa.h
+++ b/include/mbedtls/config_psa.h
@@ -843,6 +843,8 @@
 
 /* These features are always enabled. */
 #define PSA_WANT_KEY_TYPE_DERIVE 1
+#define PSA_WANT_KEY_TYPE_PASSWORD 1
+#define PSA_WANT_KEY_TYPE_PASSWORD_HASH 1
 #define PSA_WANT_KEY_TYPE_RAW_DATA 1
 
 #ifdef __cplusplus
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index 11c3139..2a2c039 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -48,8 +48,11 @@
  * Requires support for asm() in compiler.
  *
  * Used in:
+ *      library/aesni.h
  *      library/aria.c
  *      library/bn_mul.h
+ *      library/constant_time.c
+ *      library/padlock.h
  *
  * Required by:
  *      MBEDTLS_AESNI_C
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 661b23c..dbc37e8 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -809,8 +809,6 @@
 #endif
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
-typedef uint8_t mbedtls_ssl_tls13_ticket_flags;
-
 #define MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_RESUMPTION                          \
     MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK                        /* 1U << 0 */
 #define MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_EPHEMERAL_RESUMPTION                \
diff --git a/include/psa/crypto_config.h b/include/psa/crypto_config.h
index 5ab4fde..e68fac8 100644
--- a/include/psa/crypto_config.h
+++ b/include/psa/crypto_config.h
@@ -57,6 +57,7 @@
 #define PSA_WANT_ALG_CBC_NO_PADDING             1
 #define PSA_WANT_ALG_CBC_PKCS7                  1
 #define PSA_WANT_ALG_CCM                        1
+#define PSA_WANT_ALG_CCM_STAR_NO_TAG            1
 #define PSA_WANT_ALG_CMAC                       1
 #define PSA_WANT_ALG_CFB                        1
 #define PSA_WANT_ALG_CHACHA20_POLY1305          1
@@ -115,6 +116,8 @@
 #define PSA_WANT_ECC_SECP_R1_521                1
 
 #define PSA_WANT_KEY_TYPE_DERIVE                1
+#define PSA_WANT_KEY_TYPE_PASSWORD              1
+#define PSA_WANT_KEY_TYPE_PASSWORD_HASH         1
 #define PSA_WANT_KEY_TYPE_HMAC                  1
 #define PSA_WANT_KEY_TYPE_AES                   1
 #define PSA_WANT_KEY_TYPE_ARIA                  1
diff --git a/library/aesni.c b/library/aesni.c
index d4abb4d..f6b304d 100644
--- a/library/aesni.c
+++ b/library/aesni.c
@@ -37,12 +37,6 @@
 
 #include <string.h>
 
-/* *INDENT-OFF* */
-#ifndef asm
-#define asm __asm
-#endif
-/* *INDENT-ON* */
-
 #if defined(MBEDTLS_HAVE_X86_64)
 
 /*
diff --git a/library/alignment.h b/library/alignment.h
index bfc965e..aa09ff8 100644
--- a/library/alignment.h
+++ b/library/alignment.h
@@ -29,6 +29,23 @@
 
 #include "mbedtls/build_info.h"
 
+/*
+ * Define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS for architectures where unaligned memory
+ * accesses are known to be efficient.
+ *
+ * All functions defined here will behave correctly regardless, but might be less
+ * efficient when this is not defined.
+ */
+#if defined(__ARM_FEATURE_UNALIGNED) \
+    || defined(__i386__) || defined(__amd64__) || defined(__x86_64__)
+/*
+ * __ARM_FEATURE_UNALIGNED is defined where appropriate by armcc, gcc 7, clang 9
+ * (and later versions) for Arm v7 and later; all x86 platforms should have
+ * efficient unaligned access.
+ */
+#define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS
+#endif
+
 /**
  * Read the unsigned 16 bits integer from the given address, which need not
  * be aligned.
diff --git a/library/bignum_mod.c b/library/bignum_mod.c
index e701a68..e986865 100644
--- a/library/bignum_mod.c
+++ b/library/bignum_mod.c
@@ -35,15 +35,15 @@
 #include "constant_time_internal.h"
 
 int mbedtls_mpi_mod_residue_setup(mbedtls_mpi_mod_residue *r,
-                                  const mbedtls_mpi_mod_modulus *m,
+                                  const mbedtls_mpi_mod_modulus *N,
                                   mbedtls_mpi_uint *p,
                                   size_t p_limbs)
 {
-    if (p_limbs != m->limbs || !mbedtls_mpi_core_lt_ct(p, m->p, m->limbs)) {
+    if (p_limbs != N->limbs || !mbedtls_mpi_core_lt_ct(p, N->p, N->limbs)) {
         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
     }
 
-    r->limbs = m->limbs;
+    r->limbs = N->limbs;
     r->p = p;
 
     return 0;
@@ -59,45 +59,45 @@
     r->p = NULL;
 }
 
-void mbedtls_mpi_mod_modulus_init(mbedtls_mpi_mod_modulus *m)
+void mbedtls_mpi_mod_modulus_init(mbedtls_mpi_mod_modulus *N)
 {
-    if (m == NULL) {
+    if (N == NULL) {
         return;
     }
 
-    m->p = NULL;
-    m->limbs = 0;
-    m->bits = 0;
-    m->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
+    N->p = NULL;
+    N->limbs = 0;
+    N->bits = 0;
+    N->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
 }
 
-void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *m)
+void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *N)
 {
-    if (m == NULL) {
+    if (N == NULL) {
         return;
     }
 
-    switch (m->int_rep) {
+    switch (N->int_rep) {
         case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
-            if (m->rep.mont.rr != NULL) {
-                mbedtls_platform_zeroize((mbedtls_mpi_uint *) m->rep.mont.rr,
-                                         m->limbs * sizeof(mbedtls_mpi_uint));
-                mbedtls_free((mbedtls_mpi_uint *) m->rep.mont.rr);
-                m->rep.mont.rr = NULL;
+            if (N->rep.mont.rr != NULL) {
+                mbedtls_platform_zeroize((mbedtls_mpi_uint *) N->rep.mont.rr,
+                                         N->limbs * sizeof(mbedtls_mpi_uint));
+                mbedtls_free((mbedtls_mpi_uint *) N->rep.mont.rr);
+                N->rep.mont.rr = NULL;
             }
-            m->rep.mont.mm = 0;
+            N->rep.mont.mm = 0;
             break;
         case MBEDTLS_MPI_MOD_REP_OPT_RED:
-            mbedtls_free(m->rep.ored);
+            mbedtls_free(N->rep.ored);
             break;
         case MBEDTLS_MPI_MOD_REP_INVALID:
             break;
     }
 
-    m->p = NULL;
-    m->limbs = 0;
-    m->bits = 0;
-    m->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
+    N->p = NULL;
+    N->limbs = 0;
+    N->bits = 0;
+    N->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
 }
 
 static int set_mont_const_square(const mbedtls_mpi_uint **X,
@@ -136,26 +136,26 @@
     return ret;
 }
 
-int mbedtls_mpi_mod_modulus_setup(mbedtls_mpi_mod_modulus *m,
+int mbedtls_mpi_mod_modulus_setup(mbedtls_mpi_mod_modulus *N,
                                   const mbedtls_mpi_uint *p,
                                   size_t p_limbs,
                                   mbedtls_mpi_mod_rep_selector int_rep)
 {
     int ret = 0;
 
-    m->p = p;
-    m->limbs = p_limbs;
-    m->bits = mbedtls_mpi_core_bitlen(p, p_limbs);
+    N->p = p;
+    N->limbs = p_limbs;
+    N->bits = mbedtls_mpi_core_bitlen(p, p_limbs);
 
     switch (int_rep) {
         case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
-            m->int_rep = int_rep;
-            m->rep.mont.mm = mbedtls_mpi_core_montmul_init(m->p);
-            ret = set_mont_const_square(&m->rep.mont.rr, m->p, m->limbs);
+            N->int_rep = int_rep;
+            N->rep.mont.mm = mbedtls_mpi_core_montmul_init(N->p);
+            ret = set_mont_const_square(&N->rep.mont.rr, N->p, N->limbs);
             break;
         case MBEDTLS_MPI_MOD_REP_OPT_RED:
-            m->int_rep = int_rep;
-            m->rep.ored = NULL;
+            N->int_rep = int_rep;
+            N->rep.ored = NULL;
             break;
         default:
             ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
@@ -165,7 +165,7 @@
 exit:
 
     if (ret != 0) {
-        mbedtls_mpi_mod_modulus_free(m);
+        mbedtls_mpi_mod_modulus_free(N);
     }
 
     return ret;
@@ -349,7 +349,7 @@
 
 /* BEGIN MERGE SLOT 7 */
 int mbedtls_mpi_mod_read(mbedtls_mpi_mod_residue *r,
-                         const mbedtls_mpi_mod_modulus *m,
+                         const mbedtls_mpi_mod_modulus *N,
                          const unsigned char *buf,
                          size_t buflen,
                          mbedtls_mpi_mod_ext_rep ext_rep)
@@ -357,28 +357,28 @@
     int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
 
     /* Do our best to check if r and m have been set up */
-    if (r->limbs == 0 || m->limbs == 0) {
+    if (r->limbs == 0 || N->limbs == 0) {
         goto cleanup;
     }
-    if (r->limbs != m->limbs) {
+    if (r->limbs != N->limbs) {
         goto cleanup;
     }
 
-    ret = mbedtls_mpi_mod_raw_read(r->p, m, buf, buflen, ext_rep);
+    ret = mbedtls_mpi_mod_raw_read(r->p, N, buf, buflen, ext_rep);
     if (ret != 0) {
         goto cleanup;
     }
 
-    r->limbs = m->limbs;
+    r->limbs = N->limbs;
 
-    ret = mbedtls_mpi_mod_raw_canonical_to_modulus_rep(r->p, m);
+    ret = mbedtls_mpi_mod_raw_canonical_to_modulus_rep(r->p, N);
 
 cleanup:
     return ret;
 }
 
 int mbedtls_mpi_mod_write(const mbedtls_mpi_mod_residue *r,
-                          const mbedtls_mpi_mod_modulus *m,
+                          const mbedtls_mpi_mod_modulus *N,
                           unsigned char *buf,
                           size_t buflen,
                           mbedtls_mpi_mod_ext_rep ext_rep)
@@ -386,28 +386,28 @@
     int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
 
     /* Do our best to check if r and m have been set up */
-    if (r->limbs == 0 || m->limbs == 0) {
+    if (r->limbs == 0 || N->limbs == 0) {
         goto cleanup;
     }
-    if (r->limbs != m->limbs) {
+    if (r->limbs != N->limbs) {
         goto cleanup;
     }
 
-    if (m->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
-        ret = mbedtls_mpi_mod_raw_from_mont_rep(r->p, m);
+    if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
+        ret = mbedtls_mpi_mod_raw_from_mont_rep(r->p, N);
         if (ret != 0) {
             goto cleanup;
         }
     }
 
-    ret = mbedtls_mpi_mod_raw_write(r->p, m, buf, buflen, ext_rep);
+    ret = mbedtls_mpi_mod_raw_write(r->p, N, buf, buflen, ext_rep);
 
-    if (m->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
+    if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
         /* If this fails, the value of r is corrupted and we want to return
          * this error (as opposed to the error code from the write above) to
          * let the caller know. If it succeeds, we want to return the error
          * code from write above. */
-        int conv_ret = mbedtls_mpi_mod_raw_to_mont_rep(r->p, m);
+        int conv_ret = mbedtls_mpi_mod_raw_to_mont_rep(r->p, N);
         if (ret == 0) {
             ret = conv_ret;
         }
diff --git a/library/bignum_mod.h b/library/bignum_mod.h
index 0a22e71..d8c8b7d 100644
--- a/library/bignum_mod.h
+++ b/library/bignum_mod.h
@@ -140,34 +140,34 @@
 
 /** Setup a residue structure.
  *
- * The residue will be set up with the buffer \p p and modulus \p m.
+ * The residue will be set up with the buffer \p p and modulus \p N.
  *
  * The memory pointed to by \p p will be used by the resulting residue structure.
  * The value at the pointed-to memory will be the initial value of \p r and must
  * hold a value that is less than the modulus. This value will be used as-is
- * and interpreted according to the value of the `m->int_rep` field.
+ * and interpreted according to the value of the `N->int_rep` field.
  *
- * The modulus \p m will be the modulus associated with \p r. The residue \p r
- * should only be used in operations where the modulus is \p m.
+ * The modulus \p N will be the modulus associated with \p r. The residue \p r
+ * should only be used in operations where the modulus is \p N.
  *
  * \param[out] r    The address of the residue to setup.
- * \param[in] m     The address of the modulus related to \p r.
+ * \param[in] N     The address of the modulus related to \p r.
  * \param[in] p     The address of the limb array containing the value of \p r.
  *                  The memory pointed to by \p p will be used by \p r and must
  *                  not be modified in any way until after
  *                  mbedtls_mpi_mod_residue_release() is called. The data
  *                  pointed to by \p p must be less than the modulus (the value
- *                  pointed to by `m->p`) and already in the representation
- *                  indicated by `m->int_rep`.
+ *                  pointed to by `N->p`) and already in the representation
+ *                  indicated by `N->int_rep`.
  * \param p_limbs   The number of limbs of \p p. Must be the same as the number
- *                  of limbs in the modulus \p m.
+ *                  of limbs in the modulus \p N.
  *
  * \return      \c 0 if successful.
  * \return      #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p p_limbs is less than the
- *              limbs in \p m or if \p p is not less than \p m.
+ *              limbs in \p N or if \p p is not less than \p N.
  */
 int mbedtls_mpi_mod_residue_setup(mbedtls_mpi_mod_residue *r,
-                                  const mbedtls_mpi_mod_modulus *m,
+                                  const mbedtls_mpi_mod_modulus *N,
                                   mbedtls_mpi_uint *p,
                                   size_t p_limbs);
 
@@ -185,25 +185,25 @@
 
 /** Initialize a modulus structure.
  *
- * \param[out] m     The address of the modulus structure to initialize.
+ * \param[out] N     The address of the modulus structure to initialize.
  */
-void mbedtls_mpi_mod_modulus_init(mbedtls_mpi_mod_modulus *m);
+void mbedtls_mpi_mod_modulus_init(mbedtls_mpi_mod_modulus *N);
 
 /** Setup a modulus structure.
  *
- * \param[out] m    The address of the modulus structure to populate.
- * \param[in] p     The address of the limb array storing the value of \p m.
- *                  The memory pointed to by \p p will be used by \p m and must
+ * \param[out] N    The address of the modulus structure to populate.
+ * \param[in] p     The address of the limb array storing the value of \p N.
+ *                  The memory pointed to by \p p will be used by \p N and must
  *                  not be modified in any way until after
  *                  mbedtls_mpi_mod_modulus_free() is called.
  * \param p_limbs   The number of limbs of \p p.
  * \param int_rep   The internal representation to be used for residues
- *                  associated with \p m (see #mbedtls_mpi_mod_rep_selector).
+ *                  associated with \p N (see #mbedtls_mpi_mod_rep_selector).
  *
  * \return      \c 0 if successful.
  * \return      #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p int_rep is invalid.
  */
-int mbedtls_mpi_mod_modulus_setup(mbedtls_mpi_mod_modulus *m,
+int mbedtls_mpi_mod_modulus_setup(mbedtls_mpi_mod_modulus *N,
                                   const mbedtls_mpi_uint *p,
                                   size_t p_limbs,
                                   mbedtls_mpi_mod_rep_selector int_rep);
@@ -216,9 +216,9 @@
  *          mbedtls_mpi_mod_modulus_setup() only removes the reference to it,
  *          making it safe to free or to use it again.
  *
- * \param[in,out] m     The address of the modulus structure to free.
+ * \param[in,out] N     The address of the modulus structure to free.
  */
-void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *m);
+void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *N);
 
 /* BEGIN MERGE SLOT 1 */
 
@@ -401,16 +401,16 @@
 /** Read a residue from a byte buffer.
  *
  * The residue will be automatically converted to the internal representation
- * based on the value of the `m->int_rep` field.
+ * based on the value of the `N->int_rep` field.
  *
- * The modulus \p m will be the modulus associated with \p r. The residue \p r
- * should only be used in operations where the modulus is \p m or a modulus
- * equivalent to \p m (in the sense that all their fields or memory pointed by
+ * The modulus \p N will be the modulus associated with \p r. The residue \p r
+ * should only be used in operations where the modulus is \p N or a modulus
+ * equivalent to \p N (in the sense that all their fields or memory pointed by
  * their fields hold the same value).
  *
  * \param[out] r    The address of the residue. It must have exactly the same
- *                  number of limbs as the modulus \p m.
- * \param[in] m     The address of the modulus.
+ *                  number of limbs as the modulus \p N.
+ * \param[in] N     The address of the modulus.
  * \param[in] buf   The input buffer to import from.
  * \param buflen    The length in bytes of \p buf.
  * \param ext_rep   The endianness of the number in the input buffer.
@@ -419,32 +419,32 @@
  * \return       #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p r isn't
  *               large enough to hold the value in \p buf.
  * \return       #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p ext_rep
- *               is invalid or the value in the buffer is not less than \p m.
+ *               is invalid or the value in the buffer is not less than \p N.
  */
 int mbedtls_mpi_mod_read(mbedtls_mpi_mod_residue *r,
-                         const mbedtls_mpi_mod_modulus *m,
+                         const mbedtls_mpi_mod_modulus *N,
                          const unsigned char *buf,
                          size_t buflen,
                          mbedtls_mpi_mod_ext_rep ext_rep);
 
 /** Write a residue into a byte buffer.
  *
- * The modulus \p m must be the modulus associated with \p r (see
+ * The modulus \p N must be the modulus associated with \p r (see
  * mbedtls_mpi_mod_residue_setup() and mbedtls_mpi_mod_read()).
  *
  * The residue will be automatically converted from the internal representation
- * based on the value of `m->int_rep` field.
+ * based on the value of `N->int_rep` field.
  *
- * \warning     If the buffer is smaller than `m->bits`, the number of
+ * \warning     If the buffer is smaller than `N->bits`, the number of
  *              leading zeroes is leaked through timing. If \p r is
  *              secret, the caller must ensure that \p buflen is at least
- *              (`m->bits`+7)/8.
+ *              (`N->bits`+7)/8.
  *
  * \param[in] r     The address of the residue. It must have the same number of
- *                  limbs as the modulus \p m. (\p r is an input parameter, but
+ *                  limbs as the modulus \p N. (\p r is an input parameter, but
  *                  its value will be modified during execution and restored
  *                  before the function returns.)
- * \param[in] m     The address of the modulus associated with \r.
+ * \param[in] N     The address of the modulus associated with \r.
  * \param[out] buf  The output buffer to export to.
  * \param buflen    The length in bytes of \p buf.
  * \param ext_rep   The endianness in which the number should be written into
@@ -460,7 +460,7 @@
  *               MBEDTLS_MPI_MOD_REP_MONTGOMERY.
  */
 int mbedtls_mpi_mod_write(const mbedtls_mpi_mod_residue *r,
-                          const mbedtls_mpi_mod_modulus *m,
+                          const mbedtls_mpi_mod_modulus *N,
                           unsigned char *buf,
                           size_t buflen,
                           mbedtls_mpi_mod_ext_rep ext_rep);
diff --git a/library/bignum_mod_raw.c b/library/bignum_mod_raw.c
index aa2bd46..826dd07 100644
--- a/library/bignum_mod_raw.c
+++ b/library/bignum_mod_raw.c
@@ -50,7 +50,7 @@
 }
 
 int mbedtls_mpi_mod_raw_read(mbedtls_mpi_uint *X,
-                             const mbedtls_mpi_mod_modulus *m,
+                             const mbedtls_mpi_mod_modulus *N,
                              const unsigned char *input,
                              size_t input_length,
                              mbedtls_mpi_mod_ext_rep ext_rep)
@@ -59,11 +59,11 @@
 
     switch (ext_rep) {
         case MBEDTLS_MPI_MOD_EXT_REP_LE:
-            ret = mbedtls_mpi_core_read_le(X, m->limbs,
+            ret = mbedtls_mpi_core_read_le(X, N->limbs,
                                            input, input_length);
             break;
         case MBEDTLS_MPI_MOD_EXT_REP_BE:
-            ret = mbedtls_mpi_core_read_be(X, m->limbs,
+            ret = mbedtls_mpi_core_read_be(X, N->limbs,
                                            input, input_length);
             break;
         default:
@@ -74,7 +74,7 @@
         goto cleanup;
     }
 
-    if (!mbedtls_mpi_core_lt_ct(X, m->p, m->limbs)) {
+    if (!mbedtls_mpi_core_lt_ct(X, N->p, N->limbs)) {
         ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
         goto cleanup;
     }
@@ -85,17 +85,17 @@
 }
 
 int mbedtls_mpi_mod_raw_write(const mbedtls_mpi_uint *A,
-                              const mbedtls_mpi_mod_modulus *m,
+                              const mbedtls_mpi_mod_modulus *N,
                               unsigned char *output,
                               size_t output_length,
                               mbedtls_mpi_mod_ext_rep ext_rep)
 {
     switch (ext_rep) {
         case MBEDTLS_MPI_MOD_EXT_REP_LE:
-            return mbedtls_mpi_core_write_le(A, m->limbs,
+            return mbedtls_mpi_core_write_le(A, N->limbs,
                                              output, output_length);
         case MBEDTLS_MPI_MOD_EXT_REP_BE:
-            return mbedtls_mpi_core_write_be(A, m->limbs,
+            return mbedtls_mpi_core_write_be(A, N->limbs,
                                              output, output_length);
         default:
             return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
@@ -229,17 +229,17 @@
 
 /* BEGIN MERGE SLOT 7 */
 int mbedtls_mpi_mod_raw_to_mont_rep(mbedtls_mpi_uint *X,
-                                    const mbedtls_mpi_mod_modulus *m)
+                                    const mbedtls_mpi_mod_modulus *N)
 {
     mbedtls_mpi_uint *T;
-    const size_t t_limbs = mbedtls_mpi_core_montmul_working_limbs(m->limbs);
+    const size_t t_limbs = mbedtls_mpi_core_montmul_working_limbs(N->limbs);
 
     if ((T = (mbedtls_mpi_uint *) mbedtls_calloc(t_limbs, ciL)) == NULL) {
         return MBEDTLS_ERR_MPI_ALLOC_FAILED;
     }
 
-    mbedtls_mpi_core_to_mont_rep(X, X, m->p, m->limbs,
-                                 m->rep.mont.mm, m->rep.mont.rr, T);
+    mbedtls_mpi_core_to_mont_rep(X, X, N->p, N->limbs,
+                                 N->rep.mont.mm, N->rep.mont.rr, T);
 
     mbedtls_platform_zeroize(T, t_limbs * ciL);
     mbedtls_free(T);
@@ -247,16 +247,16 @@
 }
 
 int mbedtls_mpi_mod_raw_from_mont_rep(mbedtls_mpi_uint *X,
-                                      const mbedtls_mpi_mod_modulus *m)
+                                      const mbedtls_mpi_mod_modulus *N)
 {
-    const size_t t_limbs = mbedtls_mpi_core_montmul_working_limbs(m->limbs);
+    const size_t t_limbs = mbedtls_mpi_core_montmul_working_limbs(N->limbs);
     mbedtls_mpi_uint *T;
 
     if ((T = (mbedtls_mpi_uint *) mbedtls_calloc(t_limbs, ciL)) == NULL) {
         return MBEDTLS_ERR_MPI_ALLOC_FAILED;
     }
 
-    mbedtls_mpi_core_from_mont_rep(X, X, m->p, m->limbs, m->rep.mont.mm, T);
+    mbedtls_mpi_core_from_mont_rep(X, X, N->p, N->limbs, N->rep.mont.mm, T);
 
     mbedtls_platform_zeroize(T, t_limbs * ciL);
     mbedtls_free(T);
@@ -265,14 +265,14 @@
 
 void mbedtls_mpi_mod_raw_neg(mbedtls_mpi_uint *X,
                              const mbedtls_mpi_uint *A,
-                             const mbedtls_mpi_mod_modulus *m)
+                             const mbedtls_mpi_mod_modulus *N)
 {
-    mbedtls_mpi_core_sub(X, m->p, A, m->limbs);
+    mbedtls_mpi_core_sub(X, N->p, A, N->limbs);
 
     /* If A=0 initially, then X=N now. Detect this by
      * subtracting N and catching the carry. */
-    mbedtls_mpi_uint borrow = mbedtls_mpi_core_sub(X, X, m->p, m->limbs);
-    (void) mbedtls_mpi_core_add_if(X, m->p, m->limbs, (unsigned) borrow);
+    mbedtls_mpi_uint borrow = mbedtls_mpi_core_sub(X, X, N->p, N->limbs);
+    (void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) borrow);
 }
 /* END MERGE SLOT 7 */
 
diff --git a/library/bignum_mod_raw.h b/library/bignum_mod_raw.h
index da8db6f..a32500f 100644
--- a/library/bignum_mod_raw.h
+++ b/library/bignum_mod_raw.h
@@ -145,10 +145,10 @@
  * The MPI needs to have enough limbs to store the full value (including any
  * most significant zero bytes in the input).
  *
- * \param[out] X        The address of the MPI. The size is determined by \p m.
+ * \param[out] X        The address of the MPI. The size is determined by \p N.
  *                      (In particular, it must have at least as many limbs as
- *                      the modulus \p m.)
- * \param[in] m         The address of the modulus related to \p X.
+ *                      the modulus \p N.)
+ * \param[in] N         The address of the modulus related to \p X.
  * \param[in] input     The input buffer to import from.
  * \param input_length  The length in bytes of \p input.
  * \param ext_rep       The endianness of the number in the input buffer.
@@ -157,20 +157,20 @@
  * \return       #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p X isn't
  *               large enough to hold the value in \p input.
  * \return       #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the external representation
- *               of \p m is invalid or \p X is not less than \p m.
+ *               of \p N is invalid or \p X is not less than \p N.
  */
 int mbedtls_mpi_mod_raw_read(mbedtls_mpi_uint *X,
-                             const mbedtls_mpi_mod_modulus *m,
+                             const mbedtls_mpi_mod_modulus *N,
                              const unsigned char *input,
                              size_t input_length,
                              mbedtls_mpi_mod_ext_rep ext_rep);
 
 /** Export A into unsigned binary data.
  *
- * \param[in] A         The address of the MPI. The size is determined by \p m.
+ * \param[in] A         The address of the MPI. The size is determined by \p N.
  *                      (In particular, it must have at least as many limbs as
- *                      the modulus \p m.)
- * \param[in] m         The address of the modulus related to \p A.
+ *                      the modulus \p N.)
+ * \param[in] N         The address of the modulus related to \p A.
  * \param[out] output   The output buffer to export to.
  * \param output_length The length in bytes of \p output.
  * \param ext_rep       The endianness in which the number should be written into the output buffer.
@@ -179,10 +179,10 @@
  * \return       #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p output isn't
  *               large enough to hold the value of \p A.
  * \return       #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the external representation
- *               of \p m is invalid.
+ *               of \p N is invalid.
  */
 int mbedtls_mpi_mod_raw_write(const mbedtls_mpi_uint *A,
-                              const mbedtls_mpi_mod_modulus *m,
+                              const mbedtls_mpi_mod_modulus *N,
                               unsigned char *output,
                               size_t output_length,
                               mbedtls_mpi_mod_ext_rep ext_rep);
@@ -346,7 +346,7 @@
  *                  is unspecified.
  * \param[in] N     The modulus structure.
  *
- *\ return          \c 0 if successful.
+ * \return          \c 0 if successful.
  *                  Otherwise an \c MBEDTLS_ERR_MPI_xxx error code.
  */
 int mbedtls_mpi_mod_raw_canonical_to_modulus_rep(
@@ -363,7 +363,7 @@
  *                  is unspecified.
  * \param[in] N     The modulus structure.
  *
- *\ return          \c 0 if successful.
+ * \return          \c 0 if successful.
  *                  Otherwise an \c MBEDTLS_ERR_MPI_xxx error code.
  */
 int mbedtls_mpi_mod_raw_modulus_to_canonical_rep(
@@ -410,43 +410,43 @@
 /** Convert an MPI into Montgomery form.
  *
  * \param X      The address of the MPI.
- *               Must have the same number of limbs as \p m.
- * \param m      The address of the modulus, which gives the size of
- *               the base `R` = 2^(biL*m->limbs).
+ *               Must have the same number of limbs as \p N.
+ * \param N      The address of the modulus, which gives the size of
+ *               the base `R` = 2^(biL*N->limbs).
  *
  * \return       \c 0 if successful.
  */
 int mbedtls_mpi_mod_raw_to_mont_rep(mbedtls_mpi_uint *X,
-                                    const mbedtls_mpi_mod_modulus *m);
+                                    const mbedtls_mpi_mod_modulus *N);
 
 /** Convert an MPI back from Montgomery representation.
  *
  * \param X      The address of the MPI.
- *               Must have the same number of limbs as \p m.
- * \param m      The address of the modulus, which gives the size of
- *               the base `R`= 2^(biL*m->limbs).
+ *               Must have the same number of limbs as \p N.
+ * \param N      The address of the modulus, which gives the size of
+ *               the base `R`= 2^(biL*N->limbs).
  *
  * \return       \c 0 if successful.
  */
 int mbedtls_mpi_mod_raw_from_mont_rep(mbedtls_mpi_uint *X,
-                                      const mbedtls_mpi_mod_modulus *m);
+                                      const mbedtls_mpi_mod_modulus *N);
 
 /** \brief  Perform fixed width modular negation.
  *
- * The size of the operation is determined by \p m. \p A must have
- * the same number of limbs as \p m.
+ * The size of the operation is determined by \p N. \p A must have
+ * the same number of limbs as \p N.
  *
  * \p X may be aliased to \p A.
  *
  * \param[out] X        The result of the modular negation.
  *                      This must be initialized.
  * \param[in] A         Little-endian presentation of the input operand. This
- *                      must be less than or equal to \p m.
- * \param[in] m         The modulus to use.
+ *                      must be less than or equal to \p N.
+ * \param[in] N         The modulus to use.
  */
 void mbedtls_mpi_mod_raw_neg(mbedtls_mpi_uint *X,
                              const mbedtls_mpi_uint *A,
-                             const mbedtls_mpi_mod_modulus *m);
+                             const mbedtls_mpi_mod_modulus *N);
 /* END MERGE SLOT 7 */
 
 /* BEGIN MERGE SLOT 8 */
diff --git a/library/bn_mul.h b/library/bn_mul.h
index 307c241..ab59fbd 100644
--- a/library/bn_mul.h
+++ b/library/bn_mul.h
@@ -83,10 +83,6 @@
 /* *INDENT-OFF* */
 #if defined(MBEDTLS_HAVE_ASM)
 
-#ifndef asm
-#define asm __asm
-#endif
-
 /* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
 #if defined(__GNUC__) && \
     ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 )
diff --git a/library/common.h b/library/common.h
index fd3ddba..46af79f 100644
--- a/library/common.h
+++ b/library/common.h
@@ -122,11 +122,13 @@
  */
 inline void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned char *b, size_t n)
 {
-    size_t i;
-    for (i = 0; (i + 4) <= n; i += 4) {
+    size_t i = 0;
+#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
+    for (; (i + 4) <= n; i += 4) {
         uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i);
         mbedtls_put_unaligned_uint32(r + i, x);
     }
+#endif
     for (; i < n; i++) {
         r[i] = a[i] ^ b[i];
     }
@@ -140,4 +142,11 @@
 #define /*no-check-names*/ __func__ __FUNCTION__
 #endif
 
+/* Define `asm` for compilers which don't define it. */
+/* *INDENT-OFF* */
+#ifndef asm
+#define asm __asm__
+#endif
+/* *INDENT-ON* */
+
 #endif /* MBEDTLS_LIBRARY_COMMON_H */
diff --git a/library/constant_time.c b/library/constant_time.c
index 442eb0e..7f4d509 100644
--- a/library/constant_time.c
+++ b/library/constant_time.c
@@ -47,16 +47,63 @@
 
 #include <string.h>
 
+/*
+ * Define MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS where assembly is present to
+ * perform fast unaligned access to volatile data.
+ *
+ * This is needed because mbedtls_get_unaligned_uintXX etc don't support volatile
+ * memory accesses.
+ *
+ * Some of these definitions could be moved into alignment.h but for now they are
+ * only used here.
+ */
+#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) && defined(MBEDTLS_HAVE_ASM)
+#if defined(__arm__) || defined(__thumb__) || defined(__thumb2__) || defined(__aarch64__)
+#define MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS
+#endif
+#endif
+
+#if defined(MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS)
+static inline uint32_t mbedtls_get_unaligned_volatile_uint32(volatile const unsigned char *p)
+{
+    /* This is UB, even where it's safe:
+     *    return *((volatile uint32_t*)p);
+     * so instead the same thing is expressed in assembly below.
+     */
+    uint32_t r;
+#if defined(__arm__) || defined(__thumb__) || defined(__thumb2__)
+    asm ("ldr %0, [%1]" : "=r" (r) : "r" (p) :);
+#elif defined(__aarch64__)
+    asm ("ldr %w0, [%1]" : "=r" (r) : "r" (p) :);
+#endif
+    return r;
+}
+#endif /* MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS */
+
 int mbedtls_ct_memcmp(const void *a,
                       const void *b,
                       size_t n)
 {
-    size_t i;
+    size_t i = 0;
+    /*
+     * `A` and `B` are cast to volatile to ensure that the compiler
+     * generates code that always fully reads both buffers.
+     * Otherwise it could generate a test to exit early if `diff` has all
+     * bits set early in the loop.
+     */
     volatile const unsigned char *A = (volatile const unsigned char *) a;
     volatile const unsigned char *B = (volatile const unsigned char *) b;
-    volatile unsigned char diff = 0;
+    uint32_t diff = 0;
 
-    for (i = 0; i < n; i++) {
+#if defined(MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS)
+    for (; (i + 4) <= n; i += 4) {
+        uint32_t x = mbedtls_get_unaligned_volatile_uint32(A + i);
+        uint32_t y = mbedtls_get_unaligned_volatile_uint32(B + i);
+        diff |= x ^ y;
+    }
+#endif
+
+    for (; i < n; i++) {
         /* Read volatile data in order before computing diff.
          * This avoids IAR compiler warning:
          * 'the order of volatile accesses is undefined ..' */
@@ -414,10 +461,22 @@
 {
     /* mask = c1 == c2 ? 0xff : 0x00 */
     const size_t equal = mbedtls_ct_size_bool_eq(c1, c2);
-    const unsigned char mask = (unsigned char) mbedtls_ct_size_mask(equal);
 
     /* dest[i] = c1 == c2 ? src[i] : dest[i] */
-    for (size_t i = 0; i < len; i++) {
+    size_t i = 0;
+#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
+    const uint32_t mask32 = (uint32_t) mbedtls_ct_size_mask(equal);
+    const unsigned char mask = (unsigned char) mask32 & 0xff;
+
+    for (; (i + 4) <= len; i += 4) {
+        uint32_t a = mbedtls_get_unaligned_uint32(src  + i) &  mask32;
+        uint32_t b = mbedtls_get_unaligned_uint32(dest + i) & ~mask32;
+        mbedtls_put_unaligned_uint32(dest + i, a | b);
+    }
+#else
+    const unsigned char mask = (unsigned char) mbedtls_ct_size_mask(equal);
+#endif /* MBEDTLS_EFFICIENT_UNALIGNED_ACCESS */
+    for (; i < len; i++) {
         dest[i] = (src[i] & mask) | (dest[i] & ~mask);
     }
 }
diff --git a/library/ecp.c b/library/ecp.c
index d9d5425..08fbe86 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -582,11 +582,9 @@
     }
 
     if (grp->h != 1) {
-        mbedtls_mpi_free(&grp->P);
         mbedtls_mpi_free(&grp->A);
         mbedtls_mpi_free(&grp->B);
         mbedtls_ecp_point_free(&grp->G);
-        mbedtls_mpi_free(&grp->N);
     }
 
     if (!ecp_group_is_static_comb_table(grp) && grp->T != NULL) {
diff --git a/library/ecp_curves.c b/library/ecp_curves.c
index e62dcea..727283f 100644
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -4502,7 +4502,9 @@
 #endif
 #endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
 
-#if defined(ECP_LOAD_GROUP)
+
+#if defined(ECP_LOAD_GROUP) || defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
 /*
  * Create an MPI from embedded constants
  * (assumes len is an exact multiple of sizeof mbedtls_mpi_uint)
@@ -4513,7 +4515,9 @@
     X->n = len / sizeof(mbedtls_mpi_uint);
     X->p = (mbedtls_mpi_uint *) p;
 }
+#endif
 
+#if defined(ECP_LOAD_GROUP)
 /*
  * Set an MPI to static value 1
  */
@@ -4627,9 +4631,21 @@
 #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
 /* Constants used by ecp_use_curve25519() */
 static const mbedtls_mpi_sint curve25519_a24 = 0x01DB42;
-static const unsigned char curve25519_part_of_n[] = {
-    0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6,
-    0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED,
+
+/* P = 2^255 - 19 */
+static const mbedtls_mpi_uint curve25519_p[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X7F)
+};
+
+/* N = 2^252 + 27742317777372353535851937790883648493 */
+static const mbedtls_mpi_uint curve25519_n[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8(0XED, 0XD3, 0XF5, 0X5C, 0X1A, 0X63, 0X12, 0X58),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XD6, 0X9C, 0XF7, 0XA2, 0XDE, 0XF9, 0XDE, 0X14),
+    MBEDTLS_BYTES_TO_T_UINT_8(0X00, 0X00, 0X00, 0X00, 0x00, 0x00, 0x00, 0x00),
+    MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10)
 };
 
 /*
@@ -4642,16 +4658,11 @@
     /* Actually ( A + 2 ) / 4 */
     MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->A, curve25519_a24));
 
-    /* P = 2^255 - 19 */
-    MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->P, 1));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&grp->P, 255));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&grp->P, &grp->P, 19));
+    ecp_mpi_load(&grp->P, curve25519_p, sizeof(curve25519_p));
+
     grp->pbits = mbedtls_mpi_bitlen(&grp->P);
 
-    /* N = 2^252 + 27742317777372353535851937790883648493 */
-    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&grp->N,
-                                            curve25519_part_of_n, sizeof(curve25519_part_of_n)));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&grp->N, 252, 1));
+    ecp_mpi_load(&grp->N, curve25519_n, sizeof(curve25519_n));
 
     /* Y intentionally not set, since we use x/z coordinates.
      * This is used as a marker to identify Montgomery curves! */
@@ -4674,11 +4685,29 @@
 #if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
 /* Constants used by ecp_use_curve448() */
 static const mbedtls_mpi_sint curve448_a24 = 0x98AA;
-static const unsigned char curve448_part_of_n[] = {
-    0x83, 0x35, 0xDC, 0x16, 0x3B, 0xB1, 0x24,
-    0xB6, 0x51, 0x29, 0xC9, 0x6F, 0xDE, 0x93,
-    0x3D, 0x8D, 0x72, 0x3A, 0x70, 0xAA, 0xDC,
-    0x87, 0x3D, 0x6D, 0x54, 0xA7, 0xBB, 0x0D,
+
+/* P = 2^448 - 2^224 - 1 */
+static const mbedtls_mpi_uint curve448_p[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFE, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00)
+};
+
+/* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */
+static const mbedtls_mpi_uint curve448_n[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8(0XF3, 0X44, 0X58, 0XAB, 0X92, 0XC2, 0X78, 0X23),
+    MBEDTLS_BYTES_TO_T_UINT_8(0X55, 0X8F, 0XC5, 0X8D, 0X72, 0XC2, 0X6C, 0X21),
+    MBEDTLS_BYTES_TO_T_UINT_8(0X90, 0X36, 0XD6, 0XAE, 0X49, 0XDB, 0X4E, 0XC4),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XE9, 0X23, 0XCA, 0X7C, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X3F),
+    MBEDTLS_BYTES_TO_T_UINT_8(0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00)
 };
 
 /*
@@ -4686,20 +4715,12 @@
  */
 static int ecp_use_curve448(mbedtls_ecp_group *grp)
 {
-    mbedtls_mpi Ns;
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
-    mbedtls_mpi_init(&Ns);
-
     /* Actually ( A + 2 ) / 4 */
     MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->A, curve448_a24));
 
-    /* P = 2^448 - 2^224 - 1 */
-    MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->P, 1));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&grp->P, 224));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&grp->P, &grp->P, 1));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&grp->P, 224));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&grp->P, &grp->P, 1));
+    ecp_mpi_load(&grp->P, curve448_p, sizeof(curve448_p));
     grp->pbits = mbedtls_mpi_bitlen(&grp->P);
 
     /* Y intentionally not set, since we use x/z coordinates.
@@ -4708,17 +4729,12 @@
     MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.Z, 1));
     mbedtls_mpi_free(&grp->G.Y);
 
-    /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */
-    MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&grp->N, 446, 1));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&Ns,
-                                            curve448_part_of_n, sizeof(curve448_part_of_n)));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&grp->N, &grp->N, &Ns));
+    ecp_mpi_load(&grp->N, curve448_n, sizeof(curve448_n));
 
     /* Actually, the required msb for private keys */
     grp->nbits = 447;
 
 cleanup:
-    mbedtls_mpi_free(&Ns);
     if (ret != 0) {
         mbedtls_ecp_group_free(grp);
     }
diff --git a/library/padlock.c b/library/padlock.c
index b6c6919..f42c40f 100644
--- a/library/padlock.c
+++ b/library/padlock.c
@@ -31,12 +31,6 @@
 
 #include <string.h>
 
-/* *INDENT-OFF* */
-#ifndef asm
-#define asm __asm
-#endif
-/* *INDENT-ON* */
-
 #if defined(MBEDTLS_HAVE_X86)
 
 /*
diff --git a/library/pkparse.c b/library/pkparse.c
index 990b554..ccca692 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -429,7 +429,18 @@
     ret = pk_group_id_from_group(&grp, grp_id);
 
 cleanup:
-    mbedtls_ecp_group_free(&grp);
+    /* The API respecting lifecycle for mbedtls_ecp_group struct is
+     * _init(), _load() and _free(). In pk_group_id_from_specified() the
+     * temporary grp breaks that flow and it's members are populated
+     * by pk_group_id_from_group(). As such mbedtls_ecp_group_free()
+     * which is assuming a group populated by _setup() may not clean-up
+     * properly -> Manually free it's members.
+     */
+    mbedtls_mpi_free(&grp.N);
+    mbedtls_mpi_free(&grp.P);
+    mbedtls_mpi_free(&grp.A);
+    mbedtls_mpi_free(&grp.B);
+    mbedtls_ecp_point_free(&grp.G);
 
     return ret;
 }
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 0a8949f..a683fdb 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -5168,6 +5168,18 @@
     (void) alg;
     return PSA_ERROR_NOT_SUPPORTED;
 }
+
+static int psa_key_derivation_allows_free_form_secret_input(
+    psa_algorithm_t kdf_alg)
+{
+#if defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS)
+    if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
+        return 0;
+    }
+#endif
+    (void) kdf_alg;
+    return 1;
+}
 #endif /* AT_LEAST_ONE_BUILTIN_KDF */
 
 psa_status_t psa_key_derivation_setup(psa_key_derivation_operation_t *operation,
@@ -5189,6 +5201,9 @@
         if (status != PSA_SUCCESS) {
             return status;
         }
+        if (!psa_key_derivation_allows_free_form_secret_input(kdf_alg)) {
+            return PSA_ERROR_INVALID_ARGUMENT;
+        }
         status = psa_key_derivation_setup_kdf(operation, kdf_alg);
 #else
         return PSA_ERROR_NOT_SUPPORTED;
diff --git a/library/sha256.c b/library/sha256.c
index 16fd20d..cb09a71 100644
--- a/library/sha256.c
+++ b/library/sha256.c
@@ -89,12 +89,6 @@
 #include <signal.h>
 #include <setjmp.h>
 
-/* *INDENT-OFF* */
-#ifndef asm
-#define asm __asm__
-#endif
-/* *INDENT-ON* */
-
 static jmp_buf return_from_sigill;
 
 /*
diff --git a/library/sha512.c b/library/sha512.c
index 0ea6421..efcbed4 100644
--- a/library/sha512.c
+++ b/library/sha512.c
@@ -104,12 +104,6 @@
 #include <signal.h>
 #include <setjmp.h>
 
-/* *INDENT-OFF* */
-#ifndef asm
-#define asm __asm__
-#endif
-/* *INDENT-ON* */
-
 static jmp_buf return_from_sigill;
 
 /*
@@ -300,12 +294,6 @@
 #  define mbedtls_internal_sha512_process_a64_crypto      mbedtls_internal_sha512_process
 #endif
 
-/* *INDENT-OFF* */
-#ifndef asm
-#define asm __asm__
-#endif
-/* *INDENT-ON* */
-
 /* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
  * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
  */
diff --git a/library/ssl_debug_helpers.h b/library/ssl_debug_helpers.h
index 4d2a170..5c22ed2 100644
--- a/library/ssl_debug_helpers.h
+++ b/library/ssl_debug_helpers.h
@@ -55,6 +55,12 @@
                                  int hs_msg_type, unsigned int extension_type,
                                  const char *extra_msg0, const char *extra_msg1);
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
+void mbedtls_ssl_print_ticket_flags(const mbedtls_ssl_context *ssl,
+                                    int level, const char *file, int line,
+                                    unsigned int flags);
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */
+
 #define MBEDTLS_SSL_PRINT_EXTS(level, hs_msg_type, extensions_mask)            \
     mbedtls_ssl_print_extensions(ssl, level, __FILE__, __LINE__,       \
                                  hs_msg_type, extensions_mask, NULL)
@@ -63,12 +69,22 @@
     mbedtls_ssl_print_extension(ssl, level, __FILE__, __LINE__,        \
                                 hs_msg_type, extension_type,           \
                                 extra, NULL)
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
+#define MBEDTLS_SSL_PRINT_TICKET_FLAGS(level, flags)             \
+    mbedtls_ssl_print_ticket_flags(ssl, level, __FILE__, __LINE__, flags)
+#endif
+
 #else
 
 #define MBEDTLS_SSL_PRINT_EXTS(level, hs_msg_type, extension_mask)
 
 #define MBEDTLS_SSL_PRINT_EXT(level, hs_msg_type, extension_type, extra)
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
+#define MBEDTLS_SSL_PRINT_TICKET_FLAGS(level, flags)
+#endif
+
 #endif /* MBEDTLS_DEBUG_C */
 
 #endif /* MBEDTLS_SSL_DEBUG_HELPERS_H */
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 16eccfc..146dae0 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -2719,4 +2719,25 @@
                                      const char *hostname);
 #endif
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
+static inline unsigned int mbedtls_ssl_session_get_ticket_flags(
+    mbedtls_ssl_session *session, unsigned int flags)
+{
+    return session->ticket_flags &
+           (flags & MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
+}
+
+static inline void mbedtls_ssl_session_set_ticket_flags(
+    mbedtls_ssl_session *session, unsigned int flags)
+{
+    session->ticket_flags |= (flags & MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
+}
+
+static inline void mbedtls_ssl_session_clear_ticket_flags(
+    mbedtls_ssl_session *session, unsigned int flags)
+{
+    session->ticket_flags &= ~(flags & MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */
+
 #endif /* ssl_misc.h */
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index bd8fd8c..86f5c0b 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -735,6 +735,36 @@
     }
 }
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
+#define ARRAY_LENGTH(a) (sizeof(a) / sizeof(*(a)))
+
+static const char *ticket_flag_name_table[] =
+{
+    [0] = "ALLOW_PSK_RESUMPTION",
+    [2] = "ALLOW_PSK_EPHEMERAL_RESUMPTION",
+    [3] = "ALLOW_EARLY_DATA",
+};
+
+void mbedtls_ssl_print_ticket_flags(const mbedtls_ssl_context *ssl,
+                                    int level, const char *file, int line,
+                                    unsigned int flags)
+{
+    size_t i;
+
+    mbedtls_debug_print_msg(ssl, level, file, line,
+                            "print ticket_flags (0x%02x)", flags);
+
+    flags = flags & MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK;
+
+    for (i = 0; i < ARRAY_LENGTH(ticket_flag_name_table); i++) {
+        if ((flags & (1 << i))) {
+            mbedtls_debug_print_msg(ssl, level, file, line, "- %s is set.",
+                                    ticket_flag_name_table[i]);
+        }
+    }
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */
+
 #endif /* MBEDTLS_DEBUG_C */
 
 void mbedtls_ssl_optimize_checksum(mbedtls_ssl_context *ssl,
diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c
index 291a4cf..4aea61c 100644
--- a/library/ssl_tls13_client.c
+++ b/library/ssl_tls13_client.c
@@ -676,7 +676,10 @@
 {
     mbedtls_ssl_session *session = ssl->session_negotiate;
     return ssl->handshake->resume &&
-           session != NULL && session->ticket != NULL;
+           session != NULL && session->ticket != NULL &&
+           mbedtls_ssl_conf_tls13_check_kex_modes(
+        ssl, mbedtls_ssl_session_get_ticket_flags(
+            session, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL));
 }
 
 #if defined(MBEDTLS_SSL_EARLY_DATA)
@@ -2618,6 +2621,10 @@
     session->ticket = ticket;
     session->ticket_len = ticket_len;
 
+    /* Clear all flags in ticket_flags */
+    mbedtls_ssl_session_clear_ticket_flags(
+        session, MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
+
     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
     extensions_len = MBEDTLS_GET_UINT16_BE(p, 0);
     p += 2;
@@ -2701,6 +2708,11 @@
                           session->resumption_key,
                           session->resumption_key_len);
 
+    /* Set ticket_flags depends on the selected key exchange modes */
+    mbedtls_ssl_session_set_ticket_flags(
+        session, ssl->conf->tls13_kex_modes);
+    MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags);
+
     return 0;
 }
 
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index 980c225..ef90f69 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -161,6 +161,26 @@
         goto exit;
     }
 
+    /* RFC 8446 section 4.2.9
+     *
+     * Servers SHOULD NOT send NewSessionTicket with tickets that are not
+     * compatible with the advertised modes; however, if a server does so,
+     * the impact will just be that the client's attempts at resumption fail.
+     *
+     * We regard the ticket with incompatible key exchange modes as not match.
+     */
+    ret = MBEDTLS_ERR_ERROR_GENERIC_ERROR;
+    MBEDTLS_SSL_PRINT_TICKET_FLAGS(4,
+                                   session->ticket_flags);
+    if (mbedtls_ssl_tls13_check_kex_modes(
+            ssl,
+            mbedtls_ssl_session_get_ticket_flags(
+                session,
+                MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL))) {
+        MBEDTLS_SSL_DEBUG_MSG(3, ("No suitable key exchange mode"));
+        goto exit;
+    }
+
     ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
 #if defined(MBEDTLS_HAVE_TIME)
     now = mbedtls_time(NULL);
@@ -2549,11 +2569,20 @@
 
     mbedtls_ssl_tls13_handshake_wrapup(ssl);
 
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
-    mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET);
-#else
-    mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER);
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && \
+    defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
+/* TODO: Remove the check of SOME_PSK_ENABLED since SESSION_TICKETS requires
+ *       SOME_PSK_ENABLED to be enabled. Here is just to make CI happy. It is
+ *       expected to be resolved with issue#6395.
+ */
+    /* Sent NewSessionTicket message only when client supports PSK */
+    if (mbedtls_ssl_tls13_some_psk_enabled(ssl)) {
+        mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET);
+    } else
 #endif
+    {
+        mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER);
+    }
     return 0;
 }
 
@@ -2604,6 +2633,15 @@
     session->start = mbedtls_time(NULL);
 #endif
 
+    /* Set ticket_flags depends on the advertised psk key exchange mode */
+    mbedtls_ssl_session_clear_ticket_flags(
+        session, MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
+#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
+    mbedtls_ssl_session_set_ticket_flags(
+        session, ssl->handshake->tls13_kex_modes);
+#endif
+    MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags);
+
     /* Generate ticket_age_add */
     if ((ret = ssl->conf->f_rng(ssl->conf->p_rng,
                                 (unsigned char *) &session->ticket_age_add,
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 4b3799f..b124065 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -371,7 +371,8 @@
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
 #define USAGE_TLS1_3_KEY_EXCHANGE_MODES \
     "    tls13_kex_modes=%%s   default: all\n"     \
-    "                          options: psk, psk_ephemeral, ephemeral, ephemeral_all, psk_all, all\n"
+    "                          options: psk, psk_ephemeral, psk_all, ephemeral,\n"     \
+    "                                   ephemeral_all, all, psk_or_ephemeral\n"
 #else
 #define USAGE_TLS1_3_KEY_EXCHANGE_MODES ""
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
@@ -1215,6 +1216,9 @@
                 opt.tls13_kex_modes = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL;
             } else if (strcmp(q, "all") == 0) {
                 opt.tls13_kex_modes = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_ALL;
+            } else if (strcmp(q, "psk_or_ephemeral") == 0) {
+                opt.tls13_kex_modes = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK |
+                                      MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL;
             } else {
                 goto usage;
             }
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 90a13eb..b3d9f5a 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -1412,7 +1412,7 @@
         return ret;
     }
 
-    switch (opt.dummy_ticket % 7) {
+    switch (opt.dummy_ticket % 11) {
         case 1:
             return MBEDTLS_ERR_SSL_INVALID_MAC;
         case 2:
@@ -1432,6 +1432,20 @@
             session->ticket_age_add -= 1000;
 #endif
             break;
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+        case 7:
+            session->ticket_flags = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE;
+            break;
+        case 8:
+            session->ticket_flags = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
+            break;
+        case 9:
+            session->ticket_flags = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
+            break;
+        case 10:
+            session->ticket_flags = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL;
+            break;
+#endif
         default:
             break;
     }
diff --git a/scripts/code_style.py b/scripts/code_style.py
index aae3e24..3958e87 100755
--- a/scripts/code_style.py
+++ b/scripts/code_style.py
@@ -171,18 +171,32 @@
     """
     uncrustify_version = get_uncrustify_version().strip()
     if UNCRUSTIFY_SUPPORTED_VERSION not in uncrustify_version:
-        print("Warning: Using unsupported Uncrustify version '" \
-                + uncrustify_version + "' (Note: The only supported version" \
-                "is " + UNCRUSTIFY_SUPPORTED_VERSION + ")", file=STDOUT_UTF8)
-
-    src_files = get_src_files()
+        print("Warning: Using unsupported Uncrustify version '" +
+              uncrustify_version + "'", file=STDOUT_UTF8)
+        print("Note: The only supported version is " +
+              UNCRUSTIFY_SUPPORTED_VERSION, file=STDOUT_UTF8)
 
     parser = argparse.ArgumentParser()
-    parser.add_argument('-f', '--fix', action='store_true', \
-            help='modify source files to fix the code style')
+    parser.add_argument('-f', '--fix', action='store_true',
+                        help=('modify source files to fix the code style '
+                              '(default: print diff, do not modify files)'))
+    # --files is almost useless: it only matters if there are no files
+    # ('code_style.py' without arguments checks all files known to Git,
+    # 'code_style.py --files' does nothing). In particular,
+    # 'code_style.py --fix --files ...' is intended as a stable ("porcelain")
+    # way to restyle a possibly empty set of files.
+    parser.add_argument('--files', action='store_true',
+                        help='only check the specified files (default with non-option arguments)')
+    parser.add_argument('operands', nargs='*', metavar='FILE',
+                        help='files to check (if none: check files that are known to git)')
 
     args = parser.parse_args()
 
+    if args.files or args.operands:
+        src_files = args.operands
+    else:
+        src_files = get_src_files()
+
     if args.fix:
         # Fix mode
         return fix_style(src_files)
diff --git a/scripts/mbedtls_dev/crypto_knowledge.py b/scripts/mbedtls_dev/crypto_knowledge.py
index 1a03321..819d92a 100644
--- a/scripts/mbedtls_dev/crypto_knowledge.py
+++ b/scripts/mbedtls_dev/crypto_knowledge.py
@@ -20,7 +20,7 @@
 
 import enum
 import re
-from typing import FrozenSet, Iterable, List, Optional, Tuple
+from typing import FrozenSet, Iterable, List, Optional, Tuple, Dict
 
 from .asymmetric_key_data import ASYMMETRIC_KEY_DATA
 
@@ -148,7 +148,7 @@
         'PSA_ECC_FAMILY_BRAINPOOL_P_R1': (160, 192, 224, 256, 320, 384, 512),
         'PSA_ECC_FAMILY_MONTGOMERY': (255, 448),
         'PSA_ECC_FAMILY_TWISTED_EDWARDS': (255, 448),
-    }
+    } # type: Dict[str, Tuple[int, ...]]
     KEY_TYPE_SIZES = {
         'PSA_KEY_TYPE_AES': (128, 192, 256), # exhaustive
         'PSA_KEY_TYPE_ARIA': (128, 192, 256), # exhaustive
@@ -162,7 +162,7 @@
         'PSA_KEY_TYPE_PEPPER': (128, 256), # sample
         'PSA_KEY_TYPE_RAW_DATA': (8, 40, 128), # sample
         'PSA_KEY_TYPE_RSA_KEY_PAIR': (1024, 1536), # small sample
-    }
+    } # type: Dict[str, Tuple[int, ...]]
     def sizes_to_test(self) -> Tuple[int, ...]:
         """Return a tuple of key sizes to test.
 
@@ -214,9 +214,7 @@
         This function does not currently handle key derivation or PAKE.
         """
         #pylint: disable=too-many-branches,too-many-return-statements
-        if alg.is_wildcard:
-            return False
-        if alg.is_invalid_truncation():
+        if not alg.is_valid_for_operation():
             return False
         if self.head == 'HMAC' and alg.head == 'HMAC':
             return True
@@ -248,6 +246,8 @@
             # So a public key object with a key agreement algorithm is not
             # a valid combination.
             return False
+        if alg.is_invalid_key_agreement_with_derivation():
+            return False
         if self.head == 'ECC':
             assert self.params is not None
             eccc = EllipticCurveCategory.from_family(self.params[0])
@@ -414,17 +414,38 @@
         self.category = self.determine_category(self.base_expression, self.head)
         self.is_wildcard = self.determine_wildcard(self.expression)
 
-    def is_key_agreement_with_derivation(self) -> bool:
-        """Whether this is a combined key agreement and key derivation algorithm."""
+    def get_key_agreement_derivation(self) -> Optional[str]:
+        """For a combined key agreement and key derivation algorithm, get the derivation part.
+
+        For anything else, return None.
+        """
         if self.category != AlgorithmCategory.KEY_AGREEMENT:
-            return False
+            return None
         m = re.match(r'PSA_ALG_KEY_AGREEMENT\(\w+,\s*(.*)\)\Z', self.expression)
         if not m:
-            return False
+            return None
         kdf_alg = m.group(1)
         # Assume kdf_alg is either a valid KDF or 0.
-        return not re.match(r'(?:0[Xx])?0+\s*\Z', kdf_alg)
+        if re.match(r'(?:0[Xx])?0+\s*\Z', kdf_alg):
+            return None
+        return kdf_alg
 
+    KEY_DERIVATIONS_INCOMPATIBLE_WITH_AGREEMENT = frozenset([
+        'PSA_ALG_TLS12_ECJPAKE_TO_PMS', # secret input in specific format
+    ])
+    def is_valid_key_agreement_with_derivation(self) -> bool:
+        """Whether this is a valid combined key agreement and key derivation algorithm."""
+        kdf_alg = self.get_key_agreement_derivation()
+        if kdf_alg is None:
+            return False
+        return kdf_alg not in self.KEY_DERIVATIONS_INCOMPATIBLE_WITH_AGREEMENT
+
+    def is_invalid_key_agreement_with_derivation(self) -> bool:
+        """Whether this is an invalid combined key agreement and key derivation algorithm."""
+        kdf_alg = self.get_key_agreement_derivation()
+        if kdf_alg is None:
+            return False
+        return kdf_alg in self.KEY_DERIVATIONS_INCOMPATIBLE_WITH_AGREEMENT
 
     def short_expression(self, level: int = 0) -> str:
         """Abbreviate the expression, keeping it human-readable.
@@ -498,13 +519,26 @@
                 return True
         return False
 
+    def is_valid_for_operation(self) -> bool:
+        """Whether this algorithm construction is valid for an operation.
+
+        This function assumes that the algorithm is constructed in a
+        "grammatically" correct way, and only rejects semantically invalid
+        combinations.
+        """
+        if self.is_wildcard:
+            return False
+        if self.is_invalid_truncation():
+            return False
+        return True
+
     def can_do(self, category: AlgorithmCategory) -> bool:
         """Whether this algorithm can perform operations in the given category.
         """
         if category == self.category:
             return True
         if category == AlgorithmCategory.KEY_DERIVATION and \
-           self.is_key_agreement_with_derivation():
+           self.is_valid_key_agreement_with_derivation():
             return True
         return False
 
diff --git a/tests/Makefile b/tests/Makefile
index f037338..312607e 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -203,6 +203,7 @@
 	rm -f src/*.o src/drivers/*.o src/libmbed*
 	rm -f include/test/instrument_record_status.h
 	rm -rf libtestdriver1
+	rm -f ../library/libtestdriver1.a
 else
 	if exist *.c del /Q /F *.c
 	if exist *.exe del /Q /F *.exe
diff --git a/tests/compat.sh b/tests/compat.sh
index 1454fec..7693400 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -753,15 +753,17 @@
     echo "$SERVER_CMD" > $SRV_OUT
     # for servers without -www or equivalent
     while :; do echo bla; sleep 1; done | $SERVER_CMD >> $SRV_OUT 2>&1 &
-    PROCESS_ID=$!
+    SRV_PID=$!
 
-    wait_server_start "$PORT" "$PROCESS_ID"
+    wait_server_start "$PORT" "$SRV_PID"
 }
 
 # terminate the running server
 stop_server() {
-    kill $PROCESS_ID 2>/dev/null
-    wait $PROCESS_ID 2>/dev/null
+    # For Ubuntu 22.04, `Terminated` message is outputed by wait command.
+    # To remove it from stdout, redirect stdout/stderr to SRV_OUT
+    kill $SRV_PID >/dev/null 2>&1
+    wait $SRV_PID >> $SRV_OUT 2>&1
 
     if [ "$MEMCHECK" -gt 0 ]; then
         if is_mbedtls "$SERVER_CMD" && has_mem_err $SRV_OUT; then
@@ -777,7 +779,7 @@
 # kill the running server (used when killed by signal)
 cleanup() {
     rm -f $SRV_OUT $CLI_OUT
-    kill $PROCESS_ID >/dev/null 2>&1
+    kill $SRV_PID >/dev/null 2>&1
     kill $WATCHDOG_PID >/dev/null 2>&1
     exit 1
 }
@@ -790,11 +792,13 @@
     ( sleep "$DOG_DELAY"; echo "TIMEOUT" >> $CLI_OUT; kill $CLI_PID ) &
     WATCHDOG_PID=$!
 
-    wait $CLI_PID
+    # For Ubuntu 22.04, `Terminated` message is outputed by wait command.
+    # To remove it from stdout, redirect stdout/stderr to CLI_OUT
+    wait $CLI_PID >> $CLI_OUT 2>&1
     EXIT=$?
 
-    kill $WATCHDOG_PID
-    wait $WATCHDOG_PID
+    kill $WATCHDOG_PID >/dev/null 2>&1
+    wait $WATCHDOG_PID >> $CLI_OUT 2>&1
 
     echo "EXIT: $EXIT" >> $CLI_OUT
 }
diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh
index 3aaf3f3..821a37b 100755
--- a/tests/opt-testcases/tls13-misc.sh
+++ b/tests/opt-testcases/tls13-misc.sh
@@ -323,3 +323,171 @@
             -c "EncryptedExtensions: early_data(42) extension received." \
             -c "EncryptedExtensions: early_data(42) extension ( ignored )."
 
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/none." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=7" \
+         "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "sent selected_identity:" \
+         -s "key exchange mode: ephemeral" \
+         -S "key exchange mode: psk_ephemeral" \
+         -S "key exchange mode: psk$" \
+         -s "No suitable key exchange mode" \
+         -s "No matched PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=8" \
+         "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "No suitable key exchange mode" \
+         -s "found matched identity"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk_ephemeral." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=9" \
+         "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "sent selected_identity:" \
+         -s "key exchange mode: ephemeral" \
+         -S "key exchange mode: psk_ephemeral" \
+         -S "key exchange mode: psk$" \
+         -s "No suitable key exchange mode" \
+         -s "No matched PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk_all." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=10" \
+         "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "No suitable key exchange mode" \
+         -s "found matched identity"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/none." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=7" \
+         "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "sent selected_identity:" \
+         -s "key exchange mode: ephemeral" \
+         -S "key exchange mode: psk_ephemeral" \
+         -S "key exchange mode: psk$" \
+         -s "No suitable key exchange mode" \
+         -s "No matched PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=8" \
+         "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "sent selected_identity:" \
+         -s "key exchange mode: ephemeral" \
+         -S "key exchange mode: psk_ephemeral" \
+         -S "key exchange mode: psk$" \
+         -s "No suitable key exchange mode" \
+         -s "No matched PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk_ephemeral." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=9" \
+         "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "No suitable key exchange mode" \
+         -s "found matched identity"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk_all." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=10" \
+         "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "No suitable key exchange mode" \
+         -s "found matched identity"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/none." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=7" \
+         "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "sent selected_identity:" \
+         -s "key exchange mode: ephemeral" \
+         -S "key exchange mode: psk_ephemeral" \
+         -S "key exchange mode: psk$" \
+         -s "No suitable key exchange mode" \
+         -s "No matched PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=8" \
+         "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "No suitable key exchange mode" \
+         -s "found matched identity"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk_ephemeral." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=9" \
+         "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "No suitable key exchange mode" \
+         -s "found matched identity"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk_all." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=10" \
+         "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "No suitable key exchange mode" \
+         -s "found matched identity"
+
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 1e10da0..2221d59 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -133,13 +133,14 @@
 pre_initialize_variables () {
     CONFIG_H='include/mbedtls/mbedtls_config.h'
     CRYPTO_CONFIG_H='include/psa/crypto_config.h'
+    CONFIG_TEST_DRIVER_H='tests/include/test/drivers/config_test_driver.h'
 
     # Files that are clobbered by some jobs will be backed up. Use a different
     # suffix from auxiliary scripts so that all.sh and auxiliary scripts can
     # independently decide when to remove the backup file.
     backup_suffix='.all.bak'
     # Files clobbered by config.py
-    files_to_back_up="$CONFIG_H $CRYPTO_CONFIG_H"
+    files_to_back_up="$CONFIG_H $CRYPTO_CONFIG_H $CONFIG_TEST_DRIVER_H"
     # Files clobbered by in-tree cmake
     files_to_back_up="$files_to_back_up Makefile library/Makefile programs/Makefile tests/Makefile programs/fuzz/Makefile"
 
@@ -1948,6 +1949,18 @@
     tests/scripts/depends.py pkalgs
 }
 
+component_build_no_pk_rsa_alt_support () {
+    msg "build: !MBEDTLS_PK_RSA_ALT_SUPPORT" # ~30s
+
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_PK_RSA_ALT_SUPPORT
+    scripts/config.py set MBEDTLS_RSA_C
+    scripts/config.py set MBEDTLS_X509_CRT_WRITE_C
+
+    # Only compile - this is primarily to test for compile issues
+    make CC=gcc CFLAGS='-Werror -Wall -Wextra -I../tests/include/alt-dummy'
+}
+
 component_build_module_alt () {
     msg "build: MBEDTLS_XXX_ALT" # ~30s
     scripts/config.py full
@@ -2028,6 +2041,12 @@
 component_test_psa_crypto_config_accel_ecdsa () {
     msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated ECDSA"
 
+    # Algorithms and key types to accelerate
+    loc_accel_list="ALG_ECDSA ALG_DETERMINISTIC_ECDSA KEY_TYPE_ECC_KEY_PAIR KEY_TYPE_ECC_PUBLIC_KEY"
+
+    # Configure and build the test driver library
+    # -------------------------------------------
+
     # Disable ALG_STREAM_CIPHER and ALG_ECB_NO_PADDING to avoid having
     # partial support for cipher operations in the driver test library.
     scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_STREAM_CIPHER
@@ -2038,32 +2057,121 @@
     scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_SHA384_C
     scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_SHA512_C
 
-    loc_accel_list="ALG_ECDSA ALG_DETERMINISTIC_ECDSA KEY_TYPE_ECC_KEY_PAIR KEY_TYPE_ECC_PUBLIC_KEY"
     loc_accel_flags=$( echo "$loc_accel_list" | sed 's/[^ ]* */-DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_&/g' )
     make -C tests libtestdriver1.a CFLAGS="$ASAN_CFLAGS $loc_accel_flags" LDFLAGS="$ASAN_CFLAGS"
 
-    # Restore test driver base configuration
-    scripts/config.py -f tests/include/test/drivers/config_test_driver.h unset MBEDTLS_SHA224_C
-    scripts/config.py -f tests/include/test/drivers/config_test_driver.h unset MBEDTLS_SHA384_C
-    scripts/config.py -f tests/include/test/drivers/config_test_driver.h unset MBEDTLS_SHA512_C
+    # Configure and build the test driver library
+    # -------------------------------------------
 
+    # Start from default config (no USE_PSA) + driver support + TLS 1.3
     scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
     scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    scripts/config.py set MBEDTLS_SSL_PROTO_TLS1_3
+
+    # Disable the module that's accelerated
     scripts/config.py unset MBEDTLS_ECDSA_C
+
+    # Disable things that depend on it
     scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
     scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
 
+    # Build the library
     loc_accel_flags="$loc_accel_flags $( echo "$loc_accel_list" | sed 's/[^ ]* */-DMBEDTLS_PSA_ACCEL_&/g' )"
     make CFLAGS="$ASAN_CFLAGS -O -Werror -I../tests/include -I../tests -I../../tests -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_TEST_LIBTESTDRIVER1 $loc_accel_flags" LDFLAGS="-ltestdriver1 $ASAN_CFLAGS"
 
+    # Make sure ECDSA was not re-enabled by accident (additive config)
     not grep mbedtls_ecdsa_ library/ecdsa.o
 
+    # Run the tests
+    # -------------
+
     msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated ECDSA"
     make test
 }
 
+# Auxiliary function to build config for hashes with and without drivers
+config_psa_crypto_config_ecdsa_use_psa () {
+    DRIVER_ONLY="$1"
+    # start with config full for maximum coverage (also enables USE_PSA)
+    scripts/config.py full
+    # enable support for drivers and configuring PSA-only algorithms
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
+    if [ "$DRIVER_ONLY" -eq 1 ]; then
+        # Disable the module that's accelerated
+        scripts/config.py unset MBEDTLS_ECDSA_C
+    fi
+    # Disable things that depend on it
+    # TODO: make these work - #6862
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+}
+
+# Keep in sync with component_test_psa_crypto_config_reference_ecdsa_use_psa
+component_test_psa_crypto_config_accel_ecdsa_use_psa () {
+    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated ECDSA + USE_PSA"
+
+    # Algorithms and key types to accelerate
+    loc_accel_list="ALG_ECDSA ALG_DETERMINISTIC_ECDSA KEY_TYPE_ECC_KEY_PAIR KEY_TYPE_ECC_PUBLIC_KEY"
+
+    # Configure and build the test driver library
+    # -------------------------------------------
+
+    # Disable ALG_STREAM_CIPHER and ALG_ECB_NO_PADDING to avoid having
+    # partial support for cipher operations in the driver test library.
+    scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_STREAM_CIPHER
+    scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_ECB_NO_PADDING
+
+    # All SHA-2 variants are needed for ECDSA signature tests,
+    # but only SHA-256 is enabled by default, so enable the others.
+    scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_SHA224_C
+    scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_SHA384_C
+    scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_SHA512_C
+
+    loc_accel_flags=$( echo "$loc_accel_list" | sed 's/[^ ]* */-DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_&/g' )
+    make -C tests libtestdriver1.a CFLAGS="$ASAN_CFLAGS $loc_accel_flags" LDFLAGS="$ASAN_CFLAGS"
+
+    # Configure and build the main libraries with drivers enabled
+    # -----------------------------------------------------------
+
+    # Use the same config as reference, only without built-in ECDSA
+    config_psa_crypto_config_ecdsa_use_psa 1
+
+    # Build the library
+    loc_accel_flags="$loc_accel_flags $( echo "$loc_accel_list" | sed 's/[^ ]* */-DMBEDTLS_PSA_ACCEL_&/g' )"
+    make CFLAGS="$ASAN_CFLAGS -O -Werror -I../tests/include -I../tests -I../../tests -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_TEST_LIBTESTDRIVER1 $loc_accel_flags" LDFLAGS="-ltestdriver1 $ASAN_CFLAGS"
+
+    # Make sure ECDSA was not re-enabled by accident (additive config)
+    not grep mbedtls_ecdsa_ library/ecdsa.o
+
+    # Run the tests
+    # -------------
+
+    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated ECDSA + USE_PSA"
+    make test
+
+    # TODO: ssl-opt.sh (currently doesn't pass) - #6861
+}
+
+# Keep in sync with component_test_psa_crypto_config_accel_ecdsa_use_psa.
+# Used by tests/scripts/analyze_outcomes.py for comparison purposes.
+component_test_psa_crypto_config_reference_ecdsa_use_psa () {
+    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated ECDSA + USE_PSA"
+
+    # To be aligned with the accel component that needs this
+    scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_STREAM_CIPHER
+    scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_ECB_NO_PADDING
+
+    config_psa_crypto_config_ecdsa_use_psa 0
+
+    make
+
+    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated ECDSA + USE_PSA"
+    make test
+
+    # TODO: ssl-opt.sh (when the accel component is ready) - #6861
+}
+
 component_test_psa_crypto_config_accel_ecdh () {
     msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated ECDH"
 
@@ -2141,15 +2249,6 @@
     loc_accel_flags=$( echo "$loc_accel_list" | sed 's/[^ ]* */-DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_&/g' )
     make -C tests libtestdriver1.a CFLAGS="$ASAN_CFLAGS $loc_accel_flags" LDFLAGS="$ASAN_CFLAGS"
 
-    # Restore test driver base configuration
-    scripts/config.py -f tests/include/test/drivers/config_test_driver.h unset MBEDTLS_SHA1_C
-    scripts/config.py -f tests/include/test/drivers/config_test_driver.h unset MBEDTLS_SHA224_C
-    scripts/config.py -f tests/include/test/drivers/config_test_driver.h unset MBEDTLS_SHA512_C
-    scripts/config.py -f tests/include/test/drivers/config_test_driver.h unset MBEDTLS_MD_C
-    scripts/config.py -f tests/include/test/drivers/config_test_driver.h unset MBEDTLS_PEM_PARSE_C
-    scripts/config.py -f tests/include/test/drivers/config_test_driver.h unset MBEDTLS_BASE64_C
-
-
     # Mbed TLS library build
     scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
     scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py
index bb44396..eeded5f 100755
--- a/tests/scripts/analyze_outcomes.py
+++ b/tests/scripts/analyze_outcomes.py
@@ -87,8 +87,8 @@
                 driver_test_passed = True
             if component_ref in entry:
                 reference_test_passed = True
-        if(driver_test_passed is False and reference_test_passed is True):
-            print('{}: driver: skipped/failed; reference: passed'.format(key))
+        if(reference_test_passed and not driver_test_passed):
+            print(key)
             result = False
     return result
 
@@ -123,6 +123,7 @@
     """Perform coverage analysis."""
     del args # unused
     outcomes = read_outcome_file(outcome_file)
+    print("\n*** Analyze coverage ***\n")
     results = analyze_outcomes(outcomes)
     return results.error_count == 0
 
@@ -131,6 +132,8 @@
     ignored_tests = ['test_suite_' + x for x in args['ignored_suites']]
 
     outcomes = read_outcome_file(outcome_file)
+    print("\n*** Analyze driver {} vs reference {} ***\n".format(
+        args['component_driver'], args['component_ref']))
     return analyze_driver_vs_reference(outcomes, args['component_ref'],
                                        args['component_driver'], ignored_tests)
 
@@ -138,15 +141,38 @@
 TASKS = {
     'analyze_coverage':                 {
         'test_function': do_analyze_coverage,
-        'args': {}},
+        'args': {}
+        },
+    # How to use analyze_driver_vs_reference_xxx locally:
+    # 1. tests/scripts/all.sh --outcome-file "$PWD/out.csv" <component_ref> <component_driver>
+    # 2. tests/scripts/analyze_outcomes.py out.csv analyze_driver_vs_reference_xxx
     'analyze_driver_vs_reference_hash': {
         'test_function': do_analyze_driver_vs_reference,
         'args': {
             'component_ref': 'test_psa_crypto_config_reference_hash_use_psa',
             'component_driver': 'test_psa_crypto_config_accel_hash_use_psa',
-            'ignored_suites': ['shax', 'mdx', # the software implementations that are being excluded
-                               'md',  # the legacy abstraction layer that's being excluded
-                              ]}}
+            'ignored_suites': [
+                'shax', 'mdx', # the software implementations that are being excluded
+                'md',  # the legacy abstraction layer that's being excluded
+            ]}},
+    'analyze_driver_vs_reference_ecdsa': {
+        'test_function': do_analyze_driver_vs_reference,
+        'args': {
+            'component_ref': 'test_psa_crypto_config_reference_ecdsa_use_psa',
+            'component_driver': 'test_psa_crypto_config_accel_ecdsa_use_psa',
+            'ignored_suites': [
+                'ecdsa', # the software implementation that's excluded
+                # the following lines should not be needed,
+                # they will be removed by upcoming work
+                'psa_crypto_se_driver_hal', # #6856
+                'random', # #6856
+                'ecp', # #6856
+                'pk', # #6857
+                'x509parse', # #6858
+                'x509write', # #6858
+                'debug', # #6860
+                'ssl', # #6860
+            ]}},
 }
 
 def main():
diff --git a/tests/scripts/depends.py b/tests/scripts/depends.py
index d4fe4fd..52ca412 100755
--- a/tests/scripts/depends.py
+++ b/tests/scripts/depends.py
@@ -419,11 +419,8 @@
                                  exclude=r'MBEDTLS_(MD|RIPEMD|SHA1_)' \
                                           '|MBEDTLS_SHA224_' \
                                           '|MBEDTLS_SHA384_'),
-            # Key exchange types. Only build the library and the sample
-            # programs.
-            'kex': ExclusiveDomain(key_exchange_symbols,
-                                   [build_command + ['lib'],
-                                    build_command + ['-C', 'programs']]),
+            # Key exchange types.
+            'kex': ExclusiveDomain(key_exchange_symbols, build_and_test),
             'pkalgs': ComplementaryDomain(['MBEDTLS_ECDSA_C',
                                            'MBEDTLS_ECP_C',
                                            'MBEDTLS_PKCS1_V21',
diff --git a/tests/scripts/doxygen.sh b/tests/scripts/doxygen.sh
index 2c523ba..e355073 100755
--- a/tests/scripts/doxygen.sh
+++ b/tests/scripts/doxygen.sh
@@ -35,7 +35,7 @@
     grep -v "warning: ignoring unsupported tag" \
     > doc.filtered
 
-if egrep "(warning|error):" doc.filtered; then
+if grep -E "(warning|error):" doc.filtered; then
     echo "FAIL" >&2
     exit 1;
 fi
diff --git a/tests/scripts/generate_psa_tests.py b/tests/scripts/generate_psa_tests.py
index b271048..752e7ca 100755
--- a/tests/scripts/generate_psa_tests.py
+++ b/tests/scripts/generate_psa_tests.py
@@ -151,14 +151,16 @@
     tc.set_arguments([key_type] + list(args))
     return tc
 
-class NotSupported:
-    """Generate test cases for when something is not supported."""
+class KeyTypeNotSupported:
+    """Generate test cases for when a key type is not supported."""
 
     def __init__(self, info: Information) -> None:
         self.constructors = info.constructors
 
     ALWAYS_SUPPORTED = frozenset([
         'PSA_KEY_TYPE_DERIVE',
+        'PSA_KEY_TYPE_PASSWORD',
+        'PSA_KEY_TYPE_PASSWORD_HASH',
         'PSA_KEY_TYPE_RAW_DATA',
         'PSA_KEY_TYPE_HMAC'
     ])
@@ -355,7 +357,7 @@
                 dependencies[i] = '!' + dep
         tc.set_dependencies(dependencies)
         tc.set_function(category.name.lower() + '_fail')
-        arguments = []
+        arguments = [] # type: List[str]
         if kt:
             key_material = kt.key_material(kt.sizes_to_test()[0])
             arguments += [key_type, test_case.hex_string(key_material)]
@@ -522,7 +524,7 @@
             key_type: psa_storage.Expr, bits: int,
             alg: psa_storage.Expr
     ) -> bool:
-        """Whether to the given key with the given algorithm.
+        """Whether to exercise the given key with the given algorithm.
 
         Normally only the type and algorithm matter for compatibility, and
         this is handled in crypto_knowledge.KeyType.can_do(). This function
@@ -900,7 +902,7 @@
         'test_suite_psa_crypto_generate_key.generated':
         lambda info: KeyGenerate(info).test_cases_for_key_generation(),
         'test_suite_psa_crypto_not_supported.generated':
-        lambda info: NotSupported(info).test_cases_for_not_supported(),
+        lambda info: KeyTypeNotSupported(info).test_cases_for_not_supported(),
         'test_suite_psa_crypto_op_fail.generated':
         lambda info: OpFail(info).all_test_cases(),
         'test_suite_psa_crypto_storage_format.current':
diff --git a/tests/suites/test_suite_alignment.function b/tests/suites/test_suite_alignment.function
index 6c98f23..f670331 100644
--- a/tests/suites/test_suite_alignment.function
+++ b/tests/suites/test_suite_alignment.function
@@ -6,7 +6,6 @@
 #if defined(__clang__)
 #pragma clang diagnostic ignored "-Wunreachable-code"
 #endif
-#include <stdio.h>
 
 /*
  * Convert a string of the form "abcd" (case-insensitive) to a uint64_t.
diff --git a/tests/suites/test_suite_constant_time.data b/tests/suites/test_suite_constant_time.data
index 4504aa4..91a25fa 100644
--- a/tests/suites/test_suite_constant_time.data
+++ b/tests/suites/test_suite_constant_time.data
@@ -9,3 +9,129 @@
 # we could get this with 255-bytes plaintext and untruncated SHA-384
 Constant-flow memcpy from offset: large
 ssl_cf_memcpy_offset:100:339:48
+
+mbedtls_ct_memcmp NULL
+mbedtls_ct_memcmp_null
+
+mbedtls_ct_memcmp len 1
+mbedtls_ct_memcmp:-1:1:0
+
+mbedtls_ct_memcmp len 3
+mbedtls_ct_memcmp:-1:3:0
+
+mbedtls_ct_memcmp len 4
+mbedtls_ct_memcmp:-1:4:0
+
+mbedtls_ct_memcmp len 5
+mbedtls_ct_memcmp:-1:5:0
+
+mbedtls_ct_memcmp len 15
+mbedtls_ct_memcmp:-1:15:0
+
+mbedtls_ct_memcmp len 16
+mbedtls_ct_memcmp:-1:16:0
+
+mbedtls_ct_memcmp len 17
+mbedtls_ct_memcmp:-1:17:0
+
+mbedtls_ct_memcmp len 1 different
+mbedtls_ct_memcmp:0:1:0
+
+mbedtls_ct_memcmp len 17 different
+mbedtls_ct_memcmp:0:17:0
+
+mbedtls_ct_memcmp len 17 different 1
+mbedtls_ct_memcmp:1:17:0
+
+mbedtls_ct_memcmp len 17 different 4
+mbedtls_ct_memcmp:4:17:0
+
+mbedtls_ct_memcmp len 17 different 10
+mbedtls_ct_memcmp:10:17:0
+
+mbedtls_ct_memcmp len 17 different 16
+mbedtls_ct_memcmp:16:17:0
+
+mbedtls_ct_memcmp len 1 offset 1 different
+mbedtls_ct_memcmp:0:1:1
+
+mbedtls_ct_memcmp len 17 offset 1 different
+mbedtls_ct_memcmp:0:17:1
+
+mbedtls_ct_memcmp len 17 offset 1 different 1
+mbedtls_ct_memcmp:1:17:1
+
+mbedtls_ct_memcmp len 17 offset 1 different 5
+mbedtls_ct_memcmp:5:17:1
+
+mbedtls_ct_memcmp len 1 offset 1
+mbedtls_ct_memcmp:-1:1:1
+
+mbedtls_ct_memcmp len 1 offset 2
+mbedtls_ct_memcmp:-1:1:2
+
+mbedtls_ct_memcmp len 1 offset 3
+mbedtls_ct_memcmp:-1:1:3
+
+mbedtls_ct_memcmp len 5 offset 1
+mbedtls_ct_memcmp:-1:5:1
+
+mbedtls_ct_memcmp len 5 offset 2
+mbedtls_ct_memcmp:-1:5:2
+
+mbedtls_ct_memcmp len 5 offset 3
+mbedtls_ct_memcmp:-1:5:3
+
+mbedtls_ct_memcmp len 17 offset 1
+mbedtls_ct_memcmp:-1:17:1
+
+mbedtls_ct_memcmp len 17 offset 2
+mbedtls_ct_memcmp:-1:17:2
+
+mbedtls_ct_memcmp len 17 offset 3
+mbedtls_ct_memcmp:-1:17:3
+
+mbedtls_ct_memcpy_if_eq len 1 offset 0
+mbedtls_ct_memcpy_if_eq:1:1:0
+
+mbedtls_ct_memcpy_if_eq len 1 offset 1
+mbedtls_ct_memcpy_if_eq:1:1:1
+
+mbedtls_ct_memcpy_if_eq len 4 offset 0
+mbedtls_ct_memcpy_if_eq:1:1:0
+
+mbedtls_ct_memcpy_if_eq len 4 offset 1
+mbedtls_ct_memcpy_if_eq:1:1:1
+
+mbedtls_ct_memcpy_if_eq len 4 offset 2
+mbedtls_ct_memcpy_if_eq:1:1:2
+
+mbedtls_ct_memcpy_if_eq len 4 offset 3
+mbedtls_ct_memcpy_if_eq:1:1:3
+
+mbedtls_ct_memcpy_if_eq len 15 offset 0
+mbedtls_ct_memcpy_if_eq:1:15:0
+
+mbedtls_ct_memcpy_if_eq len 15 offset 1
+mbedtls_ct_memcpy_if_eq:1:15:1
+
+mbedtls_ct_memcpy_if_eq len 16 offset 0
+mbedtls_ct_memcpy_if_eq:1:16:0
+
+mbedtls_ct_memcpy_if_eq len 16 offset 1
+mbedtls_ct_memcpy_if_eq:1:16:1
+
+mbedtls_ct_memcpy_if_eq len 17 offset 0
+mbedtls_ct_memcpy_if_eq:1:17:0
+
+mbedtls_ct_memcpy_if_eq len 17 offset 1
+mbedtls_ct_memcpy_if_eq:1:17:1
+
+mbedtls_ct_memcpy_if_eq len 0 not eq
+mbedtls_ct_memcpy_if_eq:0:17:0
+
+mbedtls_ct_memcpy_if_eq len 5 offset 1 not eq
+mbedtls_ct_memcpy_if_eq:0:5:1
+
+mbedtls_ct_memcpy_if_eq len 17 offset 3 not eq
+mbedtls_ct_memcpy_if_eq:0:17:3
diff --git a/tests/suites/test_suite_constant_time.function b/tests/suites/test_suite_constant_time.function
index a40149a..14dc8ae 100644
--- a/tests/suites/test_suite_constant_time.function
+++ b/tests/suites/test_suite_constant_time.function
@@ -15,6 +15,108 @@
 #include <test/constant_flow.h>
 /* END_HEADER */
 
+/* BEGIN_CASE */
+void mbedtls_ct_memcmp_null()
+{
+    uint32_t x;
+    TEST_ASSERT(mbedtls_ct_memcmp(&x, NULL, 0) == 0);
+    TEST_ASSERT(mbedtls_ct_memcmp(NULL, &x, 0) == 0);
+    TEST_ASSERT(mbedtls_ct_memcmp(NULL, NULL, 0) == 0);
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mbedtls_ct_memcmp(int same, int size, int offset)
+{
+    uint8_t *a = NULL, *b = NULL;
+    ASSERT_ALLOC(a, size + offset);
+    ASSERT_ALLOC(b, size + offset);
+
+    TEST_CF_SECRET(a + offset, size);
+    TEST_CF_SECRET(b + offset, size);
+
+    /* Construct data that matches, if same == -1, otherwise
+     * same gives the number of bytes (after the initial offset)
+     * that will match; after that it will differ.
+     */
+    for (int i = 0; i < size + offset; i++) {
+        a[i] = i & 0xff;
+        if (same == -1 || (i - offset) < same) {
+            b[i] = a[i];
+        } else {
+            b[i] = (i + 1) & 0xff;
+        }
+    }
+
+    int reference = memcmp(a + offset, b + offset, size);
+    int actual = mbedtls_ct_memcmp(a + offset, b + offset, size);
+    TEST_CF_PUBLIC(a + offset, size);
+    TEST_CF_PUBLIC(b + offset, size);
+
+    if (same == -1 || same >= size) {
+        TEST_ASSERT(reference == 0);
+        TEST_ASSERT(actual == 0);
+    } else {
+        TEST_ASSERT(reference != 0);
+        TEST_ASSERT(actual != 0);
+    }
+exit:
+    mbedtls_free(a);
+    mbedtls_free(b);
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_SOME_SUITES_USE_MAC */
+void mbedtls_ct_memcpy_if_eq(int eq, int size, int offset)
+{
+    uint8_t *src = NULL, *result = NULL, *expected = NULL;
+    ASSERT_ALLOC(src, size + offset);
+    ASSERT_ALLOC(result, size + offset);
+    ASSERT_ALLOC(expected, size + offset);
+
+    for (int i = 0; i < size + offset; i++) {
+        src[i]    = 1;
+        result[i] = 0xff;
+        expected[i] = eq ? 1 : 0xff;
+    }
+
+    int one, secret_eq;
+    TEST_CF_SECRET(&one, sizeof(one));
+    TEST_CF_SECRET(&secret_eq,  sizeof(secret_eq));
+    one = 1;
+    secret_eq = eq;
+
+    mbedtls_ct_memcpy_if_eq(result + offset, src, size, secret_eq, one);
+
+    TEST_CF_PUBLIC(&one, sizeof(one));
+    TEST_CF_PUBLIC(&secret_eq, sizeof(secret_eq));
+
+    ASSERT_COMPARE(expected, size, result + offset, size);
+
+    for (int i = 0; i < size + offset; i++) {
+        src[i]    = 1;
+        result[i] = 0xff;
+        expected[i] = eq ? 1 : 0xff;
+    }
+
+    TEST_CF_SECRET(&one, sizeof(one));
+    TEST_CF_SECRET(&secret_eq,  sizeof(secret_eq));
+    one = 1;
+    secret_eq = eq;
+
+    mbedtls_ct_memcpy_if_eq(result, src + offset, size, secret_eq, one);
+
+    TEST_CF_PUBLIC(&one, sizeof(one));
+    TEST_CF_PUBLIC(&secret_eq, sizeof(secret_eq));
+
+    ASSERT_COMPARE(expected, size, result, size);
+exit:
+    mbedtls_free(src);
+    mbedtls_free(result);
+    mbedtls_free(expected);
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC:MBEDTLS_TEST_HOOKS */
 void ssl_cf_memcpy_offset(int offset_min, int offset_max, int len)
 {
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 9ced77c..c356142 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -5080,6 +5080,22 @@
 depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
 derive_input:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":PSA_SUCCESS:0:UNUSED:"":UNUSED:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
 
+PSA key derivation: TLS12_ECJPAKE_TO_PMS, good input, output too short
+depends_on:PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
+derive_input:PSA_ALG_TLS12_ECJPAKE_TO_PMS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_NONE:"04aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_SUCCESS:0:UNUSED:"":UNUSED:0:UNUSED:"":UNUSED:PSA_KEY_TYPE_NONE:PSA_ERROR_INVALID_ARGUMENT
+
+PSA key derivation: TLS12_ECJPAKE_TO_PMS, input[0]=0x02
+depends_on:PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
+derive_input:PSA_ALG_TLS12_ECJPAKE_TO_PMS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_NONE:"02aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ERROR_INVALID_ARGUMENT:0:UNUSED:"":UNUSED:0:UNUSED:"":UNUSED:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: TLS12_ECJPAKE_TO_PMS, input too short
+depends_on:PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
+derive_input:PSA_ALG_TLS12_ECJPAKE_TO_PMS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_NONE:"04aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ERROR_INVALID_ARGUMENT:0:UNUSED:"":UNUSED:0:UNUSED:"":UNUSED:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: TLS12_ECJPAKE_TO_PMS, input too long
+depends_on:PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
+derive_input:PSA_ALG_TLS12_ECJPAKE_TO_PMS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_NONE:"04aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ERROR_INVALID_ARGUMENT:0:UNUSED:"":UNUSED:0:UNUSED:"":UNUSED:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
 PSA key derivation over capacity: HKDF
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
 derive_over_capacity:PSA_ALG_HKDF(PSA_ALG_SHA_256)
diff --git a/tests/suites/test_suite_psa_crypto_metadata.data b/tests/suites/test_suite_psa_crypto_metadata.data
index bf5f04e..bbd5017 100644
--- a/tests/suites/test_suite_psa_crypto_metadata.data
+++ b/tests/suites/test_suite_psa_crypto_metadata.data
@@ -118,6 +118,10 @@
 depends_on:PSA_WANT_ALG_XTS:MBEDTLS_CIPHER_C
 cipher_algorithm:PSA_ALG_XTS:0
 
+Cipher: CCM*
+depends_on:PSA_WANT_ALG_CCM_STAR_NO_TAG
+cipher_algorithm:PSA_ALG_CCM_STAR_NO_TAG:ALG_IS_STREAM_CIPHER
+
 AEAD: CCM-AES-128
 depends_on:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_CCM
 aead_algorithm:PSA_ALG_CCM:ALG_IS_AEAD_ON_BLOCK_CIPHER:16:PSA_KEY_TYPE_AES:128
@@ -286,6 +290,10 @@
 depends_on:PSA_WANT_ALG_HKDF_EXPAND:PSA_WANT_ALG_SHA_384
 key_derivation_algorithm:PSA_ALG_HKDF_EXPAND( PSA_ALG_SHA_384 ):ALG_IS_HKDF_EXPAND
 
+Key derivation: TLS1.2 ECJPAKE-to-PMS
+depends_on:PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
+key_derivation_algorithm:PSA_ALG_TLS12_ECJPAKE_TO_PMS:0
+
 Key derivation: TLS 1.2 PRF using SHA-256
 depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF
 key_derivation_algorithm:PSA_ALG_TLS12_PRF( PSA_ALG_SHA_256 ):ALG_IS_TLS12_PRF
@@ -339,6 +347,12 @@
 Key type: secret for key derivation
 key_type:PSA_KEY_TYPE_DERIVE:KEY_TYPE_IS_UNSTRUCTURED
 
+Key type: password
+key_type:PSA_KEY_TYPE_PASSWORD:KEY_TYPE_IS_UNSTRUCTURED
+
+Key type: password hash
+key_type:PSA_KEY_TYPE_PASSWORD_HASH:KEY_TYPE_IS_UNSTRUCTURED
+
 Block cipher key type: AES
 depends_on:PSA_WANT_KEY_TYPE_AES
 block_cipher_key_type:PSA_KEY_TYPE_AES:16
diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data
index 3059e7f..1848c17 100644
--- a/tests/suites/test_suite_ssl.data
+++ b/tests/suites/test_suite_ssl.data
@@ -114,58 +114,59 @@
 move_handshake_to_state:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_SERVER_HELLO:1
 
 Test moving clients handshake to state: SERVER_CERTIFICATE
+depends_on:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 move_handshake_to_state:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_HANDSHAKE_OVER:1
 
 Test moving servers handshake to state: HELLO_REQUEST
@@ -175,61 +176,63 @@
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_CLIENT_HELLO:1
 
 Test moving servers handshake to state: SERVER_HELLO
+depends_on:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_SERVER_HELLO:1
 
 Test moving servers handshake to state: SERVER_CERTIFICATE
+depends_on:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 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
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_HANDSHAKE_OVER:1
 
 Negative test moving clients ssl to state: VERIFY_REQUEST_SENT
@@ -257,7 +260,7 @@
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY:1
 
 Handshake, tls1_2
-depends_on:MBEDTLS_SSL_PROTO_TLS1_2
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 handshake_version:0:MBEDTLS_SSL_VERSION_TLS1_2:MBEDTLS_SSL_VERSION_TLS1_2:MBEDTLS_SSL_VERSION_TLS1_2:MBEDTLS_SSL_VERSION_TLS1_2:MBEDTLS_SSL_VERSION_TLS1_2
 
 Handshake, tls1_3
@@ -289,7 +292,7 @@
 handshake_psk_cipher:"TLS-PSK-WITH-AES-128-CBC-SHA":MBEDTLS_PK_RSA:"abc123":0
 
 DTLS Handshake, tls1_2
-depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_PROTO_DTLS
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_PROTO_DTLS:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 handshake_version:1:MBEDTLS_SSL_VERSION_TLS1_2:MBEDTLS_SSL_VERSION_TLS1_2:MBEDTLS_SSL_VERSION_TLS1_2:MBEDTLS_SSL_VERSION_TLS1_2:MBEDTLS_SSL_VERSION_TLS1_2
 
 DTLS Handshake, ECDHE-RSA-WITH-AES-256-GCM-SHA384
@@ -329,7 +332,7 @@
 handshake_fragmentation:MBEDTLS_SSL_MAX_FRAG_LEN_1024:0:1
 
 Handshake min/max version check, all -> 1.2
-depends_on:MBEDTLS_SSL_PROTO_TLS1_2
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
 handshake_version:0:MBEDTLS_SSL_VERSION_UNKNOWN:MBEDTLS_SSL_VERSION_UNKNOWN:MBEDTLS_SSL_VERSION_UNKNOWN:MBEDTLS_SSL_VERSION_UNKNOWN:MBEDTLS_SSL_VERSION_TLS1_2
 
 Handshake, select RSA-WITH-AES-256-CBC-SHA256, non-opaque
@@ -654,99 +657,99 @@
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_4096:MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE:"TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384"
 
 DTLS no legacy renegotiation with MFL=512, RSA-WITH-AES-128-CCM
-depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C
+depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C:MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_512:MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION:"TLS-RSA-WITH-AES-128-CCM"
 
 DTLS no legacy renegotiation with MFL=1024, RSA-WITH-AES-128-CCM
-depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C
+depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C:MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_1024:MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION:"TLS-RSA-WITH-AES-128-CCM"
 
 DTLS no legacy renegotiation with MFL=2048, RSA-WITH-AES-128-CCM
-depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C
+depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C:MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_2048:MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION:"TLS-RSA-WITH-AES-128-CCM"
 
 DTLS no legacy renegotiation with MFL=4096, RSA-WITH-AES-128-CCM
-depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C
+depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C:MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_4096:MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION:"TLS-RSA-WITH-AES-128-CCM"
 
 DTLS legacy allow renegotiation with MFL=512, RSA-WITH-AES-128-CCM
-depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C
+depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C:MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_512:MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION:"TLS-RSA-WITH-AES-128-CCM"
 
 DTLS legacy allow renegotiation with MFL=1024, RSA-WITH-AES-128-CCM
-depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C
+depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C:MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_1024:MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION:"TLS-RSA-WITH-AES-128-CCM"
 
 DTLS legacy allow renegotiation with MFL=2048, RSA-WITH-AES-128-CCM
-depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C
+depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C:MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_2048:MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION:"TLS-RSA-WITH-AES-128-CCM"
 
 DTLS legacy allow renegotiation with MFL=4096, RSA-WITH-AES-128-CCM
-depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C
+depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C:MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_4096:MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION:"TLS-RSA-WITH-AES-128-CCM"
 
 DTLS legacy break handshake renegotiation with MFL=512, RSA-WITH-AES-128-CCM
-depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C
+depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C:MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_512:MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE:"TLS-RSA-WITH-AES-128-CCM"
 
 DTLS legacy break handshake renegotiation with MFL=1024, RSA-WITH-AES-128-CCM
-depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C
+depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C:MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_1024:MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE:"TLS-RSA-WITH-AES-128-CCM"
 
 DTLS legacy break handshake renegotiation with MFL=2048, RSA-WITH-AES-128-CCM
-depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C
+depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C:MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_2048:MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE:"TLS-RSA-WITH-AES-128-CCM"
 
 DTLS legacy break handshake renegotiation with MFL=4096, RSA-WITH-AES-128-CCM
-depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C
+depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C:MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_4096:MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE:"TLS-RSA-WITH-AES-128-CCM"
 
 DTLS no legacy renegotiation with MFL=512, DHE-RSA-WITH-AES-256-CBC-SHA256
-depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
+depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_512:MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION:"TLS-DHE-RSA-WITH-AES-256-CBC-SHA256"
 
 DTLS no legacy renegotiation with MFL=1024, DHE-RSA-WITH-AES-256-CBC-SHA256
-depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
+depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_1024:MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION:"TLS-DHE-RSA-WITH-AES-256-CBC-SHA256"
 
 DTLS no legacy renegotiation with MFL=2048, DHE-RSA-WITH-AES-256-CBC-SHA256
-depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
+depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_2048:MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION:"TLS-DHE-RSA-WITH-AES-256-CBC-SHA256"
 
 DTLS no legacy renegotiation with MFL=4096, DHE-RSA-WITH-AES-256-CBC-SHA256
-depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
+depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_4096:MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION:"TLS-DHE-RSA-WITH-AES-256-CBC-SHA256"
 
 DTLS legacy allow renegotiation with MFL=512, DHE-RSA-WITH-AES-256-CBC-SHA256
-depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
+depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_512:MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION:"TLS-DHE-RSA-WITH-AES-256-CBC-SHA256"
 
 DTLS legacy allow renegotiation with MFL=1024, DHE-RSA-WITH-AES-256-CBC-SHA256
-depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
+depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_1024:MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION:"TLS-DHE-RSA-WITH-AES-256-CBC-SHA256"
 
 DTLS legacy allow renegotiation with MFL=2048, DHE-RSA-WITH-AES-256-CBC-SHA256
-depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
+depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_2048:MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION:"TLS-DHE-RSA-WITH-AES-256-CBC-SHA256"
 
 DTLS legacy allow renegotiation with MFL=4096, DHE-RSA-WITH-AES-256-CBC-SHA256
-depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
+depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_4096:MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION:"TLS-DHE-RSA-WITH-AES-256-CBC-SHA256"
 
 DTLS legacy break handshake renegotiation with MFL=512, DHE-RSA-WITH-AES-256-CBC-SHA256
-depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
+depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_512:MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE:"TLS-DHE-RSA-WITH-AES-256-CBC-SHA256"
 
 DTLS legacy break handshake renegotiation with MFL=1024, DHE-RSA-WITH-AES-256-CBC-SHA256
-depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
+depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_1024:MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE:"TLS-DHE-RSA-WITH-AES-256-CBC-SHA256"
 
 DTLS legacy break handshake renegotiation with MFL=2048, DHE-RSA-WITH-AES-256-CBC-SHA256
-depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
+depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_2048:MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE:"TLS-DHE-RSA-WITH-AES-256-CBC-SHA256"
 
 DTLS legacy break handshake renegotiation with MFL=4096, DHE-RSA-WITH-AES-256-CBC-SHA256
-depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
+depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
 resize_buffers_renegotiate_mfl:MBEDTLS_SSL_MAX_FRAG_LEN_4096:MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE:"TLS-DHE-RSA-WITH-AES-256-CBC-SHA256"
 
 SSL DTLS replay: initial state, seqnum 0
@@ -3509,11 +3512,11 @@
 cid_sanity:
 
 Raw key agreement: nominal
-depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 raw_key_agreement_fail:0
 
 Raw key agreement: bad server key
-depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 raw_key_agreement_fail:1
 
 Force a bad session id length
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index 15ec5be..1d182e0 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -17,6 +17,11 @@
 #include <constant_time_internal.h>
 #include <test/constant_flow.h>
 
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
+    defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
+#define MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
+#endif
 enum {
 #define MBEDTLS_SSL_TLS1_3_LABEL(name, string)   \
     tls13_label_ ## name,
@@ -5018,7 +5023,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_ECP_C */
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_ECP_C:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY */
 void handshake_version(int dtls, int client_min_version, int client_max_version,
                        int server_min_version, int server_max_version,
                        int expected_negotiated_version)
@@ -5129,7 +5134,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_ECP_C */
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_ECP_C:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY */
 void app_data_tls(int mfl, int cli_msg_len, int srv_msg_len,
                   int expected_cli_fragments,
                   int expected_srv_fragments)
@@ -5141,7 +5146,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:!MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA */
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:!MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY */
 void app_data_dtls(int mfl, int cli_msg_len, int srv_msg_len,
                    int expected_cli_fragments,
                    int expected_srv_fragments)
@@ -5153,7 +5158,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:!MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS:MBEDTLS_SSL_RENEGOTIATION:MBEDTLS_SSL_CONTEXT_SERIALIZATION:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA */
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:!MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS:MBEDTLS_SSL_RENEGOTIATION:MBEDTLS_SSL_CONTEXT_SERIALIZATION:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY */
 void handshake_serialization()
 {
     handshake_test_options options;
@@ -5169,7 +5174,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:!MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_DEBUG_C:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA */
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:!MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_DEBUG_C:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
 void handshake_fragmentation(int mfl,
                              int expected_srv_hs_fragmentation,
                              int expected_cli_hs_fragmentation)
@@ -5208,7 +5213,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:!MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS:MBEDTLS_SSL_RENEGOTIATION:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA */
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:!MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS:MBEDTLS_SSL_RENEGOTIATION:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY */
 void renegotiation(int legacy_renegotiation)
 {
     handshake_test_options options;
@@ -5251,7 +5256,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:!MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH:MBEDTLS_SSL_CONTEXT_SERIALIZATION:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA */
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:!MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH:MBEDTLS_SSL_CONTEXT_SERIALIZATION:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY */
 void resize_buffers_serialize_mfl(int mfl)
 {
     test_resize_buffers(mfl, 0, MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION, 1, 1,
@@ -5262,7 +5267,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:!MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH:MBEDTLS_SSL_RENEGOTIATION:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA */
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:!MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH:MBEDTLS_SSL_RENEGOTIATION:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY */
 void resize_buffers_renegotiate_mfl(int mfl, int legacy_renegotiation,
                                     char *cipher)
 {
diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function
index a21ad47..03b9bae 100644
--- a/tests/suites/test_suite_x509write.function
+++ b/tests/suites/test_suite_x509write.function
@@ -345,7 +345,7 @@
 
     issuer_key_type = mbedtls_pk_get_type(&issuer_key);
 
-#if defined(MBEDTLS_RSA_C)
+#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
     /* For RSA PK contexts, create a copy as an alternative RSA context. */
     if (pk_wrap == 1 && issuer_key_type == MBEDTLS_PK_RSA) {
         TEST_ASSERT(mbedtls_pk_setup_rsa_alt(&issuer_key_alt,