Merge pull request #7282 from gilles-peskine-arm/changelog-6567-psa_key_derivation_abort-no-other_secret

Add changelog entry for a bug in non-PAKE code fixed during PAKE work
diff --git a/.travis.yml b/.travis.yml
index cdb79d1..3d86681 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -89,16 +89,14 @@
           packages:
           - gcc
       script:
-        # Do a manual build+test sequence rather than using all.sh, because
-        # there's no all.sh component that does what we want. We should set
-        # CFLAGS for arm64 host CC.
+        # Do a manual build+test sequence rather than using all.sh.
+        #
+        # On Arm64 host of Travis CI, the time of `test_full_cmake_*` exceeds
+        # limitation of Travis CI. Base on `test_full_cmake_*`, we removed
+        # `ssl-opt.sh` and GnuTLS compat.sh here to meet the time limitation.
         - scripts/config.py full
-        - scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
-        - scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
-        - scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
-        - scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
         - make generated_files
-        - make CFLAGS='-march=armv8-a+crypto -O3 -Werror -fsanitize=address,undefined -fno-sanitize-recover=all' LDFLAGS='-Werror -fsanitize=address,undefined -fno-sanitize-recover=all'
+        - make CFLAGS='-O3 -Werror -fsanitize=address,undefined -fno-sanitize-recover=all' LDFLAGS='-Werror -fsanitize=address,undefined -fno-sanitize-recover=all'
         - make test
         - programs/test/selftest
         - tests/scripts/test_psa_constant_names.py
@@ -117,16 +115,14 @@
           - clang
           - gnutls-bin
       script:
-        # Do a manual build+test sequence rather than using all.sh, because
-        # there's no all.sh component that does what we want. We should set
-        # CFLAGS for arm64 host CC.
+        # Do a manual build+test sequence rather than using all.sh.
+        #
+        # On Arm64 host of Travis CI, the time of `test_full_cmake_*` exceeds
+        # limitation of Travis CI. Base on `test_full_cmake_*`, we removed
+        # `ssl-opt.sh` and OpenSSl compat.sh here to meet the time limitation.
         - scripts/config.py full
-        - scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
-        - scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
-        - scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
-        - scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
         - make generated_files
-        - make CC=clang CFLAGS='-march=armv8-a+crypto -O3 -Werror -fsanitize=address,undefined -fno-sanitize-recover=all' LDFLAGS='-Werror -fsanitize=address,undefined -fno-sanitize-recover=all'
+        - make CC=clang CFLAGS='-O3 -Werror -fsanitize=address,undefined -fno-sanitize-recover=all' LDFLAGS='-Werror -fsanitize=address,undefined -fno-sanitize-recover=all'
         # GnuTLS supports CAMELLIA but compat.sh doesn't properly enable it.
         - tests/compat.sh -p GnuTLS -e 'CAMELLIA'
         - tests/scripts/travis-log-failure.sh
diff --git a/ChangeLog b/ChangeLog
index 1404d36..639c8e9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -106,11 +106,11 @@
    * Fix potential heap buffer overread and overwrite in DTLS if
      MBEDTLS_SSL_DTLS_CONNECTION_ID is enabled and
      MBEDTLS_SSL_CID_IN_LEN_MAX > 2 * MBEDTLS_SSL_CID_OUT_LEN_MAX.
-   * An adversary with access to precise enough information about memory
-     accesses (typically, an untrusted operating system attacking a secure
-     enclave) could recover an RSA private key after observing the victim
-     performing a single private-key operation if the window size used for the
-     exponentiation was 3 or smaller. Found and reported by Zili KOU,
+   * Fix an issue where an adversary with access to precise enough information
+     about memory accesses (typically, an untrusted operating system attacking
+     a secure enclave) could recover an RSA private key after observing the
+     victim performing a single private-key operation if the window size used
+     for the exponentiation was 3 or smaller. Found and reported by Zili KOU,
      Wenjian HE, Sharad Sinha, and Wei ZHANG. See "Cache Side-channel Attacks
      and Defenses of the Sliding Window Algorithm in TEEs" - Design, Automation
      and Test in Europe 2023.
@@ -969,16 +969,17 @@
      signature, allowing the recovery of the private key after observing a
      large number of signature operations. This completes a partial fix in
      Mbed TLS 2.20.0.
-   * An adversary with access to precise enough information about memory
-     accesses (typically, an untrusted operating system attacking a secure
-     enclave) could recover an RSA private key after observing the victim
-     performing a single private-key operation. Found and reported by
+   * Fix an issue where an adversary with access to precise enough information
+     about memory accesses (typically, an untrusted operating system attacking
+     a secure enclave) could recover an RSA private key after observing the
+     victim performing a single private-key operation. Found and reported by
      Zili KOU, Wenjian HE, Sharad Sinha, and Wei ZHANG.
-   * An adversary with access to precise enough timing information (typically, a
-     co-located process) could recover a Curve25519 or Curve448 static ECDH key
-     after inputting a chosen public key and observing the victim performing the
-     corresponding private-key operation. Found and reported by Leila Batina,
-     Lukas Chmielewski, Björn Haase, Niels Samwel and Peter Schwabe.
+   * Fix an issue where an adversary with access to precise enough timing
+     information (typically, a co-located process) could recover a Curve25519
+     or Curve448 static ECDH key after inputting a chosen public key and
+     observing the victim performing the corresponding private-key operation.
+     Found and reported by Leila Batina, Lukas Chmielewski, Björn Haase, Niels
+     Samwel and Peter Schwabe.
 
 Bugfix
    * Fix premature fopen() call in mbedtls_entropy_write_seed_file which may
diff --git a/ChangeLog.d/driver-only-ecdsa.txt b/ChangeLog.d/driver-only-ecdsa.txt
new file mode 100644
index 0000000..645a723
--- /dev/null
+++ b/ChangeLog.d/driver-only-ecdsa.txt
@@ -0,0 +1,7 @@
+Features
+   * When a PSA driver for ECDSA is present, it is now possible to disable
+     MBEDTLS_ECDSA_C in the build in order to save code size. For PK, X.509
+     and TLS to fully work, this requires MBEDTLS_USE_PSA_CRYPTO to be enabled.
+     Restartable/interruptible ECDSA operations in PK, X.509 and TLS are not
+     supported in those builds yet, as driver support for interruptible ECDSA
+     operations is not present yet.
diff --git a/ChangeLog.d/ec_jpake_driver_dispatch.txt b/ChangeLog.d/ec_jpake_driver_dispatch.txt
new file mode 100644
index 0000000..3439296
--- /dev/null
+++ b/ChangeLog.d/ec_jpake_driver_dispatch.txt
@@ -0,0 +1,3 @@
+Features
+   * Add a driver dispatch layer for EC J-PAKE, enabling alternative
+     implementations of EC J-PAKE through the driver entry points.
diff --git a/ChangeLog.d/fix-jpake-user-peer.txt b/ChangeLog.d/fix-jpake-user-peer.txt
new file mode 100644
index 0000000..e027fc3
--- /dev/null
+++ b/ChangeLog.d/fix-jpake-user-peer.txt
@@ -0,0 +1,4 @@
+Bugfix
+   * Allow setting user and peer identifiers for EC J-PAKE operation
+     instead of role in PAKE PSA Crypto API as described in the specification.
+     This is a partial fix that allows only "client" and "server" identifiers.
diff --git a/ChangeLog.d/mbedtls_ssl_read_undefined_behavior.txt b/ChangeLog.d/mbedtls_ssl_read_undefined_behavior.txt
new file mode 100644
index 0000000..1f2c563
--- /dev/null
+++ b/ChangeLog.d/mbedtls_ssl_read_undefined_behavior.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Fix undefined behavior in mbedtls_ssl_read() and mbedtls_ssl_write() if
+     len argument is 0 and buffer is NULL.
diff --git a/ChangeLog.d/pkcs7-parser.txt b/ChangeLog.d/pkcs7-parser.txt
new file mode 100644
index 0000000..b60d187
--- /dev/null
+++ b/ChangeLog.d/pkcs7-parser.txt
@@ -0,0 +1,15 @@
+Features
+   * Added partial support for parsing the PKCS #7 Cryptographic Message
+     Syntax, as defined in RFC 2315. Currently, support is limited to the
+     following:
+     - Only the signed-data content type, version 1 is supported.
+     - Only DER encoding is supported.
+     - Only a single digest algorithm per message is supported.
+     - Certificates must be in X.509 format. A message must have either 0
+       or 1 certificates.
+     - There is no support for certificate revocation lists.
+     - The authenticated and unauthenticated attribute fields of SignerInfo
+       must be empty.
+     Many thanks to Daniel Axtens, Nayna Jain, and Nick Child from IBM for
+     contributing this feature, and to Demi-Marie Obenour for contributing
+     various improvements, tests and bug fixes.
diff --git a/README.md b/README.md
index f4bf4e1..288e692 100644
--- a/README.md
+++ b/README.md
@@ -61,10 +61,11 @@
 The following tools are required:
 
 * Perl, for some library source files and for Visual Studio build files.
-* Python 3 and some Python packages, for some library source files, sample programs and test data. To install the necessary packages, run
+* Python 3 and some Python packages, for some library source files, sample programs and test data. To install the necessary packages, run:
     ```
-    python -m pip install -r scripts/basic.requirements.txt
+    python3 -m pip install --user -r scripts/basic.requirements.txt
     ```
+    Depending on your Python installation, you may need to invoke `python` instead of `python3`. To install the packages system-wide, omit the `--user` option.
 * A C compiler for the host platform, for some test data.
 
 If you are cross-compiling, you must set the `CC` environment variable to a C compiler for the host platform when generating the configuration-independent files.
diff --git a/docs/getting_started.md b/docs/getting_started.md
deleted file mode 100644
index 507afa1..0000000
--- a/docs/getting_started.md
+++ /dev/null
@@ -1,962 +0,0 @@
-## Getting started with Mbed TLS
-
-### What is Mbed TLS?
-
-Mbed TLS is an open source cryptographic library that supports a wide range of
-cryptographic operations, including:
-* Key management
-* Hashing
-* Symmetric cryptography
-* Asymmetric cryptography
-* Message authentication (MAC)
-* Key generation and derivation
-* Authenticated encryption with associated data (AEAD)
-
-Mbed TLS provides a reference implementation of the cryptography interface of
-the Arm Platform Security Architecture (PSA). It is written in portable C.
-
-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.
-
-### Using Mbed TLS
-
-* [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)
-* [Hashing a message](#hashing-a-message)
-* [Deriving a new key from an existing key](#deriving-a-new-key-from-an-existing-key)
-* [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 PSA Crypto API](#more-about-the-psa-crypto-api)
-
-### Getting the Mbed TLS library
-
-Mbed TLS releases are available in the [public GitHub repository](https://github.com/Mbed-TLS/mbedtls).
-
-### Building the Mbed TLS library
-
-**Prerequisites to building the library with the provided makefiles:**
-* GNU Make.
-* 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.
-
-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`.
-
-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 PSA Crypto API
-
-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 PSA, you need to first
-import it. The import operation returns the identifier of the key for use
-with other function calls.
-
-**Prerequisites to importing keys:**
-* Initialize the library with a successful call to `psa_crypto_init()`.
-
-This example shows how to import a key:
-```C
-void import_a_key(const uint8_t *key, size_t key_len)
-{
-    psa_status_t status;
-    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    psa_key_id_t key_id;
-
-    printf("Import an AES key...\t");
-    fflush(stdout);
-
-    /* Initialize PSA Crypto */
-    status = psa_crypto_init();
-    if (status != PSA_SUCCESS) {
-        printf("Failed to initialize PSA Crypto\n");
-        return;
-    }
-
-    /* Set key attributes */
-    psa_set_key_usage_flags(&attributes, 0);
-    psa_set_key_algorithm(&attributes, 0);
-    psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
-    psa_set_key_bits(&attributes, 128);
-
-    /* Import the key */
-    status = psa_import_key(&attributes, key, key_len, &key_id);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to import key\n");
-        return;
-    }
-    printf("Imported a key\n");
-
-    /* Free the attributes */
-    psa_reset_key_attributes(&attributes);
-
-    /* Destroy the key */
-    psa_destroy_key(key_id);
-
-    mbedtls_psa_crypto_free();
-}
-```
-
-### Signing a message using RSA
-
-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()`.
-* Have a valid key with appropriate attributes set:
-    * Usage flag `PSA_KEY_USAGE_SIGN_HASH` to allow signing.
-    * Usage flag `PSA_KEY_USAGE_VERIFY_HASH` to allow signature verification.
-    * Algorithm set to the desired signature algorithm.
-
-This example shows how to sign a hash that has already been calculated:
-```C
-void sign_a_message_using_rsa(const uint8_t *key, size_t key_len)
-{
-    psa_status_t status;
-    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    uint8_t hash[32] = {0x50, 0xd8, 0x58, 0xe0, 0x98, 0x5e, 0xcc, 0x7f,
-                        0x60, 0x41, 0x8a, 0xaf, 0x0c, 0xc5, 0xab, 0x58,
-                        0x7f, 0x42, 0xc2, 0x57, 0x0a, 0x88, 0x40, 0x95,
-                        0xa9, 0xe8, 0xcc, 0xac, 0xd0, 0xf6, 0x54, 0x5c};
-    uint8_t signature[PSA_SIGNATURE_MAX_SIZE] = {0};
-    size_t signature_length;
-    psa_key_id_t key_id;
-
-    printf("Sign a message...\t");
-    fflush(stdout);
-
-    /* Initialize PSA Crypto */
-    status = psa_crypto_init();
-    if (status != PSA_SUCCESS) {
-        printf("Failed to initialize PSA Crypto\n");
-        return;
-    }
-
-    /* Set key attributes */
-    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
-    psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_SIGN_RAW);
-    psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
-    psa_set_key_bits(&attributes, 1024);
-
-    /* Import the key */
-    status = psa_import_key(&attributes, key, key_len, &key_id);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to import key\n");
-        return;
-    }
-
-    /* Sign message using the key */
-    status = psa_sign_hash(key_id, PSA_ALG_RSA_PKCS1V15_SIGN_RAW,
-                           hash, sizeof(hash),
-                           signature, sizeof(signature),
-                           &signature_length);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to sign\n");
-        return;
-    }
-
-    printf("Signed a message\n");
-
-    /* Free the attributes */
-    psa_reset_key_attributes(&attributes);
-
-    /* Destroy the key */
-    psa_destroy_key(key_id);
-
-    mbedtls_psa_crypto_free();
-}
-```
-
-### Using symmetric 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.
-
-**To encrypt a message with a symmetric cipher:**
-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.
-
-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)
-{
-    enum {
-        block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES),
-    };
-    psa_status_t status;
-    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
-    uint8_t plaintext[block_size] = SOME_PLAINTEXT;
-    uint8_t iv[block_size];
-    size_t iv_len;
-    uint8_t output[block_size];
-    size_t output_len;
-    psa_key_id_t key_id;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
-
-    printf("Encrypt with cipher...\t");
-    fflush(stdout);
-
-    /* Initialize PSA Crypto */
-    status = psa_crypto_init();
-    if (status != PSA_SUCCESS)
-    {
-        printf("Failed to initialize PSA Crypto\n");
-        return;
-    }
-
-    /* Import a key */
-    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
-    psa_set_key_algorithm(&attributes, alg);
-    psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
-    psa_set_key_bits(&attributes, 128);
-    status = psa_import_key(&attributes, key, key_len, &key_id);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to import a key\n");
-        return;
-    }
-    psa_reset_key_attributes(&attributes);
-
-    /* Encrypt the plaintext */
-    status = psa_cipher_encrypt_setup(&operation, key_id, alg);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to begin cipher operation\n");
-        return;
-    }
-    status = psa_cipher_generate_iv(&operation, iv, sizeof(iv), &iv_len);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to generate IV\n");
-        return;
-    }
-    status = psa_cipher_update(&operation, plaintext, sizeof(plaintext),
-                               output, sizeof(output), &output_len);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to update cipher operation\n");
-        return;
-    }
-    status = psa_cipher_finish(&operation, output + output_len,
-                               sizeof(output) - output_len, &output_len);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to finish cipher operation\n");
-        return;
-    }
-    printf("Encrypted plaintext\n");
-
-    /* Clean up cipher operation context */
-    psa_cipher_abort(&operation);
-
-    /* Destroy the key */
-    psa_destroy_key(key_id);
-
-    mbedtls_psa_crypto_free();
-}
-```
-
-**To decrypt a message with a symmetric cipher:**
-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_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.
-
-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)
-{
-    enum {
-        block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES),
-    };
-    psa_status_t status;
-    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
-    uint8_t ciphertext[block_size] = SOME_CIPHERTEXT;
-    uint8_t iv[block_size] = ENCRYPTED_WITH_IV;
-    uint8_t output[block_size];
-    size_t output_len;
-    psa_key_id_t key_id;
-
-    printf("Decrypt with cipher...\t");
-    fflush(stdout);
-
-    /* Initialize PSA Crypto */
-    status = psa_crypto_init();
-    if (status != PSA_SUCCESS)
-    {
-        printf("Failed to initialize PSA Crypto\n");
-        return;
-    }
-
-    /* Import a key */
-    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);
-    psa_set_key_algorithm(&attributes, alg);
-    psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
-    psa_set_key_bits(&attributes, 128);
-    status = psa_import_key(&attributes, key, key_len, &key_id);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to import a key\n");
-        return;
-    }
-    psa_reset_key_attributes(&attributes);
-
-    /* Decrypt the ciphertext */
-    status = psa_cipher_decrypt_setup(&operation, key_id, alg);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to begin cipher operation\n");
-        return;
-    }
-    status = psa_cipher_set_iv(&operation, iv, sizeof(iv));
-    if (status != PSA_SUCCESS) {
-        printf("Failed to set IV\n");
-        return;
-    }
-    status = psa_cipher_update(&operation, ciphertext, sizeof(ciphertext),
-                               output, sizeof(output), &output_len);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to update cipher operation\n");
-        return;
-    }
-    status = psa_cipher_finish(&operation, output + output_len,
-                               sizeof(output) - output_len, &output_len);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to finish cipher operation\n");
-        return;
-    }
-    printf("Decrypted ciphertext\n");
-
-    /* Clean up cipher operation context */
-    psa_cipher_abort(&operation);
-
-    /* Destroy the key */
-    psa_destroy_key(key_id);
-
-    mbedtls_psa_crypto_free();
-}
-```
-
-#### 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()`.
-
-The call to `psa_cipher_abort()` frees any resources associated with the
-operation, except for the operation structure itself.
-
-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.
-
-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.
-
-### Hashing a message
-
-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. 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.
-
-This example shows how to calculate the SHA-256 hash of a message:
-```c
-    psa_status_t status;
-    psa_algorithm_t alg = PSA_ALG_SHA_256;
-    psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
-    unsigned char input[] = { 'a', 'b', 'c' };
-    unsigned char actual_hash[PSA_HASH_MAX_SIZE];
-    size_t actual_hash_len;
-
-    printf("Hash a message...\t");
-    fflush(stdout);
-
-    /* Initialize PSA Crypto */
-    status = psa_crypto_init();
-    if (status != PSA_SUCCESS) {
-        printf("Failed to initialize PSA Crypto\n");
-        return;
-    }
-
-    /* Compute hash of message  */
-    status = psa_hash_setup(&operation, alg);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to begin hash operation\n");
-        return;
-    }
-    status = psa_hash_update(&operation, input, sizeof(input));
-    if (status != PSA_SUCCESS) {
-        printf("Failed to update hash operation\n");
-        return;
-    }
-    status = psa_hash_finish(&operation, actual_hash, sizeof(actual_hash),
-                             &actual_hash_len);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to finish hash operation\n");
-        return;
-    }
-
-    printf("Hashed a message\n");
-
-    /* Clean up hash operation context */
-    psa_hash_abort(&operation);
-
-    mbedtls_psa_crypto_free();
-```
-
-This example shows how to verify the SHA-256 hash of a message:
-```c
-    psa_status_t status;
-    psa_algorithm_t alg = PSA_ALG_SHA_256;
-    psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
-    unsigned char input[] = { 'a', 'b', 'c' };
-    unsigned char expected_hash[] = {
-        0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
-        0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
-        0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
-    };
-    size_t expected_hash_len = PSA_HASH_LENGTH(alg);
-
-    printf("Verify a hash...\t");
-    fflush(stdout);
-
-    /* Initialize PSA Crypto */
-    status = psa_crypto_init();
-    if (status != PSA_SUCCESS) {
-        printf("Failed to initialize PSA Crypto\n");
-        return;
-    }
-
-    /* Verify message hash */
-    status = psa_hash_setup(&operation, alg);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to begin hash operation\n");
-        return;
-    }
-    status = psa_hash_update(&operation, input, sizeof(input));
-    if (status != PSA_SUCCESS) {
-        printf("Failed to update hash operation\n");
-        return;
-    }
-    status = psa_hash_verify(&operation, expected_hash, expected_hash_len);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to verify hash\n");
-        return;
-    }
-
-    printf("Verified a hash\n");
-
-    /* Clean up hash operation context */
-    psa_hash_abort(&operation);
-
-    mbedtls_psa_crypto_free();
-```
-
-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.
-
-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.
-
-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.
-
-### Generating a random value
-
-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>
-
-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 };
-
-    printf("Generate random...\t");
-    fflush(stdout);
-
-    /* Initialize PSA Crypto */
-    status = psa_crypto_init();
-    if (status != PSA_SUCCESS) {
-        printf("Failed to initialize PSA Crypto\n");
-        return;
-    }
-
-    status = psa_generate_random(random, sizeof(random));
-    if (status != PSA_SUCCESS) {
-        printf("Failed to generate a random value\n");
-        return;
-    }
-
-    printf("Generated random data\n");
-
-    /* Clean up */
-    mbedtls_psa_crypto_free();
-```
-
-### Deriving a new key from an existing key
-
-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.
-
-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()`.
-* Use a key with the appropriate attributes set:
-    * Usage flags set for key derivation (`PSA_KEY_USAGE_DERIVE`)
-    * Key type set to `PSA_KEY_TYPE_DERIVE`.
-    * Algorithm set to a key derivation algorithm
-      (for example, `PSA_ALG_HKDF(PSA_ALG_SHA_256)`).
-
-**To derive a new AES-CTR 128-bit encryption key into a given key slot using HKDF
-with a given key, salt and info:**
-
-1. Set up the key derivation context using the `psa_key_derivation_setup()`
-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. 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.
-1. Derive the key by calling `psa_key_derivation_output_key()`.
-1. Clean up the key derivation context.
-
-At this point, the derived key slot holds a new 128-bit AES-CTR encryption key
-derived from the key, salt and info provided:
-```C
-    psa_status_t status;
-    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    static const unsigned char key[] = {
-        0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-        0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-        0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-        0x0b };
-    static const unsigned char salt[] = {
-        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
-        0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c };
-    static const unsigned char info[] = {
-        0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
-        0xf7, 0xf8, 0xf9 };
-    psa_algorithm_t alg = PSA_ALG_HKDF(PSA_ALG_SHA_256);
-    psa_key_derivation_operation_t operation =
-        PSA_KEY_DERIVATION_OPERATION_INIT;
-    size_t derived_bits = 128;
-    size_t capacity = PSA_BITS_TO_BYTES(derived_bits);
-    psa_key_id_t base_key;
-    psa_key_id_t derived_key;
-
-    printf("Derive a key (HKDF)...\t");
-    fflush(stdout);
-
-    /* Initialize PSA Crypto */
-    status = psa_crypto_init();
-    if (status != PSA_SUCCESS) {
-        printf("Failed to initialize PSA Crypto\n");
-        return;
-    }
-
-    /* Import a key for use in key derivation. If such a key has already been
-     * generated or imported, you can skip this part. */
-    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE);
-    psa_set_key_algorithm(&attributes, alg);
-    psa_set_key_type(&attributes, PSA_KEY_TYPE_DERIVE);
-    status = psa_import_key(&attributes, key, sizeof(key), &base_key);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to import a key\n");
-        return;
-    }
-    psa_reset_key_attributes(&attributes);
-
-    /* Derive a key */
-    status = psa_key_derivation_setup(&operation, alg);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to begin key derivation\n");
-        return;
-    }
-    status = psa_key_derivation_set_capacity(&operation, capacity);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to set capacity\n");
-        return;
-    }
-    status = psa_key_derivation_input_bytes(&operation,
-                                            PSA_KEY_DERIVATION_INPUT_SALT,
-                                            salt, sizeof(salt));
-    if (status != PSA_SUCCESS) {
-        printf("Failed to input salt (extract)\n");
-        return;
-    }
-    status = psa_key_derivation_input_key(&operation,
-                                          PSA_KEY_DERIVATION_INPUT_SECRET,
-                                          base_key);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to input key (extract)\n");
-        return;
-    }
-    status = psa_key_derivation_input_bytes(&operation,
-                                            PSA_KEY_DERIVATION_INPUT_INFO,
-                                            info, sizeof(info));
-    if (status != PSA_SUCCESS) {
-        printf("Failed to input info (expand)\n");
-        return;
-    }
-    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
-    psa_set_key_algorithm(&attributes, PSA_ALG_CTR);
-    psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
-    psa_set_key_bits(&attributes, 128);
-    status = psa_key_derivation_output_key(&attributes, &operation,
-                                           &derived_key);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to derive key\n");
-        return;
-    }
-    psa_reset_key_attributes(&attributes);
-
-    printf("Derived key\n");
-
-    /* Clean up key derivation operation */
-    psa_key_derivation_abort(&operation);
-
-    /* Destroy the keys */
-    psa_destroy_key(derived_key);
-    psa_destroy_key(base_key);
-
-    mbedtls_psa_crypto_free();
-```
-
-### Authenticating and encrypting or decrypting a message
-
-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.
-
-This example shows how to authenticate and encrypt a message:
-```C
-    psa_status_t status;
-    static const uint8_t key[] = {
-        0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
-        0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF };
-    static const uint8_t nonce[] = {
-        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-        0x08, 0x09, 0x0A, 0x0B };
-    static const uint8_t additional_data[] = {
-        0xEC, 0x46, 0xBB, 0x63, 0xB0, 0x25,
-        0x20, 0xC3, 0x3C, 0x49, 0xFD, 0x70 };
-    static const uint8_t input_data[] = {
-        0xB9, 0x6B, 0x49, 0xE2, 0x1D, 0x62, 0x17, 0x41,
-        0x63, 0x28, 0x75, 0xDB, 0x7F, 0x6C, 0x92, 0x43,
-        0xD2, 0xD7, 0xC2 };
-    uint8_t *output_data = NULL;
-    size_t output_size = 0;
-    size_t output_length = 0;
-    size_t tag_length = 16;
-    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    psa_key_id_t key_id;
-
-    printf("Authenticate encrypt...\t");
-    fflush(stdout);
-
-    /* Initialize PSA Crypto */
-    status = psa_crypto_init();
-    if (status != PSA_SUCCESS) {
-        printf("Failed to initialize PSA Crypto\n");
-        return;
-    }
-
-    output_size = sizeof(input_data) + tag_length;
-    output_data = (uint8_t *)malloc(output_size);
-    if (!output_data) {
-        printf("Out of memory\n");
-        return;
-    }
-
-    /* Import a key */
-    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
-    psa_set_key_algorithm(&attributes, PSA_ALG_CCM);
-    psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
-    psa_set_key_bits(&attributes, 128);
-    status = psa_import_key(&attributes, key, sizeof(key), &key_id);
-    psa_reset_key_attributes(&attributes);
-
-    /* Authenticate and encrypt */
-    status = psa_aead_encrypt(key_id, PSA_ALG_CCM,
-                              nonce, sizeof(nonce),
-                              additional_data, sizeof(additional_data),
-                              input_data, sizeof(input_data),
-                              output_data, output_size,
-                              &output_length);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to authenticate and encrypt\n");
-        return;
-    }
-
-    printf("Authenticated and encrypted\n");
-
-    /* Clean up */
-    free(output_data);
-
-    /* Destroy the key */
-    psa_destroy_key(key_id);
-
-    mbedtls_psa_crypto_free();
-```
-
-This example shows how to authenticate and decrypt a message:
-
-```C
-    psa_status_t status;
-    static const uint8_t key_data[] = {
-        0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
-        0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF };
-    static const uint8_t nonce[] = {
-        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-        0x08, 0x09, 0x0A, 0x0B };
-    static const uint8_t additional_data[] = {
-        0xEC, 0x46, 0xBB, 0x63, 0xB0, 0x25,
-        0x20, 0xC3, 0x3C, 0x49, 0xFD, 0x70 };
-    static const uint8_t input_data[] = {
-        0x20, 0x30, 0xE0, 0x36, 0xED, 0x09, 0xA0, 0x45, 0xAF, 0x3C, 0xBA, 0xEE,
-        0x0F, 0xC8, 0x48, 0xAF, 0xCD, 0x89, 0x54, 0xF4, 0xF6, 0x3F, 0x28, 0x9A,
-        0xA1, 0xDD, 0xB2, 0xB8, 0x09, 0xCD, 0x7C, 0xE1, 0x46, 0xE9, 0x98 };
-    uint8_t *output_data = NULL;
-    size_t output_size = 0;
-    size_t output_length = 0;
-    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    psa_key_id_t key_id;
-
-    printf("Authenticate decrypt...\t");
-    fflush(stdout);
-
-    /* Initialize PSA Crypto */
-    status = psa_crypto_init();
-    if (status != PSA_SUCCESS) {
-        printf("Failed to initialize PSA Crypto\n");
-        return;
-    }
-
-    output_size = sizeof(input_data);
-    output_data = (uint8_t *)malloc(output_size);
-    if (!output_data) {
-        printf("Out of memory\n");
-        return;
-    }
-
-    /* Import a key */
-    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);
-    psa_set_key_algorithm(&attributes, PSA_ALG_CCM);
-    psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
-    psa_set_key_bits(&attributes, 128);
-    status = psa_import_key(&attributes, key_data, sizeof(key_data), &key_id);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to import a key\n");
-        return;
-    }
-    psa_reset_key_attributes(&attributes);
-
-    /* Authenticate and decrypt */
-    status = psa_aead_decrypt(key_id, PSA_ALG_CCM,
-                              nonce, sizeof(nonce),
-                              additional_data, sizeof(additional_data),
-                              input_data, sizeof(input_data),
-                              output_data, output_size,
-                              &output_length);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to authenticate and decrypt %ld\n", status);
-        return;
-    }
-
-    printf("Authenticated and decrypted\n");
-
-    /* Clean up */
-    free(output_data);
-
-    /* Destroy the key */
-    psa_destroy_key(key_id);
-
-    mbedtls_psa_crypto_free();
-```
-
-### Generating and exporting keys
-
-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()`.
-
-**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`.
-1. Generate a key by calling `psa_generate_key()`.
-1. Export the generated public key by calling `psa_export_public_key()`:
-```C
-    enum {
-        key_bits = 256,
-    };
-    psa_status_t status;
-    size_t exported_length = 0;
-    static uint8_t exported[PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits)];
-    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    psa_key_id_t key_id;
-
-    printf("Generate a key pair...\t");
-    fflush(stdout);
-
-    /* Initialize PSA Crypto */
-    status = psa_crypto_init();
-    if (status != PSA_SUCCESS) {
-        printf("Failed to initialize PSA Crypto\n");
-        return;
-    }
-
-    /* Generate a key */
-    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
-    psa_set_key_algorithm(&attributes,
-                          PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
-    psa_set_key_type(&attributes,
-                     PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
-    psa_set_key_bits(&attributes, key_bits);
-    status = psa_generate_key(&attributes, &key_id);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to generate key\n");
-        return;
-    }
-    psa_reset_key_attributes(&attributes);
-
-    status = psa_export_public_key(key_id, exported, sizeof(exported),
-                                   &exported_length);
-    if (status != PSA_SUCCESS) {
-        printf("Failed to export public key %ld\n", status);
-        return;
-    }
-
-    printf("Exported a public key\n");
-
-    /* Destroy the key */
-    psa_destroy_key(key_id);
-
-    mbedtls_psa_crypto_free();
-```
-
-### More about the PSA Crypto API
-
-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/docs/proposed/psa-driver-interface.md b/docs/proposed/psa-driver-interface.md
index 8f02af1..0027ec7 100644
--- a/docs/proposed/psa-driver-interface.md
+++ b/docs/proposed/psa-driver-interface.md
@@ -321,6 +321,175 @@
 
 TODO
 
+### Driver entry points for PAKE
+
+A PAKE operation is divided into two stages: collecting inputs and computation. Core side is responsible for keeping inputs and core set-data functions do not have driver entry points. Collected inputs are available for drivers via get-data functions for `password`, `role` and `cipher_suite`.
+
+### PAKE driver dispatch logic
+The core decides whether to dispatch a PAKE operation to a driver based on the location of the provided password.
+When all inputs are collected and `"psa_pake_output"` or `"psa_pake_input"` is called for the first time `"pake_setup"` driver entry point is invoked.
+
+1. If the location of the `password` is the local storage
+- if there is a transparent driver for the specified ciphersuite, the core calls that driver's `"pake_setup"` and subsequent entry points.
+- otherwise, or on fallback, the core uses its built-in implementation.
+2. If the location of the `password` is the location of a secure element
+- the core calls the `"pake_setup"` entry point of the secure element driver and subsequent entry points.
+
+### Summary of entry points for PAKE
+
+A PAKE driver has the following entry points:
+* `"pake_setup"` (mandatory): always the first entry point to be called. It is called when all inputs are collected and the computation stage starts. 
+* `"pake_output"` (mandatory): derive cryptographic material for the specified step and output it.
+* `"pake_input"` (mandatory): provides cryptographic material in the format appropriate for the specified step.
+* `"pake_get_implicit_key"` (mandatory): returns implicitly confirmed shared secret from a PAKE.
+* `"pake_abort"` (mandatory): always the last entry point to be called.
+
+For naming purposes, here and in the following subsection, this specification takes the example of a driver with the prefix `"acme"` that implements the PAKE entry point family with a capability that does not use the `"names"` property to declare different type and entry point names. Such a driver must implement the following type and functions, as well as the entry points listed above and described in the following subsections:
+```
+typedef ... acme_pake_operation_t;
+psa_status_t acme_pake_abort( acme_pake_operation_t *operation );
+```
+
+#### PAKE driver inputs
+
+The core conveys the initial inputs for a PAKE operation via an opaque data structure of type `psa_crypto_driver_pake_inputs_t`.
+
+```
+typedef ... psa_crypto_driver_pake_inputs_t; // implementation-specific type
+```
+
+A driver receiving an argument that points to a `psa_crypto_driver_pake_inputs_t` can retrieve its contents by calling one of the get-data functions below.
+
+```
+psa_status_t psa_crypto_driver_pake_get_password_len(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    size_t *password_len);
+
+psa_status_t psa_crypto_driver_pake_get_password_bytes(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    uint8_t *buffer, size_t buffer_size, size_t *buffer_length);
+
+psa_status_t psa_crypto_driver_pake_get_password_key(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    uint8_t** p_key_buffer, size_t *key_buffer_size,
+    const psa_key_attributes_t *attributes);
+
+psa_status_t psa_crypto_driver_pake_get_user_len(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    size_t *user_len);
+
+psa_status_t psa_crypto_driver_pake_get_user(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    uint8_t *user_id, size_t user_id_size, size_t *user_id_len);
+
+psa_status_t psa_crypto_driver_pake_get_peer_len(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    size_t *peer_len);
+
+psa_status_t psa_crypto_driver_pake_get_peer(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    uint8_t *peer_id, size_t peer_id_size, size_t *peer_id_length);
+
+psa_status_t psa_crypto_driver_pake_get_role(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    psa_pake_role_t *role);
+
+psa_status_t psa_crypto_driver_pake_get_cipher_suite(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    psa_pake_cipher_suite_t *cipher_suite);
+```
+The get-data functions take the following parameters:
+
+The first parameter `inputs` must be a pointer passed by the core to a PAKE driver setup entry point.
+Next parameters are return buffers (must not be null pointers).
+
+These functions can return the following statuses:
+* `PSA_SUCCESS`: value has been successfully obtained
+* `PSA_ERROR_BAD_STATE`: the inputs are not ready
+* `PSA_ERROR_BUFFER_TOO_SMALL` (`psa_crypto_driver_pake_get_password_bytes` and `psa_crypto_driver_pake_get_password_key` only): the output buffer is too small. This is not a fatal error and the driver can, for example, subsequently call the same function again with a larger buffer. Call `psa_crypto_driver_pake_get_password_len` to obtain the required size.
+
+#### PAKE driver setup
+
+```
+psa_status_t acme_pake_setup( acme_pake_operation_t *operation,
+                              const psa_crypto_driver_pake_inputs_t *inputs );
+```
+
+* `operation` is a zero-initialized operation object.
+* `inputs` is an opaque pointer to the [inputs](#pake-driver-inputs) for the PAKE operation.
+
+The setup driver function should preserve the inputs using get-data functions.
+
+The pointer output by `psa_crypto_driver_pake_get_password_key` is only valid until the "pake_setup" entry point returns. Opaque drivers must copy all relevant data from the key buffer during the "pake_setup" entry point and must not store the pointer itself.
+
+#### PAKE driver output
+
+```
+psa_status_t acme_pake_output(acme_pake_operation_t *operation,
+                              psa_crypto_driver_pake_step_t step,
+                              uint8_t *output,
+                              size_t output_size,
+                              size_t *output_length);
+```
+
+* `operation` is an operation object.
+* `step` computation step based on which driver should perform an action.
+* `output` buffer where the output is to be written.
+* `output_size` size of the output buffer in bytes.
+* `output_length` the number of bytes of the returned output.
+
+For `PSA_ALG_JPAKE` the following steps are available for output operation:
+`step` can be one of the following values:
+* `PSA_JPAKE_X1_STEP_KEY_SHARE`     Round 1: output our key share (for ephemeral private key X1)
+* `PSA_JPAKE_X1_STEP_ZK_PUBLIC`     Round 1: output Schnorr NIZKP public key for the X1 key
+* `PSA_JPAKE_X1_STEP_ZK_PROOF`      Round 1: output Schnorr NIZKP proof for the X1 key
+* `PSA_JPAKE_X2_STEP_KEY_SHARE`     Round 1: output our key share (for ephemeral private key X2)
+* `PSA_JPAKE_X2_STEP_ZK_PUBLIC`     Round 1: output Schnorr NIZKP public key for the X2 key
+* `PSA_JPAKE_X2_STEP_ZK_PROOF`      Round 1: output Schnorr NIZKP proof for the X2 key
+* `PSA_JPAKE_X2S_STEP_KEY_SHARE`    Round 2: output our X2S key
+* `PSA_JPAKE_X2S_STEP_ZK_PUBLIC`    Round 2: output Schnorr NIZKP public key for the X2S key 
+* `PSA_JPAKE_X2S_STEP_ZK_PROOF`     Round 2: output Schnorr NIZKP proof for the X2S key
+
+#### PAKE driver input
+```
+psa_status_t acme_pake_input(acme_pake_operation_t *operation,
+                             psa_crypto_driver_pake_step_t step,
+                             uint8_t *input,
+                             size_t input_size);
+```
+
+* `operation` is an operation object.
+* `step` computation step based on which driver should perform an action.
+* `input` buffer containing the input.
+* `input_length` length of the input in bytes.
+
+For `PSA_ALG_JPAKE` the following steps are available for input operation:
+* `PSA_JPAKE_X1_STEP_KEY_SHARE`     Round 1: input key share from peer (for ephemeral private key X1)
+* `PSA_JPAKE_X1_STEP_ZK_PUBLIC`     Round 1: input Schnorr NIZKP public key for the X1 key
+* `PSA_JPAKE_X1_STEP_ZK_PROOF`      Round 1: input Schnorr NIZKP proof for the X1 key
+* `PSA_JPAKE_X2_STEP_KEY_SHARE`     Round 1: input key share from peer (for ephemeral private key X2)
+* `PSA_JPAKE_X2_STEP_ZK_PUBLIC`     Round 1: input Schnorr NIZKP public key for the X2 key
+* `PSA_JPAKE_X2_STEP_ZK_PROOF`      Round 1: input Schnorr NIZKP proof for the X2 key
+* `PSA_JPAKE_X4S_STEP_KEY_SHARE`    Round 2: input X4S key from peer
+* `PSA_JPAKE_X4S_STEP_ZK_PUBLIC`    Round 2: input Schnorr NIZKP public key for the X4S key
+* `PSA_JPAKE_X4S_STEP_ZK_PROOF`     Round 2: input Schnorr NIZKP proof for the X4S key
+
+The core checks that input_length is smaller than PSA_PAKE_INPUT_MAX_SIZE.
+
+### PAKE driver get implicit key
+
+```
+psa_status_t acme_pake_get_implicit_key(
+                            acme_pake_operation_t *operation,
+                            uint8_t *output, size_t output_size,
+                            size_t *output_length );
+```
+
+* `operation` The driver PAKE operation object to use.
+* `output` Buffer where the implicit key is to be written.
+* `output_size` Size of the output buffer in bytes.
+* `output_length` On success, the number of bytes of the implicit key.
+
 ### Driver entry points for key management
 
 The driver entry points for key management differ significantly between [transparent drivers](#key-management-with-transparent-drivers) and [opaque drivers](#key-management-with-opaque-drivers). This section describes common elements. Refer to the applicable section for each driver type for more information.
diff --git a/docs/use-psa-crypto.md b/docs/use-psa-crypto.md
index fc5317a..c63e65a 100644
--- a/docs/use-psa-crypto.md
+++ b/docs/use-psa-crypto.md
@@ -11,12 +11,15 @@
 `psa_crypto_init()` before calling any function from the SSL/TLS, X.509 or PK
 module.
 
-**Scope:** `MBEDTLS_USE_PSA_CRYPTO` has no effect on the parts of the code that
-are specific to TLS 1.3; those parts always use PSA Crypto. The parts of the
-TLS 1.3 code that are common with TLS 1.2, however, follow this option;
-currently this is the record protection code, computation of the running
-handshake hash, and X.509. You need to enable `MBEDTLS_USE_PSA_CRYPTO` if you
-want TLS 1.3 to use PSA everywhere.
+**Scope:** `MBEDTLS_USE_PSA_CRYPTO` has no effect on the most of the TLS 1.3
+code, which always uses PSA crypto. The parts of the TLS 1.3 code that will
+use PSA Crypto or not depending on the value of this option are:
+- record protection;
+- running handshake hash;
+- asymmetric signature verification & generation;
+- X.509 certificate chain verification.
+You need to enable `MBEDTLS_USE_PSA_CRYPTO` if you want TLS 1.3 to use PSA
+everywhere.
 
 New APIs / API extensions
 -------------------------
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 3065df5..85c1de8 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -70,9 +70,12 @@
 #error "MBEDTLS_AESNI_C defined, but not all prerequisites"
 #endif
 
+#if defined(__aarch64__) && defined(__GNUC__)
+/* We don't do anything with MBEDTLS_AESCE_C on systems without ^ these two */
 #if defined(MBEDTLS_AESCE_C) && !defined(MBEDTLS_HAVE_ASM)
 #error "MBEDTLS_AESCE_C defined, but not all prerequisites"
 #endif
+#endif
 
 #if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C)
 #error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites"
@@ -279,8 +282,20 @@
 #error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites"
 #endif
 
+/* Helper for ECDSA dependencies, will be undefined at the end of the file */
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#if defined(PSA_HAVE_FULL_ECDSA)
+#define MBEDTLS_PK_HAVE_ECDSA
+#endif
+#else /* MBEDTLS_USE_PSA_CRYPTO */
+#if defined(MBEDTLS_ECDSA_C)
+#define MBEDTLS_PK_HAVE_ECDSA
+#endif
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
 #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) &&                 \
-    ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) ||          \
+    ( !defined(MBEDTLS_ECDH_C) ||                                       \
+      !defined(MBEDTLS_PK_HAVE_ECDSA) ||                                \
       !defined(MBEDTLS_X509_CRT_PARSE_C) )
 #error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites"
 #endif
@@ -312,8 +327,9 @@
 #error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites"
 #endif
 
-#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) &&                 \
-    ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) ||          \
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) &&                \
+    ( !defined(MBEDTLS_ECDH_C) ||                                       \
+      !defined(MBEDTLS_PK_HAVE_ECDSA) ||                                \
       !defined(MBEDTLS_X509_CRT_PARSE_C) )
 #error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites"
 #endif
@@ -770,7 +786,7 @@
 
 #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
 #if !( defined(MBEDTLS_ECDH_C) && defined(MBEDTLS_X509_CRT_PARSE_C) && \
-       ( defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_PKCS1_V21) ) )
+       ( defined(MBEDTLS_PK_HAVE_ECDSA) || defined(MBEDTLS_PKCS1_V21) ) )
 #error "MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED defined, but not all prerequisites"
 #endif
 #endif
@@ -1066,6 +1082,9 @@
 #error  "MBEDTLS_PKCS7_C is defined, but not all prerequisites"
 #endif
 
+/* Undefine helper symbols */
+#undef MBEDTLS_PK_HAVE_ECDSA
+
 /*
  * Avoid warning from -pedantic. This is a convenient place for this
  * workaround since this is included by every single file before the
diff --git a/include/mbedtls/config_psa.h b/include/mbedtls/config_psa.h
index 48b2d32..568d8c2 100644
--- a/include/mbedtls/config_psa.h
+++ b/include/mbedtls/config_psa.h
@@ -147,12 +147,14 @@
 #endif
 
 #if defined(PSA_WANT_ALG_JPAKE)
+#if !defined(MBEDTLS_PSA_ACCEL_ALG_JPAKE)
 #define MBEDTLS_PSA_BUILTIN_PAKE 1
 #define MBEDTLS_PSA_BUILTIN_ALG_JPAKE 1
 #define MBEDTLS_ECP_DP_SECP256R1_ENABLED
 #define MBEDTLS_BIGNUM_C
 #define MBEDTLS_ECP_C
 #define MBEDTLS_ECJPAKE_C
+#endif /* MBEDTLS_PSA_ACCEL_ALG_JPAKE */
 #endif /* PSA_WANT_ALG_JPAKE */
 
 #if defined(PSA_WANT_ALG_RIPEMD160) && !defined(MBEDTLS_PSA_ACCEL_ALG_RIPEMD160)
@@ -841,6 +843,11 @@
 
 #endif /* MBEDTLS_PSA_CRYPTO_CONFIG */
 
+#if defined(PSA_WANT_ALG_ECDSA) && defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) && \
+    defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
+#define PSA_HAVE_FULL_ECDSA 1
+#endif
+
 /* These features are always enabled. */
 #define PSA_WANT_KEY_TYPE_DERIVE 1
 #define PSA_WANT_KEY_TYPE_PASSWORD 1
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index 7daba37..1ea241c 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -2039,17 +2039,6 @@
  *
  * Requires: MBEDTLS_HAVE_ASM, MBEDTLS_AES_C
  *
- * \note The code uses Neon intrinsics, so \c CFLAGS must be set to a minimum
- * of \c -march=armv8-a+crypto .
- *
- * \warning If the target architecture is set to something that includes the
- *          SHA3 feature (e.g. `-march=armv8.2-a+sha3`), for example because
- *          `MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT` is desired, compilers
- *          generate code for `MBEDTLS_AESCE_C` that includes instructions
- *          only present with the (optional) SHA3 feature. This will lead to an
- *          undefined instruction exception if the code is run on a CPU without
- *          that feature.
- *
  * \warning Runtime detection only works on linux. For non-linux operation
  *          system, crypto extension MUST be supported by CPU.
  *
@@ -2862,11 +2851,7 @@
 /**
  * \def MBEDTLS_PKCS7_C
  *
- * This feature is a work in progress and not ready for production. Testing and
- * validation is incomplete, and handling of malformed inputs may not be robust.
- * The API may change.
- *
- * Enable PKCS7 core for using PKCS7 formatted signatures.
+ * Enable PKCS #7 core for using PKCS #7-formatted signatures.
  * RFC Link - https://tools.ietf.org/html/rfc2315
  *
  * Module:  library/pkcs7.c
@@ -2875,9 +2860,9 @@
  *           MBEDTLS_X509_CRT_PARSE_C MBEDTLS_X509_CRL_PARSE_C,
  *           MBEDTLS_BIGNUM_C, MBEDTLS_MD_C
  *
- * This module is required for the PKCS7 parsing modules.
+ * This module is required for the PKCS #7 parsing modules.
  */
-//#define MBEDTLS_PKCS7_C
+#define MBEDTLS_PKCS7_C
 
 /**
  * \def MBEDTLS_PKCS12_C
diff --git a/include/mbedtls/pkcs7.h b/include/mbedtls/pkcs7.h
index 126eac4..1231e34 100644
--- a/include/mbedtls/pkcs7.h
+++ b/include/mbedtls/pkcs7.h
@@ -1,7 +1,7 @@
 /**
  * \file pkcs7.h
  *
- * \brief PKCS7 generic defines and structures
+ * \brief PKCS #7 generic defines and structures
  *  https://tools.ietf.org/html/rfc2315
  */
 /*
@@ -22,27 +22,22 @@
  */
 
 /**
- * This feature is a work in progress and not ready for production. The API may
- * change. Furthermore, please note that the implementation has only been
- * validated with well-formed inputs, not yet with untrusted inputs (which is
- * almost always the case in practice).
- *
- * Note: For the time being, this implementation of the PKCS7 cryptographic
+ * Note: For the time being, this implementation of the PKCS #7 cryptographic
  * message syntax is a partial implementation of RFC 2315.
  * Differences include:
  *  - The RFC specifies 6 different content types. The only type currently
- *    supported in Mbed TLS is the signed data content type.
- *  - The only supported PKCS7 Signed Data syntax version is version 1
+ *    supported in Mbed TLS is the signed-data content type.
+ *  - The only supported PKCS #7 Signed Data syntax version is version 1
  *  - The RFC specifies support for BER. This implementation is limited to
  *    DER only.
  *  - The RFC specifies that multiple digest algorithms can be specified
  *    in the Signed Data type. Only one digest algorithm is supported in Mbed TLS.
- *  - The RFC specifies the Signed Data type can contain multiple X509 or PKCS6
+ *  - The RFC specifies the Signed Data type can contain multiple X.509 or PKCS #6 extended
  *    certificates. In Mbed TLS, this list can only contain 0 or 1 certificates
- *    and they must be in X509 format.
+ *    and they must be in X.509 format.
  *  - The RFC specifies the Signed Data type can contain
- *    certificate-revocation lists (crls). This implementation has no support
- *    for crls so it is assumed to be an empty list.
+ *    certificate-revocation lists (CRLs). This implementation has no support
+ *    for CRLs so it is assumed to be an empty list.
  *  - The RFC allows for SignerInfo structure to optionally contain
  *    unauthenticatedAttributes and authenticatedAttributes. In Mbed TLS it is
  *    assumed these fields are empty.
@@ -62,13 +57,13 @@
 #include "mbedtls/x509_crt.h"
 
 /**
- * \name PKCS7 Module Error codes
+ * \name PKCS #7 Module Error codes
  * \{
  */
 #define MBEDTLS_ERR_PKCS7_INVALID_FORMAT                   -0x5300  /**< The format is invalid, e.g. different type expected. */
 #define MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE              -0x5380  /**< Unavailable feature, e.g. anything other than signed data. */
-#define MBEDTLS_ERR_PKCS7_INVALID_VERSION                  -0x5400  /**< The PKCS7 version element is invalid or cannot be parsed. */
-#define MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO             -0x5480  /**< The PKCS7 content info is invalid or cannot be parsed. */
+#define MBEDTLS_ERR_PKCS7_INVALID_VERSION                  -0x5400  /**< The PKCS #7 version element is invalid or cannot be parsed. */
+#define MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO             -0x5480  /**< The PKCS #7 content info is invalid or cannot be parsed. */
 #define MBEDTLS_ERR_PKCS7_INVALID_ALG                      -0x5500  /**< The algorithm tag or value is invalid or cannot be parsed. */
 #define MBEDTLS_ERR_PKCS7_INVALID_CERT                     -0x5580  /**< The certificate tag or value is invalid or cannot be parsed. */
 #define MBEDTLS_ERR_PKCS7_INVALID_SIGNATURE                -0x5600  /**< Error parsing the signature */
@@ -76,11 +71,11 @@
 #define MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA                   -0x5700  /**< Input invalid. */
 #define MBEDTLS_ERR_PKCS7_ALLOC_FAILED                     -0x5780  /**< Allocation of memory failed. */
 #define MBEDTLS_ERR_PKCS7_VERIFY_FAIL                      -0x5800  /**< Verification Failed */
-#define MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID                -0x5880  /**< The PKCS7 date issued/expired dates are invalid */
+#define MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID                -0x5880  /**< The PKCS #7 date issued/expired dates are invalid */
 /* \} name */
 
 /**
- * \name PKCS7 Supported Version
+ * \name PKCS #7 Supported Version
  * \{
  */
 #define MBEDTLS_PKCS7_SUPPORTED_VERSION                           0x01
@@ -91,12 +86,12 @@
 #endif
 
 /**
- * Type-length-value structure that allows for ASN1 using DER.
+ * Type-length-value structure that allows for ASN.1 using DER.
  */
 typedef mbedtls_asn1_buf mbedtls_pkcs7_buf;
 
 /**
- * Container for ASN1 named information objects.
+ * Container for ASN.1 named information objects.
  * It allows for Relative Distinguished Names (e.g. cn=localhost,ou=code,etc.).
  */
 typedef mbedtls_asn1_named_data mbedtls_pkcs7_name;
@@ -107,7 +102,7 @@
 typedef mbedtls_asn1_sequence mbedtls_pkcs7_sequence;
 
 /**
- * PKCS7 types
+ * PKCS #7 types
  */
 typedef enum {
     MBEDTLS_PKCS7_NONE=0,
@@ -121,7 +116,7 @@
 mbedtls_pkcs7_type;
 
 /**
- * Structure holding PKCS7 signer info
+ * Structure holding PKCS #7 signer info
  */
 typedef struct mbedtls_pkcs7_signer_info {
     int MBEDTLS_PRIVATE(version);
@@ -151,7 +146,7 @@
 mbedtls_pkcs7_signed_data;
 
 /**
- * Structure holding PKCS7 structure, only signed data for now
+ * Structure holding PKCS #7 structure, only signed data for now
  */
 typedef struct mbedtls_pkcs7 {
     mbedtls_pkcs7_buf MBEDTLS_PRIVATE(raw);
@@ -160,21 +155,21 @@
 mbedtls_pkcs7;
 
 /**
- * \brief          Initialize pkcs7 structure.
+ * \brief          Initialize mbedtls_pkcs7 structure.
  *
- * \param pkcs7    pkcs7 structure.
+ * \param pkcs7    mbedtls_pkcs7 structure.
  */
 void mbedtls_pkcs7_init(mbedtls_pkcs7 *pkcs7);
 
 /**
- * \brief          Parse a single DER formatted pkcs7 detached signature.
+ * \brief          Parse a single DER formatted PKCS #7 detached signature.
  *
- * \param pkcs7    The pkcs7 structure to be filled by parser for the output.
- * \param buf      The buffer holding only the DER encoded pkcs7.
+ * \param pkcs7    The mbedtls_pkcs7 structure to be filled by the parser.
+ * \param buf      The buffer holding only the DER encoded PKCS #7 content.
  * \param buflen   The size in bytes of \p buf. The size must be exactly the
- *                 length of the DER encoded pkcs7.
+ *                 length of the DER encoded PKCS #7 content.
  *
- * \note           This function makes an internal copy of the PKCS7 buffer
+ * \note           This function makes an internal copy of the PKCS #7 buffer
  *                 \p buf. In particular, \p buf may be destroyed or reused
  *                 after this call returns.
  * \note           Signatures with internal data are not supported.
@@ -186,7 +181,7 @@
                             const size_t buflen);
 
 /**
- * \brief          Verification of PKCS7 signature against a caller-supplied
+ * \brief          Verification of PKCS #7 signature against a caller-supplied
  *                 certificate.
  *
  *                 For each signer in the PKCS structure, this function computes
@@ -197,10 +192,10 @@
  *                 matches.
  *
  *                 This function does not use the certificates held within the
- *                 PKCS7 structure itself, and does not check that the
+ *                 PKCS #7 structure itself, and does not check that the
  *                 certificate is signed by a trusted certification authority.
  *
- * \param pkcs7    PKCS7 structure containing signature.
+ * \param pkcs7    mbedtls_pkcs7 structure containing signature.
  * \param cert     Certificate containing key to verify signature.
  * \param data     Plain data on which signature has to be verified.
  * \param datalen  Length of the data.
@@ -216,7 +211,7 @@
                                      size_t datalen);
 
 /**
- * \brief          Verification of PKCS7 signature against a caller-supplied
+ * \brief          Verification of PKCS #7 signature against a caller-supplied
  *                 certificate.
  *
  *                 For each signer in the PKCS structure, this function
@@ -226,10 +221,10 @@
  *                 signature is good.
  *
  *                 This function does not use the certificates held within the
- *                 PKCS7 structure itself, and does not check that the
+ *                 PKCS #7 structure itself, and does not check that the
  *                 certificate is signed by a trusted certification authority.
  *
- * \param pkcs7    PKCS7 structure containing signature.
+ * \param pkcs7    PKCS #7 structure containing signature.
  * \param cert     Certificate containing key to verify signature.
  * \param hash     Hash of the plain data on which signature has to be verified.
  * \param hashlen  Length of the hash.
@@ -244,10 +239,10 @@
                                      const unsigned char *hash, size_t hashlen);
 
 /**
- * \brief          Unallocate all PKCS7 data and zeroize the memory.
- *                 It doesn't free pkcs7 itself. It should be done by the caller.
+ * \brief          Unallocate all PKCS #7 data and zeroize the memory.
+ *                 It doesn't free \p pkcs7 itself. This should be done by the caller.
  *
- * \param pkcs7    PKCS7 structure to free.
+ * \param pkcs7    mbedtls_pkcs7 structure to free.
  */
 void mbedtls_pkcs7_free(mbedtls_pkcs7 *pkcs7);
 
diff --git a/include/psa/crypto_builtin_composites.h b/include/psa/crypto_builtin_composites.h
index 9f23551..932c503 100644
--- a/include/psa/crypto_builtin_composites.h
+++ b/include/psa/crypto_builtin_composites.h
@@ -180,5 +180,40 @@
 #endif
 
 
+/* EC-JPAKE operation definitions */
+
+#include "mbedtls/ecjpake.h"
+
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
+#define MBEDTLS_PSA_BUILTIN_PAKE  1
+#endif
+
+/* Note: the format for mbedtls_ecjpake_read/write function has an extra
+ * length byte for each step, plus an extra 3 bytes for ECParameters in the
+ * server's 2nd round. */
+#define MBEDTLS_PSA_JPAKE_BUFFER_SIZE ((3 + 1 + 65 + 1 + 65 + 1 + 32) * 2)
+
+typedef struct {
+    psa_algorithm_t MBEDTLS_PRIVATE(alg);
+
+    uint8_t *MBEDTLS_PRIVATE(password);
+    size_t MBEDTLS_PRIVATE(password_len);
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
+    uint8_t MBEDTLS_PRIVATE(role);
+    uint8_t MBEDTLS_PRIVATE(buffer[MBEDTLS_PSA_JPAKE_BUFFER_SIZE]);
+    size_t MBEDTLS_PRIVATE(buffer_length);
+    size_t MBEDTLS_PRIVATE(buffer_offset);
+#endif
+    /* Context structure for the Mbed TLS EC-JPAKE implementation. */
+    union {
+        unsigned int MBEDTLS_PRIVATE(dummy);
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
+        mbedtls_ecjpake_context MBEDTLS_PRIVATE(jpake);
+#endif
+    } MBEDTLS_PRIVATE(ctx);
+
+} mbedtls_psa_pake_operation_t;
+
+#define MBEDTLS_PSA_PAKE_OPERATION_INIT { { 0 } }
 
 #endif /* PSA_CRYPTO_BUILTIN_COMPOSITES_H */
diff --git a/include/psa/crypto_driver_contexts_composites.h b/include/psa/crypto_driver_contexts_composites.h
index 1b95814..6c56a51 100644
--- a/include/psa/crypto_driver_contexts_composites.h
+++ b/include/psa/crypto_driver_contexts_composites.h
@@ -88,6 +88,32 @@
 
 #endif /* MBEDTLS_TEST_LIBTESTDRIVER1 && LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_AEAD */
 
+#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
+    defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_PAKE)
+
+typedef libtestdriver1_mbedtls_psa_pake_operation_t
+    mbedtls_transparent_test_driver_pake_operation_t;
+typedef libtestdriver1_mbedtls_psa_pake_operation_t
+    mbedtls_opaque_test_driver_pake_operation_t;
+
+#define MBEDTLS_TRANSPARENT_TEST_DRIVER_PAKE_OPERATION_INIT \
+    LIBTESTDRIVER1_MBEDTLS_PSA_PAKE_OPERATION_INIT
+#define MBEDTLS_OPAQUE_TEST_DRIVER_PAKE_OPERATION_INIT \
+    LIBTESTDRIVER1_MBEDTLS_PSA_PAKE_OPERATION_INIT
+
+#else
+typedef mbedtls_psa_pake_operation_t
+    mbedtls_transparent_test_driver_pake_operation_t;
+typedef mbedtls_psa_pake_operation_t
+    mbedtls_opaque_test_driver_pake_operation_t;
+
+#define MBEDTLS_TRANSPARENT_TEST_DRIVER_PAKE_OPERATION_INIT \
+    MBEDTLS_PSA_PAKE_OPERATION_INIT
+#define MBEDTLS_OPAQUE_TEST_DRIVER_PAKE_OPERATION_INIT \
+    MBEDTLS_PSA_PAKE_OPERATION_INIT
+
+#endif /* MBEDTLS_TEST_LIBTESTDRIVER1 && LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_PAKE */
+
 #endif /* PSA_CRYPTO_DRIVER_TEST */
 
 /* Define the context to be used for an operation that is executed through the
@@ -124,5 +150,14 @@
     mbedtls_psa_verify_hash_interruptible_operation_t mbedtls_ctx;
 } psa_driver_verify_hash_interruptible_context_t;
 
+typedef union {
+    unsigned dummy; /* Make sure this union is always non-empty */
+    mbedtls_psa_pake_operation_t mbedtls_ctx;
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+    mbedtls_transparent_test_driver_pake_operation_t transparent_test_driver_ctx;
+    mbedtls_opaque_test_driver_pake_operation_t opaque_test_driver_ctx;
+#endif
+} psa_driver_pake_context_t;
+
 #endif /* PSA_CRYPTO_DRIVER_CONTEXTS_COMPOSITES_H */
 /* End of automatically generated file. */
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index 582d942..4920508 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -429,6 +429,10 @@
  */
 #define PSA_DH_FAMILY_CUSTOM             ((psa_dh_family_t) 0x7e)
 
+/** PAKE operation stages. */
+#define PSA_PAKE_OPERATION_STAGE_SETUP 0
+#define PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS 1
+#define PSA_PAKE_OPERATION_STAGE_COMPUTATION 2
 
 /**
  * \brief Set domain parameters for a key.
@@ -1286,10 +1290,138 @@
  * Implementation details can change in future versions without notice. */
 typedef struct psa_pake_operation_s psa_pake_operation_t;
 
+/** The type of input values for PAKE operations. */
+typedef struct psa_crypto_driver_pake_inputs_s psa_crypto_driver_pake_inputs_t;
+
+/** The type of computation stage for J-PAKE operations. */
+typedef struct psa_jpake_computation_stage_s psa_jpake_computation_stage_t;
+
 /** Return an initial value for a PAKE operation object.
  */
 static psa_pake_operation_t psa_pake_operation_init(void);
 
+/** Get the length of the password in bytes from given inputs.
+ *
+ * \param[in]  inputs           Operation inputs.
+ * \param[out] password_len     Password length.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ *         Password hasn't been set yet.
+ */
+psa_status_t psa_crypto_driver_pake_get_password_len(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    size_t *password_len);
+
+/** Get the password from given inputs.
+ *
+ * \param[in]  inputs           Operation inputs.
+ * \param[out] buffer           Return buffer for password.
+ * \param      buffer_size      Size of the return buffer in bytes.
+ * \param[out] buffer_length    Actual size of the password in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ *         Password hasn't been set yet.
+ */
+psa_status_t psa_crypto_driver_pake_get_password(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    uint8_t *buffer, size_t buffer_size, size_t *buffer_length);
+
+/** Get the role from given inputs.
+ *
+ * \param[in]  inputs           Operation inputs.
+ * \param[out] role             Return buffer for role.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ *         Role hasn't been set yet.
+ */
+psa_status_t psa_crypto_driver_pake_get_role(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    psa_pake_role_t *role);
+
+/** Get the length of the user id in bytes from given inputs.
+ *
+ * \param[in]  inputs           Operation inputs.
+ * \param[out] user_len         User id length.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ *         User id hasn't been set yet.
+ */
+psa_status_t psa_crypto_driver_pake_get_user_len(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    size_t *user_len);
+
+/** Get the length of the peer id in bytes from given inputs.
+ *
+ * \param[in]  inputs           Operation inputs.
+ * \param[out] peer_len         Peer id length.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ *         Peer id hasn't been set yet.
+ */
+psa_status_t psa_crypto_driver_pake_get_peer_len(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    size_t *peer_len);
+
+/** Get the user id from given inputs.
+ *
+ * \param[in]  inputs           Operation inputs.
+ * \param[out] user_id          User id.
+ * \param      user_id_size     Size of \p user_id in bytes.
+ * \param[out] user_id_len      Size of the user id in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ *         User id hasn't been set yet.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ *         The size of the \p user_id is too small.
+ */
+psa_status_t psa_crypto_driver_pake_get_user(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    uint8_t *user_id, size_t user_id_size, size_t *user_id_len);
+
+/** Get the peer id from given inputs.
+ *
+ * \param[in]  inputs           Operation inputs.
+ * \param[out] peer_id          Peer id.
+ * \param      peer_id_size     Size of \p peer_id in bytes.
+ * \param[out] peer_id_length   Size of the peer id in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ *         Peer id hasn't been set yet.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ *         The size of the \p peer_id is too small.
+ */
+psa_status_t psa_crypto_driver_pake_get_peer(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    uint8_t *peer_id, size_t peer_id_size, size_t *peer_id_length);
+
+/** Get the cipher suite from given inputs.
+ *
+ * \param[in]  inputs           Operation inputs.
+ * \param[out] cipher_suite     Return buffer for role.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ *         Cipher_suite hasn't been set yet.
+ */
+psa_status_t psa_crypto_driver_pake_get_cipher_suite(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    psa_pake_cipher_suite_t *cipher_suite);
+
 /** Set the session information for a password-authenticated key exchange.
  *
  * The sequence of operations to set up a password-authenticated key exchange
@@ -1430,6 +1562,7 @@
  *                              been set (psa_pake_set_user() hasn't been
  *                              called yet).
  * \param[in] user_id           The user ID to authenticate with.
+ *                              (temporary limitation: "client" or "server" only)
  * \param user_id_len           Size of the \p user_id buffer in bytes.
  *
  * \retval #PSA_SUCCESS
@@ -1471,6 +1604,7 @@
  *                              been set (psa_pake_set_peer() hasn't been
  *                              called yet).
  * \param[in] peer_id           The peer's ID to authenticate.
+ *                              (temporary limitation: "client" or "server" only)
  * \param peer_id_len           Size of the \p peer_id buffer in bytes.
  *
  * \retval #PSA_SUCCESS
@@ -1826,14 +1960,8 @@
 /** Returns a suitable initializer for a PAKE operation object of type
  * psa_pake_operation_t.
  */
-#if defined(MBEDTLS_PSA_BUILTIN_PAKE)
-#define PSA_PAKE_OPERATION_INIT { PSA_ALG_NONE, 0, 0, 0, 0,              \
-                                  NULL, 0,               \
-                                  PSA_PAKE_ROLE_NONE, { 0 }, 0, 0,         \
-                                  { .dummy = 0 } }
-#else
-#define PSA_PAKE_OPERATION_INIT { PSA_ALG_NONE, 0, 0, { 0 } }
-#endif
+#define PSA_PAKE_OPERATION_INIT { 0, PSA_ALG_NONE, PSA_PAKE_OPERATION_STAGE_SETUP, \
+                                  { 0 }, { { 0 } } }
 
 struct psa_pake_cipher_suite_s {
     psa_algorithm_t algorithm;
@@ -1904,35 +2032,94 @@
     }
 }
 
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
-#include <mbedtls/ecjpake.h>
-/* Note: the format for mbedtls_ecjpake_read/write function has an extra
- * length byte for each step, plus an extra 3 bytes for ECParameters in the
- * server's 2nd round. */
-#define MBEDTLS_PSA_PAKE_BUFFER_SIZE ((3 + 1 + 65 + 1 + 65 + 1 + 32) * 2)
-#endif
-
-struct psa_pake_operation_s {
-    psa_algorithm_t MBEDTLS_PRIVATE(alg);
-    unsigned int MBEDTLS_PRIVATE(state);
-    unsigned int MBEDTLS_PRIVATE(sequence);
-#if defined(MBEDTLS_PSA_BUILTIN_PAKE)
-    unsigned int MBEDTLS_PRIVATE(input_step);
-    unsigned int MBEDTLS_PRIVATE(output_step);
+struct psa_crypto_driver_pake_inputs_s {
     uint8_t *MBEDTLS_PRIVATE(password);
     size_t MBEDTLS_PRIVATE(password_len);
     psa_pake_role_t MBEDTLS_PRIVATE(role);
-    uint8_t MBEDTLS_PRIVATE(buffer[MBEDTLS_PSA_PAKE_BUFFER_SIZE]);
-    size_t MBEDTLS_PRIVATE(buffer_length);
-    size_t MBEDTLS_PRIVATE(buffer_offset);
-#endif
+    uint8_t *MBEDTLS_PRIVATE(user);
+    size_t MBEDTLS_PRIVATE(user_len);
+    uint8_t *MBEDTLS_PRIVATE(peer);
+    size_t MBEDTLS_PRIVATE(peer_len);
+    psa_key_attributes_t MBEDTLS_PRIVATE(attributes);
+    psa_pake_cipher_suite_t MBEDTLS_PRIVATE(cipher_suite);
+};
+
+typedef enum psa_jpake_step {
+    PSA_PAKE_STEP_INVALID       = 0,
+    PSA_PAKE_STEP_X1_X2         = 1,
+    PSA_PAKE_STEP_X2S           = 2,
+    PSA_PAKE_STEP_DERIVE        = 3,
+} psa_jpake_step_t;
+
+typedef enum psa_jpake_state {
+    PSA_PAKE_STATE_INVALID      = 0,
+    PSA_PAKE_STATE_SETUP        = 1,
+    PSA_PAKE_STATE_READY        = 2,
+    PSA_PAKE_OUTPUT_X1_X2       = 3,
+    PSA_PAKE_OUTPUT_X2S         = 4,
+    PSA_PAKE_INPUT_X1_X2        = 5,
+    PSA_PAKE_INPUT_X4S          = 6,
+} psa_jpake_state_t;
+
+typedef enum psa_jpake_sequence {
+    PSA_PAKE_SEQ_INVALID        = 0,
+    PSA_PAKE_X1_STEP_KEY_SHARE  = 1,    /* also X2S & X4S KEY_SHARE */
+    PSA_PAKE_X1_STEP_ZK_PUBLIC  = 2,    /* also X2S & X4S ZK_PUBLIC */
+    PSA_PAKE_X1_STEP_ZK_PROOF   = 3,    /* also X2S & X4S ZK_PROOF */
+    PSA_PAKE_X2_STEP_KEY_SHARE  = 4,
+    PSA_PAKE_X2_STEP_ZK_PUBLIC  = 5,
+    PSA_PAKE_X2_STEP_ZK_PROOF   = 6,
+    PSA_PAKE_SEQ_END            = 7,
+} psa_jpake_sequence_t;
+
+typedef enum psa_crypto_driver_pake_step {
+    PSA_JPAKE_STEP_INVALID        = 0,  /* Invalid step */
+    PSA_JPAKE_X1_STEP_KEY_SHARE   = 1,  /* Round 1: input/output key share (for ephemeral private key X1).*/
+    PSA_JPAKE_X1_STEP_ZK_PUBLIC   = 2,  /* Round 1: input/output Schnorr NIZKP public key for the X1 key */
+    PSA_JPAKE_X1_STEP_ZK_PROOF    = 3,  /* Round 1: input/output Schnorr NIZKP proof for the X1 key */
+    PSA_JPAKE_X2_STEP_KEY_SHARE   = 4,  /* Round 1: input/output key share (for ephemeral private key X2).*/
+    PSA_JPAKE_X2_STEP_ZK_PUBLIC   = 5,  /* Round 1: input/output Schnorr NIZKP public key for the X2 key */
+    PSA_JPAKE_X2_STEP_ZK_PROOF    = 6,  /* Round 1: input/output Schnorr NIZKP proof for the X2 key */
+    PSA_JPAKE_X2S_STEP_KEY_SHARE  = 7,  /* Round 2: output X2S key (our key) */
+    PSA_JPAKE_X2S_STEP_ZK_PUBLIC  = 8,  /* Round 2: output Schnorr NIZKP public key for the X2S key (our key) */
+    PSA_JPAKE_X2S_STEP_ZK_PROOF   = 9,  /* Round 2: output Schnorr NIZKP proof for the X2S key (our key) */
+    PSA_JPAKE_X4S_STEP_KEY_SHARE  = 10, /* Round 2: input X4S key (from peer) */
+    PSA_JPAKE_X4S_STEP_ZK_PUBLIC  = 11, /* Round 2: input Schnorr NIZKP public key for the X4S key (from peer) */
+    PSA_JPAKE_X4S_STEP_ZK_PROOF   = 12  /* Round 2: input Schnorr NIZKP proof for the X4S key (from peer) */
+} psa_crypto_driver_pake_step_t;
+
+
+struct psa_jpake_computation_stage_s {
+    psa_jpake_state_t MBEDTLS_PRIVATE(state);
+    psa_jpake_sequence_t MBEDTLS_PRIVATE(sequence);
+    psa_jpake_step_t MBEDTLS_PRIVATE(input_step);
+    psa_jpake_step_t MBEDTLS_PRIVATE(output_step);
+};
+
+struct psa_pake_operation_s {
+    /** Unique ID indicating which driver got assigned to do the
+     * operation. Since driver contexts are driver-specific, swapping
+     * drivers halfway through the operation is not supported.
+     * ID values are auto-generated in psa_crypto_driver_wrappers.h
+     * ID value zero means the context is not valid or not assigned to
+     * any driver (i.e. none of the driver contexts are active). */
+    unsigned int MBEDTLS_PRIVATE(id);
+    /* Algorithm of the PAKE operation */
+    psa_algorithm_t MBEDTLS_PRIVATE(alg);
+    /* Stage of the PAKE operation: waiting for the setup, collecting inputs
+     * or computing. */
+    uint8_t MBEDTLS_PRIVATE(stage);
+    /* Holds computation stage of the PAKE algorithms. */
     union {
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
-        mbedtls_ecjpake_context ecjpake;
+        uint8_t MBEDTLS_PRIVATE(dummy);
+#if defined(PSA_WANT_ALG_JPAKE)
+        psa_jpake_computation_stage_t MBEDTLS_PRIVATE(jpake);
 #endif
-        /* Make the union non-empty even with no supported algorithms. */
-        uint8_t dummy;
-    } MBEDTLS_PRIVATE(ctx);
+    } MBEDTLS_PRIVATE(computation_stage);
+    union {
+        psa_driver_pake_context_t MBEDTLS_PRIVATE(ctx);
+        psa_crypto_driver_pake_inputs_t MBEDTLS_PRIVATE(inputs);
+    } MBEDTLS_PRIVATE(data);
 };
 
 static inline struct psa_pake_cipher_suite_s psa_pake_cipher_suite_init(void)
diff --git a/library/aesce.c b/library/aesce.c
index 0f6c323..acfac23 100644
--- a/library/aesce.c
+++ b/library/aesce.c
@@ -17,6 +17,28 @@
  *  limitations under the License.
  */
 
+#if defined(__aarch64__) && !defined(__ARM_FEATURE_CRYPTO) && \
+    defined(__clang__) && __clang_major__ >= 4
+/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
+ *
+ * The intrinsic declaration are guarded by predefined ACLE macros in clang:
+ * these are normally only enabled by the -march option on the command line.
+ * By defining the macros ourselves we gain access to those declarations without
+ * requiring -march on the command line.
+ *
+ * `arm_neon.h` could be included by any header file, so we put these defines
+ * at the top of this file, before any includes.
+ */
+#define __ARM_FEATURE_CRYPTO 1
+/* See: https://arm-software.github.io/acle/main/acle.html#cryptographic-extensions
+ *
+ * `__ARM_FEATURE_CRYPTO` is deprecated, but we need to continue to specify it
+ * for older compilers.
+ */
+#define __ARM_FEATURE_AES    1
+#define MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG
+#endif
+
 #include <string.h>
 #include "common.h"
 
@@ -26,22 +48,24 @@
 
 #if defined(MBEDTLS_HAVE_ARM64)
 
-#if defined(__clang__)
-#   if __clang_major__ < 4
-#       error "A more recent Clang is required for MBEDTLS_AESCE_C"
+#if !defined(__ARM_FEATURE_AES) || defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG)
+#   if defined(__clang__)
+#       if __clang_major__ < 4
+#           error "A more recent Clang is required for MBEDTLS_AESCE_C"
+#       endif
+#       pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
+#       define MBEDTLS_POP_TARGET_PRAGMA
+#   elif defined(__GNUC__)
+#       if __GNUC__ < 6
+#           error "A more recent GCC is required for MBEDTLS_AESCE_C"
+#       endif
+#       pragma GCC push_options
+#       pragma GCC target ("arch=armv8-a+crypto")
+#       define MBEDTLS_POP_TARGET_PRAGMA
+#   else
+#       error "Only GCC and Clang supported for MBEDTLS_AESCE_C"
 #   endif
-#elif defined(__GNUC__)
-#   if __GNUC__ < 6
-#       error "A more recent GCC is required for MBEDTLS_AESCE_C"
-#   endif
-#else
-#    error "Only GCC and Clang supported for MBEDTLS_AESCE_C"
-#endif
-
-#if !defined(__ARM_FEATURE_CRYPTO)
-#   error "`crypto` feature modifier MUST be enabled for MBEDTLS_AESCE_C."
-#   error "Typical option for GCC and Clang is `-march=armv8-a+crypto`."
-#endif /* !__ARM_FEATURE_CRYPTO */
+#endif /* !__ARM_FEATURE_AES || MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG */
 
 #include <arm_neon.h>
 
@@ -252,6 +276,16 @@
     return 0;
 }
 
+
+#if defined(MBEDTLS_POP_TARGET_PRAGMA)
+#if defined(__clang__)
+#pragma clang attribute pop
+#elif defined(__GNUC__)
+#pragma GCC pop_options
+#endif
+#undef MBEDTLS_POP_TARGET_PRAGMA
+#endif
+
 #endif /* MBEDTLS_HAVE_ARM64 */
 
 #endif /* MBEDTLS_AESCE_C */
diff --git a/library/common.h b/library/common.h
index 46af79f..eb159a7 100644
--- a/library/common.h
+++ b/library/common.h
@@ -26,6 +26,7 @@
 #include "mbedtls/build_info.h"
 #include "alignment.h"
 
+#include <assert.h>
 #include <stddef.h>
 #include <stdint.h>
 #include <stddef.h>
@@ -149,4 +150,18 @@
 #endif
 /* *INDENT-ON* */
 
+/* Always provide a static assert macro, so it can be used unconditionally.
+ * It will expand to nothing on some systems.
+ * Can be used outside functions (but don't add a trailing ';' in that case:
+ * the semicolon is included here to avoid triggering -Wextra-semi when
+ * MBEDTLS_STATIC_ASSERT() expands to nothing).
+ * Can't use the C11-style `defined(static_assert)` on FreeBSD, since it
+ * defines static_assert even with -std=c99, but then complains about it.
+ */
+#if defined(static_assert) && !defined(__FreeBSD__)
+#define MBEDTLS_STATIC_ASSERT(expr, msg)    static_assert(expr, msg);
+#else
+#define MBEDTLS_STATIC_ASSERT(expr, msg)
+#endif
+
 #endif /* MBEDTLS_LIBRARY_COMMON_H */
diff --git a/library/pkcs7.c b/library/pkcs7.c
index d4059d7..cf05afd 100644
--- a/library/pkcs7.c
+++ b/library/pkcs7.c
@@ -42,7 +42,7 @@
 #endif
 
 /**
- * Initializes the pkcs7 structure.
+ * Initializes the mbedtls_pkcs7 structure.
  */
 void mbedtls_pkcs7_init(mbedtls_pkcs7 *pkcs7)
 {
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 0efebb4..ba204f7 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -48,7 +48,6 @@
 
 #include "psa_crypto_random_impl.h"
 
-#include <assert.h>
 #include <stdlib.h>
 #include <string.h>
 #include "mbedtls/platform.h"
@@ -91,6 +90,10 @@
 #define BUILTIN_ALG_ANY_HKDF 1
 #endif
 
+/* The only two JPAKE user/peer identifiers supported for the time being. */
+static const uint8_t jpake_server_id[] = { 's', 'e', 'r', 'v', 'e', 'r' };
+static const uint8_t jpake_client_id[] = { 'c', 'l', 'i', 'e', 'n', 't' };
+
 /****************************************************************/
 /* Global data, support functions and library management */
 /****************************************************************/
@@ -916,14 +919,27 @@
     return PSA_SUCCESS;
 }
 
-psa_status_t psa_get_and_lock_key_slot_with_policy(
+/** Get the description of a key given its identifier and policy constraints
+ *  and lock it.
+ *
+ * The key must have allow all the usage flags set in \p usage. If \p alg is
+ * nonzero, the key must allow operations with this algorithm. If \p alg is
+ * zero, the algorithm is not checked.
+ *
+ * In case of a persistent key, the function loads the description of the key
+ * into a key slot if not already done.
+ *
+ * On success, the returned key slot is locked. It is the responsibility of
+ * the caller to unlock the key slot when it does not access it anymore.
+ */
+static psa_status_t psa_get_and_lock_key_slot_with_policy(
     mbedtls_svc_key_id_t key,
     psa_key_slot_t **p_slot,
     psa_key_usage_t usage,
     psa_algorithm_t alg)
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
-    psa_key_slot_t *slot;
+    psa_key_slot_t *slot = NULL;
 
     status = psa_get_and_lock_key_slot(key, p_slot);
     if (status != PSA_SUCCESS) {
@@ -1471,14 +1487,15 @@
     return (status == PSA_SUCCESS) ? unlock_status : status;
 }
 
-#if defined(static_assert)
-static_assert((MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE) == 0,
-              "One or more key attribute flag is listed as both external-only and dual-use");
-static_assert((PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE) == 0,
-              "One or more key attribute flag is listed as both internal-only and dual-use");
-static_assert((PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY) == 0,
-              "One or more key attribute flag is listed as both internal-only and external-only");
-#endif
+MBEDTLS_STATIC_ASSERT(
+    (MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE) == 0,
+    "One or more key attribute flag is listed as both external-only and dual-use")
+MBEDTLS_STATIC_ASSERT(
+    (PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE) == 0,
+    "One or more key attribute flag is listed as both internal-only and dual-use")
+MBEDTLS_STATIC_ASSERT(
+    (PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY) == 0,
+    "One or more key attribute flag is listed as both internal-only and external-only")
 
 /** Validate that a key policy is internally well-formed.
  *
@@ -1742,11 +1759,10 @@
             psa_key_slot_number_t slot_number =
                 psa_key_slot_get_slot_number(slot);
 
-#if defined(static_assert)
-            static_assert(sizeof(slot_number) ==
-                          sizeof(data.slot_number),
-                          "Slot number size does not match psa_se_key_data_storage_t");
-#endif
+            MBEDTLS_STATIC_ASSERT(sizeof(slot_number) ==
+                                  sizeof(data.slot_number),
+                                  "Slot number size does not match psa_se_key_data_storage_t");
+
             memcpy(&data.slot_number, &slot_number, sizeof(slot_number));
             status = psa_save_persistent_key(&slot->attr,
                                              (uint8_t *) &data,
@@ -5061,13 +5077,13 @@
                                      operation->ctx.tls12_prf.label_length);
             mbedtls_free(operation->ctx.tls12_prf.label);
         }
-
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
         if (operation->ctx.tls12_prf.other_secret != NULL) {
             mbedtls_platform_zeroize(operation->ctx.tls12_prf.other_secret,
                                      operation->ctx.tls12_prf.other_secret_length);
             mbedtls_free(operation->ctx.tls12_prf.other_secret);
         }
-
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
         status = PSA_SUCCESS;
 
         /* We leave the fields Ai and output_block to be erased safely by the
@@ -7152,4 +7168,866 @@
     return status;
 }
 
+psa_status_t psa_crypto_driver_pake_get_password_len(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    size_t *password_len)
+{
+    if (inputs->password_len == 0) {
+        return PSA_ERROR_BAD_STATE;
+    }
+
+    *password_len = inputs->password_len;
+
+    return PSA_SUCCESS;
+}
+
+psa_status_t psa_crypto_driver_pake_get_password(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    uint8_t *buffer, size_t buffer_size, size_t *buffer_length)
+{
+    if (inputs->password_len == 0) {
+        return PSA_ERROR_BAD_STATE;
+    }
+
+    if (buffer_size < inputs->password_len) {
+        return PSA_ERROR_BUFFER_TOO_SMALL;
+    }
+
+    memcpy(buffer, inputs->password, inputs->password_len);
+    *buffer_length = inputs->password_len;
+
+    return PSA_SUCCESS;
+}
+
+psa_status_t psa_crypto_driver_pake_get_role(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    psa_pake_role_t *role)
+{
+    if (inputs->role == PSA_PAKE_ROLE_NONE) {
+        return PSA_ERROR_BAD_STATE;
+    }
+
+    *role = inputs->role;
+
+    return PSA_SUCCESS;
+}
+
+psa_status_t psa_crypto_driver_pake_get_user_len(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    size_t *user_len)
+{
+    if (inputs->user_len == 0) {
+        return PSA_ERROR_BAD_STATE;
+    }
+
+    *user_len = inputs->user_len;
+
+    return PSA_SUCCESS;
+}
+
+psa_status_t psa_crypto_driver_pake_get_user(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    uint8_t *user_id, size_t user_id_size, size_t *user_id_len)
+{
+    if (inputs->user_len == 0) {
+        return PSA_ERROR_BAD_STATE;
+    }
+
+    if (user_id_size < inputs->user_len) {
+        return PSA_ERROR_BUFFER_TOO_SMALL;
+    }
+
+    memcpy(user_id, inputs->user, inputs->user_len);
+    *user_id_len = inputs->user_len;
+
+    return PSA_SUCCESS;
+}
+
+psa_status_t psa_crypto_driver_pake_get_peer_len(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    size_t *peer_len)
+{
+    if (inputs->peer_len == 0) {
+        return PSA_ERROR_BAD_STATE;
+    }
+
+    *peer_len = inputs->peer_len;
+
+    return PSA_SUCCESS;
+}
+
+psa_status_t psa_crypto_driver_pake_get_peer(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    uint8_t *peer_id, size_t peer_id_size, size_t *peer_id_length)
+{
+    if (inputs->peer_len == 0) {
+        return PSA_ERROR_BAD_STATE;
+    }
+
+    if (peer_id_size < inputs->peer_len) {
+        return PSA_ERROR_BUFFER_TOO_SMALL;
+    }
+
+    memcpy(peer_id, inputs->peer, inputs->peer_len);
+    *peer_id_length = inputs->peer_len;
+
+    return PSA_SUCCESS;
+}
+
+psa_status_t psa_crypto_driver_pake_get_cipher_suite(
+    const psa_crypto_driver_pake_inputs_t *inputs,
+    psa_pake_cipher_suite_t *cipher_suite)
+{
+    if (inputs->cipher_suite.algorithm == PSA_ALG_NONE) {
+        return PSA_ERROR_BAD_STATE;
+    }
+
+    *cipher_suite = inputs->cipher_suite;
+
+    return PSA_SUCCESS;
+}
+
+psa_status_t psa_pake_setup(
+    psa_pake_operation_t *operation,
+    const psa_pake_cipher_suite_t *cipher_suite)
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+    if (operation->stage != PSA_PAKE_OPERATION_STAGE_SETUP) {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    if (PSA_ALG_IS_PAKE(cipher_suite->algorithm) == 0 ||
+        PSA_ALG_IS_HASH(cipher_suite->hash) == 0) {
+        status = PSA_ERROR_INVALID_ARGUMENT;
+        goto exit;
+    }
+
+    memset(&operation->data.inputs, 0, sizeof(operation->data.inputs));
+
+    operation->alg = cipher_suite->algorithm;
+    operation->data.inputs.cipher_suite = *cipher_suite;
+
+#if defined(PSA_WANT_ALG_JPAKE)
+    if (operation->alg == PSA_ALG_JPAKE) {
+        psa_jpake_computation_stage_t *computation_stage =
+            &operation->computation_stage.jpake;
+
+        computation_stage->state = PSA_PAKE_STATE_SETUP;
+        computation_stage->sequence = PSA_PAKE_SEQ_INVALID;
+        computation_stage->input_step = PSA_PAKE_STEP_X1_X2;
+        computation_stage->output_step = PSA_PAKE_STEP_X1_X2;
+    } else
+#endif /* PSA_WANT_ALG_JPAKE */
+    {
+        status = PSA_ERROR_NOT_SUPPORTED;
+        goto exit;
+    }
+
+    operation->stage = PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS;
+
+    return PSA_SUCCESS;
+exit:
+    psa_pake_abort(operation);
+    return status;
+}
+
+psa_status_t psa_pake_set_password_key(
+    psa_pake_operation_t *operation,
+    mbedtls_svc_key_id_t password)
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_slot_t *slot = NULL;
+
+    if (operation->stage != PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    status = psa_get_and_lock_key_slot_with_policy(password, &slot,
+                                                   PSA_KEY_USAGE_DERIVE,
+                                                   operation->alg);
+    if (status != PSA_SUCCESS) {
+        goto exit;
+    }
+
+    psa_key_attributes_t attributes = {
+        .core = slot->attr
+    };
+
+    psa_key_type_t type = psa_get_key_type(&attributes);
+
+    if (type != PSA_KEY_TYPE_PASSWORD &&
+        type != PSA_KEY_TYPE_PASSWORD_HASH) {
+        status = PSA_ERROR_INVALID_ARGUMENT;
+        goto exit;
+    }
+
+    operation->data.inputs.password = mbedtls_calloc(1, slot->key.bytes);
+    if (operation->data.inputs.password == NULL) {
+        status = PSA_ERROR_INSUFFICIENT_MEMORY;
+        goto exit;
+    }
+
+    memcpy(operation->data.inputs.password, slot->key.data, slot->key.bytes);
+    operation->data.inputs.password_len = slot->key.bytes;
+    operation->data.inputs.attributes = attributes;
+exit:
+    if (status != PSA_SUCCESS) {
+        psa_pake_abort(operation);
+    }
+    unlock_status = psa_unlock_key_slot(slot);
+    return (status == PSA_SUCCESS) ? unlock_status : status;
+}
+
+psa_status_t psa_pake_set_user(
+    psa_pake_operation_t *operation,
+    const uint8_t *user_id,
+    size_t user_id_len)
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+    if (operation->stage != PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    if (user_id_len == 0) {
+        status = PSA_ERROR_INVALID_ARGUMENT;
+        goto exit;
+    }
+
+    if (operation->data.inputs.user_len != 0) {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    /* Allow only "client" or "server" values (temporary restriction). */
+    if ((user_id_len != sizeof(jpake_server_id) ||
+         memcmp(user_id, jpake_server_id, user_id_len) != 0) &&
+        (user_id_len != sizeof(jpake_client_id) ||
+         memcmp(user_id, jpake_client_id, user_id_len) != 0)) {
+        status = PSA_ERROR_NOT_SUPPORTED;
+        goto exit;
+    }
+
+    operation->data.inputs.user = mbedtls_calloc(1, user_id_len);
+    if (operation->data.inputs.user == NULL) {
+        status = PSA_ERROR_INSUFFICIENT_MEMORY;
+        goto exit;
+    }
+
+    memcpy(operation->data.inputs.user, user_id, user_id_len);
+    operation->data.inputs.user_len = user_id_len;
+
+    return PSA_SUCCESS;
+exit:
+    psa_pake_abort(operation);
+    return status;
+}
+
+psa_status_t psa_pake_set_peer(
+    psa_pake_operation_t *operation,
+    const uint8_t *peer_id,
+    size_t peer_id_len)
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+    if (operation->stage != PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    if (peer_id_len == 0) {
+        status = PSA_ERROR_INVALID_ARGUMENT;
+        goto exit;
+    }
+
+    if (operation->data.inputs.peer_len != 0) {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    /* Allow only "client" or "server" values (temporary restriction). */
+    if ((peer_id_len != sizeof(jpake_server_id) ||
+         memcmp(peer_id, jpake_server_id, peer_id_len) != 0) &&
+        (peer_id_len != sizeof(jpake_client_id) ||
+         memcmp(peer_id, jpake_client_id, peer_id_len) != 0)) {
+        status = PSA_ERROR_NOT_SUPPORTED;
+        goto exit;
+    }
+
+    operation->data.inputs.peer = mbedtls_calloc(1, peer_id_len);
+    if (operation->data.inputs.peer == NULL) {
+        status = PSA_ERROR_INSUFFICIENT_MEMORY;
+        goto exit;
+    }
+
+    memcpy(operation->data.inputs.peer, peer_id, peer_id_len);
+    operation->data.inputs.peer_len = peer_id_len;
+
+    return PSA_SUCCESS;
+exit:
+    psa_pake_abort(operation);
+    return status;
+}
+
+psa_status_t psa_pake_set_role(
+    psa_pake_operation_t *operation,
+    psa_pake_role_t role)
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+    if (operation->stage != PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    switch (operation->alg) {
+#if defined(PSA_WANT_ALG_JPAKE)
+        case PSA_ALG_JPAKE:
+            if (role == PSA_PAKE_ROLE_NONE) {
+                return PSA_SUCCESS;
+            }
+            status = PSA_ERROR_INVALID_ARGUMENT;
+            break;
+#endif
+        default:
+            (void) role;
+            status = PSA_ERROR_NOT_SUPPORTED;
+            goto exit;
+    }
+exit:
+    psa_pake_abort(operation);
+    return status;
+}
+
+/* Auxiliary function to convert core computation stage(step, sequence, state) to single driver step. */
+#if defined(PSA_WANT_ALG_JPAKE)
+static psa_crypto_driver_pake_step_t convert_jpake_computation_stage_to_driver_step(
+    psa_jpake_computation_stage_t *stage)
+{
+    switch (stage->state) {
+        case PSA_PAKE_OUTPUT_X1_X2:
+        case PSA_PAKE_INPUT_X1_X2:
+            switch (stage->sequence) {
+                case PSA_PAKE_X1_STEP_KEY_SHARE:
+                    return PSA_JPAKE_X1_STEP_KEY_SHARE;
+                case PSA_PAKE_X1_STEP_ZK_PUBLIC:
+                    return PSA_JPAKE_X1_STEP_ZK_PUBLIC;
+                case PSA_PAKE_X1_STEP_ZK_PROOF:
+                    return PSA_JPAKE_X1_STEP_ZK_PROOF;
+                case PSA_PAKE_X2_STEP_KEY_SHARE:
+                    return PSA_JPAKE_X2_STEP_KEY_SHARE;
+                case PSA_PAKE_X2_STEP_ZK_PUBLIC:
+                    return PSA_JPAKE_X2_STEP_ZK_PUBLIC;
+                case PSA_PAKE_X2_STEP_ZK_PROOF:
+                    return PSA_JPAKE_X2_STEP_ZK_PROOF;
+                default:
+                    return PSA_JPAKE_STEP_INVALID;
+            }
+            break;
+        case PSA_PAKE_OUTPUT_X2S:
+            switch (stage->sequence) {
+                case PSA_PAKE_X1_STEP_KEY_SHARE:
+                    return PSA_JPAKE_X2S_STEP_KEY_SHARE;
+                case PSA_PAKE_X1_STEP_ZK_PUBLIC:
+                    return PSA_JPAKE_X2S_STEP_ZK_PUBLIC;
+                case PSA_PAKE_X1_STEP_ZK_PROOF:
+                    return PSA_JPAKE_X2S_STEP_ZK_PROOF;
+                default:
+                    return PSA_JPAKE_STEP_INVALID;
+            }
+            break;
+        case PSA_PAKE_INPUT_X4S:
+            switch (stage->sequence) {
+                case PSA_PAKE_X1_STEP_KEY_SHARE:
+                    return PSA_JPAKE_X4S_STEP_KEY_SHARE;
+                case PSA_PAKE_X1_STEP_ZK_PUBLIC:
+                    return PSA_JPAKE_X4S_STEP_ZK_PUBLIC;
+                case PSA_PAKE_X1_STEP_ZK_PROOF:
+                    return PSA_JPAKE_X4S_STEP_ZK_PROOF;
+                default:
+                    return PSA_JPAKE_STEP_INVALID;
+            }
+            break;
+        default:
+            return PSA_JPAKE_STEP_INVALID;
+    }
+    return PSA_JPAKE_STEP_INVALID;
+}
+#endif /* PSA_WANT_ALG_JPAKE */
+
+static psa_status_t psa_pake_complete_inputs(
+    psa_pake_operation_t *operation)
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    /* Create copy of the inputs on stack as inputs share memory
+       with the driver context which will be setup by the driver. */
+    psa_crypto_driver_pake_inputs_t inputs = operation->data.inputs;
+
+    if (inputs.password_len == 0) {
+        return PSA_ERROR_BAD_STATE;
+    }
+
+    if (operation->alg == PSA_ALG_JPAKE) {
+        if (inputs.user_len == 0 || inputs.peer_len == 0) {
+            return PSA_ERROR_BAD_STATE;
+        }
+        if (memcmp(inputs.user, jpake_client_id, inputs.user_len) == 0 &&
+            memcmp(inputs.peer, jpake_server_id, inputs.peer_len) == 0) {
+            inputs.role = PSA_PAKE_ROLE_CLIENT;
+        } else
+        if (memcmp(inputs.user, jpake_server_id, inputs.user_len) == 0 &&
+            memcmp(inputs.peer, jpake_client_id, inputs.peer_len) == 0) {
+            inputs.role = PSA_PAKE_ROLE_SERVER;
+        }
+
+        if (inputs.role != PSA_PAKE_ROLE_CLIENT &&
+            inputs.role != PSA_PAKE_ROLE_SERVER) {
+            return PSA_ERROR_NOT_SUPPORTED;
+        }
+    }
+
+    /* Clear driver context */
+    mbedtls_platform_zeroize(&operation->data, sizeof(operation->data));
+
+    status = psa_driver_wrapper_pake_setup(operation, &inputs);
+
+    /* Driver is responsible for creating its own copy of the password. */
+    mbedtls_platform_zeroize(inputs.password, inputs.password_len);
+    mbedtls_free(inputs.password);
+
+    /* User and peer are translated to role. */
+    mbedtls_free(inputs.user);
+    mbedtls_free(inputs.peer);
+
+    if (status == PSA_SUCCESS) {
+#if defined(PSA_WANT_ALG_JPAKE)
+        if (operation->alg == PSA_ALG_JPAKE) {
+            operation->stage = PSA_PAKE_OPERATION_STAGE_COMPUTATION;
+            psa_jpake_computation_stage_t *computation_stage =
+                &operation->computation_stage.jpake;
+            computation_stage->state = PSA_PAKE_STATE_READY;
+            computation_stage->sequence = PSA_PAKE_SEQ_INVALID;
+            computation_stage->input_step = PSA_PAKE_STEP_X1_X2;
+            computation_stage->output_step = PSA_PAKE_STEP_X1_X2;
+        } else
+#endif /* PSA_WANT_ALG_JPAKE */
+        {
+            status = PSA_ERROR_NOT_SUPPORTED;
+        }
+    }
+    return status;
+}
+
+#if defined(PSA_WANT_ALG_JPAKE)
+static psa_status_t psa_jpake_output_prologue(
+    psa_pake_operation_t *operation,
+    psa_pake_step_t step)
+{
+    if (step != PSA_PAKE_STEP_KEY_SHARE &&
+        step != PSA_PAKE_STEP_ZK_PUBLIC &&
+        step != PSA_PAKE_STEP_ZK_PROOF) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    psa_jpake_computation_stage_t *computation_stage =
+        &operation->computation_stage.jpake;
+
+    if (computation_stage->state == PSA_PAKE_STATE_INVALID) {
+        return PSA_ERROR_BAD_STATE;
+    }
+
+    if (computation_stage->state != PSA_PAKE_STATE_READY &&
+        computation_stage->state != PSA_PAKE_OUTPUT_X1_X2 &&
+        computation_stage->state != PSA_PAKE_OUTPUT_X2S) {
+        return PSA_ERROR_BAD_STATE;
+    }
+
+    if (computation_stage->state == PSA_PAKE_STATE_READY) {
+        if (step != PSA_PAKE_STEP_KEY_SHARE) {
+            return PSA_ERROR_BAD_STATE;
+        }
+
+        switch (computation_stage->output_step) {
+            case PSA_PAKE_STEP_X1_X2:
+                computation_stage->state = PSA_PAKE_OUTPUT_X1_X2;
+                break;
+            case PSA_PAKE_STEP_X2S:
+                computation_stage->state = PSA_PAKE_OUTPUT_X2S;
+                break;
+            default:
+                return PSA_ERROR_BAD_STATE;
+        }
+
+        computation_stage->sequence = PSA_PAKE_X1_STEP_KEY_SHARE;
+    }
+
+    /* Check if step matches current sequence */
+    switch (computation_stage->sequence) {
+        case PSA_PAKE_X1_STEP_KEY_SHARE:
+        case PSA_PAKE_X2_STEP_KEY_SHARE:
+            if (step != PSA_PAKE_STEP_KEY_SHARE) {
+                return PSA_ERROR_BAD_STATE;
+            }
+            break;
+
+        case PSA_PAKE_X1_STEP_ZK_PUBLIC:
+        case PSA_PAKE_X2_STEP_ZK_PUBLIC:
+            if (step != PSA_PAKE_STEP_ZK_PUBLIC) {
+                return PSA_ERROR_BAD_STATE;
+            }
+            break;
+
+        case PSA_PAKE_X1_STEP_ZK_PROOF:
+        case PSA_PAKE_X2_STEP_ZK_PROOF:
+            if (step != PSA_PAKE_STEP_ZK_PROOF) {
+                return PSA_ERROR_BAD_STATE;
+            }
+            break;
+
+        default:
+            return PSA_ERROR_BAD_STATE;
+    }
+
+    return PSA_SUCCESS;
+}
+
+static psa_status_t psa_jpake_output_epilogue(
+    psa_pake_operation_t *operation)
+{
+    psa_jpake_computation_stage_t *computation_stage =
+        &operation->computation_stage.jpake;
+
+    if ((computation_stage->state == PSA_PAKE_OUTPUT_X1_X2 &&
+         computation_stage->sequence == PSA_PAKE_X2_STEP_ZK_PROOF) ||
+        (computation_stage->state == PSA_PAKE_OUTPUT_X2S &&
+         computation_stage->sequence == PSA_PAKE_X1_STEP_ZK_PROOF)) {
+        computation_stage->state = PSA_PAKE_STATE_READY;
+        computation_stage->output_step++;
+        computation_stage->sequence = PSA_PAKE_SEQ_INVALID;
+    } else {
+        computation_stage->sequence++;
+    }
+
+    return PSA_SUCCESS;
+}
+#endif /* PSA_WANT_ALG_JPAKE */
+
+psa_status_t psa_pake_output(
+    psa_pake_operation_t *operation,
+    psa_pake_step_t step,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length)
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_crypto_driver_pake_step_t driver_step = PSA_JPAKE_STEP_INVALID;
+    *output_length = 0;
+
+    if (operation->stage == PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) {
+        status = psa_pake_complete_inputs(operation);
+        if (status != PSA_SUCCESS) {
+            goto exit;
+        }
+    }
+
+    if (operation->stage != PSA_PAKE_OPERATION_STAGE_COMPUTATION) {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    if (output_size == 0) {
+        status = PSA_ERROR_INVALID_ARGUMENT;
+        goto exit;
+    }
+
+    switch (operation->alg) {
+#if defined(PSA_WANT_ALG_JPAKE)
+        case PSA_ALG_JPAKE:
+            status = psa_jpake_output_prologue(operation, step);
+            if (status != PSA_SUCCESS) {
+                goto exit;
+            }
+            driver_step = convert_jpake_computation_stage_to_driver_step(
+                &operation->computation_stage.jpake);
+            break;
+#endif /* PSA_WANT_ALG_JPAKE */
+        default:
+            (void) step;
+            status = PSA_ERROR_NOT_SUPPORTED;
+            goto exit;
+    }
+
+    status = psa_driver_wrapper_pake_output(operation, driver_step,
+                                            output, output_size, output_length);
+
+    if (status != PSA_SUCCESS) {
+        goto exit;
+    }
+
+    switch (operation->alg) {
+#if defined(PSA_WANT_ALG_JPAKE)
+        case PSA_ALG_JPAKE:
+            status = psa_jpake_output_epilogue(operation);
+            if (status != PSA_SUCCESS) {
+                goto exit;
+            }
+            break;
+#endif /* PSA_WANT_ALG_JPAKE */
+        default:
+            status = PSA_ERROR_NOT_SUPPORTED;
+            goto exit;
+    }
+
+    return PSA_SUCCESS;
+exit:
+    psa_pake_abort(operation);
+    return status;
+}
+
+#if defined(PSA_WANT_ALG_JPAKE)
+static psa_status_t psa_jpake_input_prologue(
+    psa_pake_operation_t *operation,
+    psa_pake_step_t step)
+{
+    if (step != PSA_PAKE_STEP_KEY_SHARE &&
+        step != PSA_PAKE_STEP_ZK_PUBLIC &&
+        step != PSA_PAKE_STEP_ZK_PROOF) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    psa_jpake_computation_stage_t *computation_stage =
+        &operation->computation_stage.jpake;
+
+    if (computation_stage->state == PSA_PAKE_STATE_INVALID) {
+        return PSA_ERROR_BAD_STATE;
+    }
+
+    if (computation_stage->state != PSA_PAKE_STATE_READY &&
+        computation_stage->state != PSA_PAKE_INPUT_X1_X2 &&
+        computation_stage->state != PSA_PAKE_INPUT_X4S) {
+        return PSA_ERROR_BAD_STATE;
+    }
+
+    if (computation_stage->state == PSA_PAKE_STATE_READY) {
+        if (step != PSA_PAKE_STEP_KEY_SHARE) {
+            return PSA_ERROR_BAD_STATE;
+        }
+
+        switch (computation_stage->input_step) {
+            case PSA_PAKE_STEP_X1_X2:
+                computation_stage->state = PSA_PAKE_INPUT_X1_X2;
+                break;
+            case PSA_PAKE_STEP_X2S:
+                computation_stage->state = PSA_PAKE_INPUT_X4S;
+                break;
+            default:
+                return PSA_ERROR_BAD_STATE;
+        }
+
+        computation_stage->sequence = PSA_PAKE_X1_STEP_KEY_SHARE;
+    }
+
+    /* Check if step matches current sequence */
+    switch (computation_stage->sequence) {
+        case PSA_PAKE_X1_STEP_KEY_SHARE:
+        case PSA_PAKE_X2_STEP_KEY_SHARE:
+            if (step != PSA_PAKE_STEP_KEY_SHARE) {
+                return PSA_ERROR_BAD_STATE;
+            }
+            break;
+
+        case PSA_PAKE_X1_STEP_ZK_PUBLIC:
+        case PSA_PAKE_X2_STEP_ZK_PUBLIC:
+            if (step != PSA_PAKE_STEP_ZK_PUBLIC) {
+                return PSA_ERROR_BAD_STATE;
+            }
+            break;
+
+        case PSA_PAKE_X1_STEP_ZK_PROOF:
+        case PSA_PAKE_X2_STEP_ZK_PROOF:
+            if (step != PSA_PAKE_STEP_ZK_PROOF) {
+                return PSA_ERROR_BAD_STATE;
+            }
+            break;
+
+        default:
+            return PSA_ERROR_BAD_STATE;
+    }
+
+    return PSA_SUCCESS;
+}
+
+static psa_status_t psa_jpake_input_epilogue(
+    psa_pake_operation_t *operation)
+{
+    psa_jpake_computation_stage_t *computation_stage =
+        &operation->computation_stage.jpake;
+
+    if ((computation_stage->state == PSA_PAKE_INPUT_X1_X2 &&
+         computation_stage->sequence == PSA_PAKE_X2_STEP_ZK_PROOF) ||
+        (computation_stage->state == PSA_PAKE_INPUT_X4S &&
+         computation_stage->sequence == PSA_PAKE_X1_STEP_ZK_PROOF)) {
+        computation_stage->state = PSA_PAKE_STATE_READY;
+        computation_stage->input_step++;
+        computation_stage->sequence = PSA_PAKE_SEQ_INVALID;
+    } else {
+        computation_stage->sequence++;
+    }
+
+    return PSA_SUCCESS;
+}
+#endif /* PSA_WANT_ALG_JPAKE */
+
+psa_status_t psa_pake_input(
+    psa_pake_operation_t *operation,
+    psa_pake_step_t step,
+    const uint8_t *input,
+    size_t input_length)
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_crypto_driver_pake_step_t driver_step = PSA_JPAKE_STEP_INVALID;
+
+    if (operation->stage == PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) {
+        status = psa_pake_complete_inputs(operation);
+        if (status != PSA_SUCCESS) {
+            goto exit;
+        }
+    }
+
+    if (operation->stage != PSA_PAKE_OPERATION_STAGE_COMPUTATION) {
+        status =  PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+    if (input_length == 0 || input_length > PSA_PAKE_INPUT_MAX_SIZE) {
+        status = PSA_ERROR_INVALID_ARGUMENT;
+        goto exit;
+    }
+
+    switch (operation->alg) {
+#if defined(PSA_WANT_ALG_JPAKE)
+        case PSA_ALG_JPAKE:
+            status = psa_jpake_input_prologue(operation, step);
+            if (status != PSA_SUCCESS) {
+                goto exit;
+            }
+            driver_step = convert_jpake_computation_stage_to_driver_step(
+                &operation->computation_stage.jpake);
+            break;
+#endif /* PSA_WANT_ALG_JPAKE */
+        default:
+            (void) step;
+            status = PSA_ERROR_NOT_SUPPORTED;
+            goto exit;
+    }
+
+    status = psa_driver_wrapper_pake_input(operation, driver_step,
+                                           input, input_length);
+
+    if (status != PSA_SUCCESS) {
+        goto exit;
+    }
+
+    switch (operation->alg) {
+#if defined(PSA_WANT_ALG_JPAKE)
+        case PSA_ALG_JPAKE:
+            status = psa_jpake_input_epilogue(operation);
+            if (status != PSA_SUCCESS) {
+                goto exit;
+            }
+            break;
+#endif /* PSA_WANT_ALG_JPAKE */
+        default:
+            status = PSA_ERROR_NOT_SUPPORTED;
+            goto exit;
+    }
+
+    return PSA_SUCCESS;
+exit:
+    psa_pake_abort(operation);
+    return status;
+}
+
+psa_status_t psa_pake_get_implicit_key(
+    psa_pake_operation_t *operation,
+    psa_key_derivation_operation_t *output)
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
+    uint8_t shared_key[MBEDTLS_PSA_JPAKE_BUFFER_SIZE];
+    size_t shared_key_len = 0;
+
+    if (operation->stage != PSA_PAKE_OPERATION_STAGE_COMPUTATION) {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
+
+#if defined(PSA_WANT_ALG_JPAKE)
+    if (operation->alg == PSA_ALG_JPAKE) {
+        psa_jpake_computation_stage_t *computation_stage =
+            &operation->computation_stage.jpake;
+        if (computation_stage->input_step != PSA_PAKE_STEP_DERIVE ||
+            computation_stage->output_step != PSA_PAKE_STEP_DERIVE) {
+            status = PSA_ERROR_BAD_STATE;
+            goto exit;
+        }
+    } else
+#endif /* PSA_WANT_ALG_JPAKE */
+    {
+        status = PSA_ERROR_NOT_SUPPORTED;
+        goto exit;
+    }
+
+    status = psa_driver_wrapper_pake_get_implicit_key(operation,
+                                                      shared_key,
+                                                      sizeof(shared_key),
+                                                      &shared_key_len);
+
+    if (status != PSA_SUCCESS) {
+        goto exit;
+    }
+
+    status = psa_key_derivation_input_bytes(output,
+                                            PSA_KEY_DERIVATION_INPUT_SECRET,
+                                            shared_key,
+                                            shared_key_len);
+
+    mbedtls_platform_zeroize(shared_key, sizeof(shared_key));
+exit:
+    abort_status = psa_pake_abort(operation);
+    return status == PSA_SUCCESS ? abort_status : status;
+}
+
+psa_status_t psa_pake_abort(
+    psa_pake_operation_t *operation)
+{
+    psa_status_t status = PSA_SUCCESS;
+
+    if (operation->stage == PSA_PAKE_OPERATION_STAGE_COMPUTATION) {
+        status = psa_driver_wrapper_pake_abort(operation);
+    }
+
+    if (operation->stage == PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) {
+        if (operation->data.inputs.password != NULL) {
+            mbedtls_platform_zeroize(operation->data.inputs.password,
+                                     operation->data.inputs.password_len);
+            mbedtls_free(operation->data.inputs.password);
+        }
+        if (operation->data.inputs.user != NULL) {
+            mbedtls_free(operation->data.inputs.user);
+        }
+        if (operation->data.inputs.peer != NULL) {
+            mbedtls_free(operation->data.inputs.peer);
+        }
+    }
+    memset(operation, 0, sizeof(psa_pake_operation_t));
+
+    return status;
+}
+
 #endif /* MBEDTLS_PSA_CRYPTO_C */
diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h
index 5260cf7..d3d0188 100644
--- a/library/psa_crypto_core.h
+++ b/library/psa_crypto_core.h
@@ -182,24 +182,6 @@
 }
 #endif
 
-/** Get the description of a key given its identifier and policy constraints
- *  and lock it.
- *
- * The key must have allow all the usage flags set in \p usage. If \p alg is
- * nonzero, the key must allow operations with this algorithm. If \p alg is
- * zero, the algorithm is not checked.
- *
- * In case of a persistent key, the function loads the description of the key
- * into a key slot if not already done.
- *
- * On success, the returned key slot is locked. It is the responsibility of
- * the caller to unlock the key slot when it does not access it anymore.
- */
-psa_status_t psa_get_and_lock_key_slot_with_policy(mbedtls_svc_key_id_t key,
-                                                   psa_key_slot_t **p_slot,
-                                                   psa_key_usage_t usage,
-                                                   psa_algorithm_t alg);
-
 /** Completely wipe a slot in memory, including its policy.
  *
  * Persistent storage is not affected.
diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h
index b167506..7d672d6 100644
--- a/library/psa_crypto_driver_wrappers.h
+++ b/library/psa_crypto_driver_wrappers.h
@@ -408,6 +408,34 @@
     size_t shared_secret_size,
     size_t *shared_secret_length);
 
+/*
+ * PAKE functions.
+ */
+psa_status_t psa_driver_wrapper_pake_setup(
+    psa_pake_operation_t *operation,
+    const psa_crypto_driver_pake_inputs_t *inputs);
+
+psa_status_t psa_driver_wrapper_pake_output(
+    psa_pake_operation_t *operation,
+    psa_crypto_driver_pake_step_t step,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length);
+
+psa_status_t psa_driver_wrapper_pake_input(
+    psa_pake_operation_t *operation,
+    psa_crypto_driver_pake_step_t step,
+    const uint8_t *input,
+    size_t input_length);
+
+psa_status_t psa_driver_wrapper_pake_get_implicit_key(
+    psa_pake_operation_t *operation,
+    uint8_t *output, size_t output_size,
+    size_t *output_length);
+
+psa_status_t psa_driver_wrapper_pake_abort(
+    psa_pake_operation_t *operation);
+
 #endif /* PSA_CRYPTO_DRIVER_WRAPPERS_H */
 
 /* End of automatically generated file. */
diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c
index 1f9a8cb..a537184 100644
--- a/library/psa_crypto_pake.c
+++ b/library/psa_crypto_pake.c
@@ -24,6 +24,7 @@
 
 #include <psa/crypto.h>
 #include "psa_crypto_core.h"
+#include "psa_crypto_pake.h"
 #include "psa_crypto_slot_management.h"
 
 #include <mbedtls/ecjpake.h>
@@ -78,23 +79,6 @@
  *   psa_pake_abort()
  */
 
-enum psa_pake_step {
-    PSA_PAKE_STEP_INVALID       = 0,
-    PSA_PAKE_STEP_X1_X2         = 1,
-    PSA_PAKE_STEP_X2S           = 2,
-    PSA_PAKE_STEP_DERIVE        = 3,
-};
-
-enum psa_pake_state {
-    PSA_PAKE_STATE_INVALID      = 0,
-    PSA_PAKE_STATE_SETUP        = 1,
-    PSA_PAKE_STATE_READY        = 2,
-    PSA_PAKE_OUTPUT_X1_X2       = 3,
-    PSA_PAKE_OUTPUT_X2S         = 4,
-    PSA_PAKE_INPUT_X1_X2        = 5,
-    PSA_PAKE_INPUT_X4S          = 6,
-};
-
 /*
  * The first PAKE step shares the same sequences of the second PAKE step
  * but with a second set of KEY_SHARE/ZK_PUBLIC/ZK_PROOF outputs/inputs.
@@ -156,16 +140,6 @@
  *   psa_pake_get_implicit_key()
  *   => Input & Output Step = PSA_PAKE_STEP_INVALID
  */
-enum psa_pake_sequence {
-    PSA_PAKE_SEQ_INVALID        = 0,
-    PSA_PAKE_X1_STEP_KEY_SHARE  = 1,    /* also X2S & X4S KEY_SHARE */
-    PSA_PAKE_X1_STEP_ZK_PUBLIC  = 2,    /* also X2S & X4S ZK_PUBLIC */
-    PSA_PAKE_X1_STEP_ZK_PROOF   = 3,    /* also X2S & X4S ZK_PROOF */
-    PSA_PAKE_X2_STEP_KEY_SHARE  = 4,
-    PSA_PAKE_X2_STEP_ZK_PUBLIC  = 5,
-    PSA_PAKE_X2_STEP_ZK_PROOF   = 6,
-    PSA_PAKE_SEQ_END            = 7,
-};
 
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
 static psa_status_t mbedtls_ecjpake_to_psa_error(int ret)
@@ -190,232 +164,16 @@
 #endif
 
 #if defined(MBEDTLS_PSA_BUILTIN_PAKE)
-psa_status_t psa_pake_setup(psa_pake_operation_t *operation,
-                            const psa_pake_cipher_suite_t *cipher_suite)
-{
-    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
-
-    /* A context must be freshly initialized before it can be set up. */
-    if (operation->alg != PSA_ALG_NONE) {
-        status = PSA_ERROR_BAD_STATE;
-        goto error;
-    }
-
-    if (cipher_suite == NULL ||
-        PSA_ALG_IS_PAKE(cipher_suite->algorithm) == 0 ||
-        (cipher_suite->type != PSA_PAKE_PRIMITIVE_TYPE_ECC &&
-         cipher_suite->type != PSA_PAKE_PRIMITIVE_TYPE_DH) ||
-        PSA_ALG_IS_HASH(cipher_suite->hash) == 0) {
-        status = PSA_ERROR_INVALID_ARGUMENT;
-        goto error;
-    }
-
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
-    if (cipher_suite->algorithm == PSA_ALG_JPAKE) {
-        if (cipher_suite->type != PSA_PAKE_PRIMITIVE_TYPE_ECC ||
-            cipher_suite->family != PSA_ECC_FAMILY_SECP_R1 ||
-            cipher_suite->bits != 256 ||
-            cipher_suite->hash != PSA_ALG_SHA_256) {
-            status = PSA_ERROR_NOT_SUPPORTED;
-            goto error;
-        }
-
-        operation->alg = cipher_suite->algorithm;
-
-        mbedtls_ecjpake_init(&operation->ctx.ecjpake);
-
-        operation->state = PSA_PAKE_STATE_SETUP;
-        operation->sequence = PSA_PAKE_SEQ_INVALID;
-        operation->input_step = PSA_PAKE_STEP_X1_X2;
-        operation->output_step = PSA_PAKE_STEP_X1_X2;
-
-        mbedtls_platform_zeroize(operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE);
-        operation->buffer_length = 0;
-        operation->buffer_offset = 0;
-
-        return PSA_SUCCESS;
-    } else
-#endif
-    status = PSA_ERROR_NOT_SUPPORTED;
-
-error:
-    psa_pake_abort(operation);
-    return status;
-}
-
-psa_status_t psa_pake_set_password_key(psa_pake_operation_t *operation,
-                                       mbedtls_svc_key_id_t password)
-{
-    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
-    psa_key_attributes_t attributes = psa_key_attributes_init();
-    psa_key_type_t type;
-    psa_key_usage_t usage;
-    psa_key_slot_t *slot = NULL;
-
-    if (operation->alg == PSA_ALG_NONE ||
-        operation->state != PSA_PAKE_STATE_SETUP) {
-        status = PSA_ERROR_BAD_STATE;
-        goto error;
-    }
-
-    status = psa_get_key_attributes(password, &attributes);
-    if (status != PSA_SUCCESS) {
-        goto error;
-    }
-
-    type = psa_get_key_type(&attributes);
-    usage = psa_get_key_usage_flags(&attributes);
-
-    psa_reset_key_attributes(&attributes);
-
-    if (type != PSA_KEY_TYPE_PASSWORD &&
-        type != PSA_KEY_TYPE_PASSWORD_HASH) {
-        status = PSA_ERROR_INVALID_ARGUMENT;
-        goto error;
-    }
-
-    if ((usage & PSA_KEY_USAGE_DERIVE) == 0) {
-        status = PSA_ERROR_NOT_PERMITTED;
-        goto error;
-    }
-
-    if (operation->password != NULL) {
-        return PSA_ERROR_BAD_STATE;
-    }
-
-    status = psa_get_and_lock_key_slot_with_policy(password, &slot,
-                                                   PSA_KEY_USAGE_DERIVE,
-                                                   PSA_ALG_JPAKE);
-    if (status != PSA_SUCCESS) {
-        return status;
-    }
-
-    operation->password = mbedtls_calloc(1, slot->key.bytes);
-    if (operation->password == NULL) {
-        psa_unlock_key_slot(slot);
-        return PSA_ERROR_INSUFFICIENT_MEMORY;
-    }
-    memcpy(operation->password, slot->key.data, slot->key.bytes);
-    operation->password_len = slot->key.bytes;
-
-    status = psa_unlock_key_slot(slot);
-    if (status != PSA_SUCCESS) {
-        return status;
-    }
-
-    return PSA_SUCCESS;
-
-error:
-    psa_pake_abort(operation);
-    return status;
-}
-
-psa_status_t psa_pake_set_user(psa_pake_operation_t *operation,
-                               const uint8_t *user_id,
-                               size_t user_id_len)
-{
-    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
-
-    if (operation->alg == PSA_ALG_NONE ||
-        operation->state != PSA_PAKE_STATE_SETUP) {
-        status = PSA_ERROR_BAD_STATE;
-        goto error;
-    }
-
-    if (user_id_len == 0 || user_id == NULL) {
-        status = PSA_ERROR_INVALID_ARGUMENT;
-        goto error;
-    }
-
-    status = PSA_ERROR_NOT_SUPPORTED;
-
-error:
-    psa_pake_abort(operation);
-    return status;
-}
-
-psa_status_t psa_pake_set_peer(psa_pake_operation_t *operation,
-                               const uint8_t *peer_id,
-                               size_t peer_id_len)
-{
-    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
-
-    if (operation->alg == PSA_ALG_NONE ||
-        operation->state != PSA_PAKE_STATE_SETUP) {
-        status = PSA_ERROR_BAD_STATE;
-        goto error;
-    }
-
-    if (peer_id_len == 0 || peer_id == NULL) {
-        status = PSA_ERROR_INVALID_ARGUMENT;
-        goto error;
-    }
-
-    status = PSA_ERROR_NOT_SUPPORTED;
-
-error:
-    psa_pake_abort(operation);
-    return status;
-}
-
-psa_status_t psa_pake_set_role(psa_pake_operation_t *operation,
-                               psa_pake_role_t role)
-{
-    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
-
-    if (operation->alg == PSA_ALG_NONE ||
-        operation->state != PSA_PAKE_STATE_SETUP) {
-        status = PSA_ERROR_BAD_STATE;
-        goto error;
-    }
-
-    if (role != PSA_PAKE_ROLE_NONE &&
-        role != PSA_PAKE_ROLE_FIRST &&
-        role != PSA_PAKE_ROLE_SECOND &&
-        role != PSA_PAKE_ROLE_CLIENT &&
-        role != PSA_PAKE_ROLE_SERVER) {
-        status = PSA_ERROR_INVALID_ARGUMENT;
-        goto error;
-    }
-
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
-    if (operation->alg == PSA_ALG_JPAKE) {
-        if (role != PSA_PAKE_ROLE_CLIENT &&
-            role != PSA_PAKE_ROLE_SERVER) {
-            return PSA_ERROR_NOT_SUPPORTED;
-        }
-
-        operation->role = role;
-
-        return PSA_SUCCESS;
-    } else
-#endif
-    status = PSA_ERROR_NOT_SUPPORTED;
-
-error:
-    psa_pake_abort(operation);
-    return status;
-}
-
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
-static psa_status_t psa_pake_ecjpake_setup(psa_pake_operation_t *operation)
+static psa_status_t psa_pake_ecjpake_setup(mbedtls_psa_pake_operation_t *operation)
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    mbedtls_ecjpake_role role;
+    mbedtls_ecjpake_role role = (operation->role == PSA_PAKE_ROLE_CLIENT) ?
+                                MBEDTLS_ECJPAKE_CLIENT : MBEDTLS_ECJPAKE_SERVER;
 
-    if (operation->role == PSA_PAKE_ROLE_CLIENT) {
-        role = MBEDTLS_ECJPAKE_CLIENT;
-    } else if (operation->role == PSA_PAKE_ROLE_SERVER) {
-        role = MBEDTLS_ECJPAKE_SERVER;
-    } else {
-        return PSA_ERROR_BAD_STATE;
-    }
+    mbedtls_ecjpake_init(&operation->ctx.jpake);
 
-    if (operation->password_len == 0) {
-        return PSA_ERROR_BAD_STATE;
-    }
-
-    ret = mbedtls_ecjpake_setup(&operation->ctx.ecjpake,
+    ret = mbedtls_ecjpake_setup(&operation->ctx.jpake,
                                 role,
                                 MBEDTLS_MD_SHA256,
                                 MBEDTLS_ECP_DP_SECP256R1,
@@ -423,39 +181,101 @@
                                 operation->password_len);
 
     mbedtls_platform_zeroize(operation->password, operation->password_len);
-    mbedtls_free(operation->password);
-    operation->password = NULL;
-    operation->password_len = 0;
 
     if (ret != 0) {
         return mbedtls_ecjpake_to_psa_error(ret);
     }
 
-    operation->state = PSA_PAKE_STATE_READY;
-
     return PSA_SUCCESS;
 }
 #endif
 
-static psa_status_t psa_pake_output_internal(
-    psa_pake_operation_t *operation,
-    psa_pake_step_t step,
+psa_status_t mbedtls_psa_pake_setup(mbedtls_psa_pake_operation_t *operation,
+                                    const psa_crypto_driver_pake_inputs_t *inputs)
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    size_t password_len = 0;
+    psa_pake_role_t role = PSA_PAKE_ROLE_NONE;
+    psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
+    size_t actual_password_len = 0;
+
+    status = psa_crypto_driver_pake_get_password_len(inputs, &password_len);
+    if (status != PSA_SUCCESS) {
+        return status;
+    }
+
+    status = psa_crypto_driver_pake_get_role(inputs, &role);
+    if (status != PSA_SUCCESS) {
+        return status;
+    }
+
+    status = psa_crypto_driver_pake_get_cipher_suite(inputs, &cipher_suite);
+    if (status != PSA_SUCCESS) {
+        return status;
+    }
+
+    operation->password = mbedtls_calloc(1, password_len);
+    if (operation->password == NULL) {
+        return PSA_ERROR_INSUFFICIENT_MEMORY;
+    }
+
+    status = psa_crypto_driver_pake_get_password(inputs, operation->password,
+                                                 password_len, &actual_password_len);
+    if (status != PSA_SUCCESS) {
+        goto error;
+    }
+
+    operation->password_len = actual_password_len;
+    operation->alg = cipher_suite.algorithm;
+
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
+    if (cipher_suite.algorithm == PSA_ALG_JPAKE) {
+        if (cipher_suite.type != PSA_PAKE_PRIMITIVE_TYPE_ECC ||
+            cipher_suite.family != PSA_ECC_FAMILY_SECP_R1 ||
+            cipher_suite.bits != 256 ||
+            cipher_suite.hash != PSA_ALG_SHA_256) {
+            status = PSA_ERROR_NOT_SUPPORTED;
+            goto error;
+        }
+
+        operation->role = role;
+
+        operation->buffer_length = 0;
+        operation->buffer_offset = 0;
+
+        status = psa_pake_ecjpake_setup(operation);
+        if (status != PSA_SUCCESS) {
+            goto error;
+        }
+
+        return PSA_SUCCESS;
+    } else
+#else
+    (void) operation;
+    (void) inputs;
+#endif
+    { status = PSA_ERROR_NOT_SUPPORTED; }
+
+error:
+    /* In case of failure of the setup of a multipart operation, the PSA driver interface
+     * specifies that the core does not call any other driver entry point thus does not
+     * call mbedtls_psa_pake_abort(). Therefore call it here to do the needed clean
+     * up like freeing the memory that may have been allocated to store the password.
+     */
+    mbedtls_psa_pake_abort(operation);
+    return status;
+}
+
+static psa_status_t mbedtls_psa_pake_output_internal(
+    mbedtls_psa_pake_operation_t *operation,
+    psa_crypto_driver_pake_step_t step,
     uint8_t *output,
     size_t output_size,
     size_t *output_length)
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     size_t length;
-
-    if (operation->alg == PSA_ALG_NONE ||
-        operation->state == PSA_PAKE_STATE_INVALID) {
-        return PSA_ERROR_BAD_STATE;
-    }
-
-    if (output == NULL || output_size == 0 || output_length == NULL) {
-        return PSA_ERROR_INVALID_ARGUMENT;
-    }
+    (void) step; // Unused parameter
 
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
     /*
@@ -473,77 +293,11 @@
      * to return the right parts on each step.
      */
     if (operation->alg == PSA_ALG_JPAKE) {
-        if (step != PSA_PAKE_STEP_KEY_SHARE &&
-            step != PSA_PAKE_STEP_ZK_PUBLIC &&
-            step != PSA_PAKE_STEP_ZK_PROOF) {
-            return PSA_ERROR_INVALID_ARGUMENT;
-        }
-
-        if (operation->state == PSA_PAKE_STATE_SETUP) {
-            status = psa_pake_ecjpake_setup(operation);
-            if (status != PSA_SUCCESS) {
-                return status;
-            }
-        }
-
-        if (operation->state != PSA_PAKE_STATE_READY &&
-            operation->state != PSA_PAKE_OUTPUT_X1_X2 &&
-            operation->state != PSA_PAKE_OUTPUT_X2S) {
-            return PSA_ERROR_BAD_STATE;
-        }
-
-        if (operation->state == PSA_PAKE_STATE_READY) {
-            if (step != PSA_PAKE_STEP_KEY_SHARE) {
-                return PSA_ERROR_BAD_STATE;
-            }
-
-            switch (operation->output_step) {
-                case PSA_PAKE_STEP_X1_X2:
-                    operation->state = PSA_PAKE_OUTPUT_X1_X2;
-                    break;
-                case PSA_PAKE_STEP_X2S:
-                    operation->state = PSA_PAKE_OUTPUT_X2S;
-                    break;
-                default:
-                    return PSA_ERROR_BAD_STATE;
-            }
-
-            operation->sequence = PSA_PAKE_X1_STEP_KEY_SHARE;
-        }
-
-        /* Check if step matches current sequence */
-        switch (operation->sequence) {
-            case PSA_PAKE_X1_STEP_KEY_SHARE:
-            case PSA_PAKE_X2_STEP_KEY_SHARE:
-                if (step != PSA_PAKE_STEP_KEY_SHARE) {
-                    return PSA_ERROR_BAD_STATE;
-                }
-                break;
-
-            case PSA_PAKE_X1_STEP_ZK_PUBLIC:
-            case PSA_PAKE_X2_STEP_ZK_PUBLIC:
-                if (step != PSA_PAKE_STEP_ZK_PUBLIC) {
-                    return PSA_ERROR_BAD_STATE;
-                }
-                break;
-
-            case PSA_PAKE_X1_STEP_ZK_PROOF:
-            case PSA_PAKE_X2_STEP_ZK_PROOF:
-                if (step != PSA_PAKE_STEP_ZK_PROOF) {
-                    return PSA_ERROR_BAD_STATE;
-                }
-                break;
-
-            default:
-                return PSA_ERROR_BAD_STATE;
-        }
-
         /* Initialize & write round on KEY_SHARE sequences */
-        if (operation->state == PSA_PAKE_OUTPUT_X1_X2 &&
-            operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE) {
-            ret = mbedtls_ecjpake_write_round_one(&operation->ctx.ecjpake,
+        if (step == PSA_JPAKE_X1_STEP_KEY_SHARE) {
+            ret = mbedtls_ecjpake_write_round_one(&operation->ctx.jpake,
                                                   operation->buffer,
-                                                  MBEDTLS_PSA_PAKE_BUFFER_SIZE,
+                                                  sizeof(operation->buffer),
                                                   &operation->buffer_length,
                                                   mbedtls_psa_get_random,
                                                   MBEDTLS_PSA_RANDOM_STATE);
@@ -552,11 +306,10 @@
             }
 
             operation->buffer_offset = 0;
-        } else if (operation->state == PSA_PAKE_OUTPUT_X2S &&
-                   operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE) {
-            ret = mbedtls_ecjpake_write_round_two(&operation->ctx.ecjpake,
+        } else if (step == PSA_JPAKE_X2S_STEP_KEY_SHARE) {
+            ret = mbedtls_ecjpake_write_round_two(&operation->ctx.jpake,
                                                   operation->buffer,
-                                                  MBEDTLS_PSA_PAKE_BUFFER_SIZE,
+                                                  sizeof(operation->buffer),
                                                   &operation->buffer_length,
                                                   mbedtls_psa_get_random,
                                                   MBEDTLS_PSA_RANDOM_STATE);
@@ -578,8 +331,7 @@
          * output with a length byte, even less a curve identifier, as that
          * information is already available.
          */
-        if (operation->state == PSA_PAKE_OUTPUT_X2S &&
-            operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE &&
+        if (step == PSA_JPAKE_X2S_STEP_KEY_SHARE &&
             operation->role == PSA_PAKE_ROLE_SERVER) {
             /* Skip ECParameters, with is 3 bytes (RFC 8422) */
             operation->buffer_offset += 3;
@@ -605,60 +357,44 @@
         operation->buffer_offset += length;
 
         /* Reset buffer after ZK_PROOF sequence */
-        if ((operation->state == PSA_PAKE_OUTPUT_X1_X2 &&
-             operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF) ||
-            (operation->state == PSA_PAKE_OUTPUT_X2S &&
-             operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF)) {
-            mbedtls_platform_zeroize(operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE);
+        if ((step == PSA_JPAKE_X2_STEP_ZK_PROOF) ||
+            (step == PSA_JPAKE_X2S_STEP_ZK_PROOF)) {
+            mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer));
             operation->buffer_length = 0;
             operation->buffer_offset = 0;
-
-            operation->state = PSA_PAKE_STATE_READY;
-            operation->output_step++;
-            operation->sequence = PSA_PAKE_SEQ_INVALID;
-        } else {
-            operation->sequence++;
         }
 
         return PSA_SUCCESS;
     } else
+#else
+    (void) step;
+    (void) output;
+    (void) output_size;
+    (void) output_length;
 #endif
-    return PSA_ERROR_NOT_SUPPORTED;
+    { return PSA_ERROR_NOT_SUPPORTED; }
 }
 
-psa_status_t psa_pake_output(psa_pake_operation_t *operation,
-                             psa_pake_step_t step,
-                             uint8_t *output,
-                             size_t output_size,
-                             size_t *output_length)
+psa_status_t mbedtls_psa_pake_output(mbedtls_psa_pake_operation_t *operation,
+                                     psa_crypto_driver_pake_step_t step,
+                                     uint8_t *output,
+                                     size_t output_size,
+                                     size_t *output_length)
 {
-    psa_status_t status = psa_pake_output_internal(
+    psa_status_t status = mbedtls_psa_pake_output_internal(
         operation, step, output, output_size, output_length);
 
-    if (status != PSA_SUCCESS) {
-        psa_pake_abort(operation);
-    }
-
     return status;
 }
 
-static psa_status_t psa_pake_input_internal(
-    psa_pake_operation_t *operation,
-    psa_pake_step_t step,
+static psa_status_t mbedtls_psa_pake_input_internal(
+    mbedtls_psa_pake_operation_t *operation,
+    psa_crypto_driver_pake_step_t step,
     const uint8_t *input,
     size_t input_length)
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
-
-    if (operation->alg == PSA_ALG_NONE ||
-        operation->state == PSA_PAKE_STATE_INVALID) {
-        return PSA_ERROR_BAD_STATE;
-    }
-
-    if (input == NULL || input_length == 0) {
-        return PSA_ERROR_INVALID_ARGUMENT;
-    }
+    (void) step; // Unused parameter
 
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
     /*
@@ -677,77 +413,6 @@
      * This causes any input error to be only detected on the last step.
      */
     if (operation->alg == PSA_ALG_JPAKE) {
-        if (step != PSA_PAKE_STEP_KEY_SHARE &&
-            step != PSA_PAKE_STEP_ZK_PUBLIC &&
-            step != PSA_PAKE_STEP_ZK_PROOF) {
-            return PSA_ERROR_INVALID_ARGUMENT;
-        }
-
-        const psa_pake_primitive_t prim = PSA_PAKE_PRIMITIVE(
-            PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256);
-        if (input_length > (size_t) PSA_PAKE_INPUT_SIZE(PSA_ALG_JPAKE, prim, step)) {
-            return PSA_ERROR_INVALID_ARGUMENT;
-        }
-
-        if (operation->state == PSA_PAKE_STATE_SETUP) {
-            status = psa_pake_ecjpake_setup(operation);
-            if (status != PSA_SUCCESS) {
-                return status;
-            }
-        }
-
-        if (operation->state != PSA_PAKE_STATE_READY &&
-            operation->state != PSA_PAKE_INPUT_X1_X2 &&
-            operation->state != PSA_PAKE_INPUT_X4S) {
-            return PSA_ERROR_BAD_STATE;
-        }
-
-        if (operation->state == PSA_PAKE_STATE_READY) {
-            if (step != PSA_PAKE_STEP_KEY_SHARE) {
-                return PSA_ERROR_BAD_STATE;
-            }
-
-            switch (operation->input_step) {
-                case PSA_PAKE_STEP_X1_X2:
-                    operation->state = PSA_PAKE_INPUT_X1_X2;
-                    break;
-                case PSA_PAKE_STEP_X2S:
-                    operation->state = PSA_PAKE_INPUT_X4S;
-                    break;
-                default:
-                    return PSA_ERROR_BAD_STATE;
-            }
-
-            operation->sequence = PSA_PAKE_X1_STEP_KEY_SHARE;
-        }
-
-        /* Check if step matches current sequence */
-        switch (operation->sequence) {
-            case PSA_PAKE_X1_STEP_KEY_SHARE:
-            case PSA_PAKE_X2_STEP_KEY_SHARE:
-                if (step != PSA_PAKE_STEP_KEY_SHARE) {
-                    return PSA_ERROR_BAD_STATE;
-                }
-                break;
-
-            case PSA_PAKE_X1_STEP_ZK_PUBLIC:
-            case PSA_PAKE_X2_STEP_ZK_PUBLIC:
-                if (step != PSA_PAKE_STEP_ZK_PUBLIC) {
-                    return PSA_ERROR_BAD_STATE;
-                }
-                break;
-
-            case PSA_PAKE_X1_STEP_ZK_PROOF:
-            case PSA_PAKE_X2_STEP_ZK_PROOF:
-                if (step != PSA_PAKE_STEP_ZK_PROOF) {
-                    return PSA_ERROR_BAD_STATE;
-                }
-                break;
-
-            default:
-                return PSA_ERROR_BAD_STATE;
-        }
-
         /*
          * Copy input to local buffer and format it as the Mbed TLS API
          * expects, i.e. as defined by draft-cragie-tls-ecjpake-01 section 7.
@@ -757,8 +422,7 @@
          * ECParameters structure - which means we have to prepend that when
          * we're a client.
          */
-        if (operation->state == PSA_PAKE_INPUT_X4S &&
-            operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE &&
+        if (step == PSA_JPAKE_X4S_STEP_KEY_SHARE &&
             operation->role == PSA_PAKE_ROLE_CLIENT) {
             /* We only support secp256r1. */
             /* This is the ECParameters structure defined by RFC 8422. */
@@ -766,11 +430,26 @@
                 3, /* named_curve */
                 0, 23 /* secp256r1 */
             };
+
+            if (operation->buffer_length + sizeof(ecparameters) >
+                sizeof(operation->buffer)) {
+                return PSA_ERROR_BUFFER_TOO_SMALL;
+            }
+
             memcpy(operation->buffer + operation->buffer_length,
                    ecparameters, sizeof(ecparameters));
             operation->buffer_length += sizeof(ecparameters);
         }
 
+        /*
+         * The core checks that input_length is smaller than
+         * PSA_PAKE_INPUT_MAX_SIZE.
+         * Thus no risk of integer overflow here.
+         */
+        if (operation->buffer_length + input_length + 1 > sizeof(operation->buffer)) {
+            return PSA_ERROR_BUFFER_TOO_SMALL;
+        }
+
         /* Write the length byte */
         operation->buffer[operation->buffer_length] = (uint8_t) input_length;
         operation->buffer_length += 1;
@@ -781,25 +460,23 @@
         operation->buffer_length += input_length;
 
         /* Load buffer at each last round ZK_PROOF */
-        if (operation->state == PSA_PAKE_INPUT_X1_X2 &&
-            operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF) {
-            ret = mbedtls_ecjpake_read_round_one(&operation->ctx.ecjpake,
+        if (step == PSA_JPAKE_X2_STEP_ZK_PROOF) {
+            ret = mbedtls_ecjpake_read_round_one(&operation->ctx.jpake,
                                                  operation->buffer,
                                                  operation->buffer_length);
 
-            mbedtls_platform_zeroize(operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE);
+            mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer));
             operation->buffer_length = 0;
 
             if (ret != 0) {
                 return mbedtls_ecjpake_to_psa_error(ret);
             }
-        } else if (operation->state == PSA_PAKE_INPUT_X4S &&
-                   operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF) {
-            ret = mbedtls_ecjpake_read_round_two(&operation->ctx.ecjpake,
+        } else if (step == PSA_JPAKE_X4S_STEP_ZK_PROOF) {
+            ret = mbedtls_ecjpake_read_round_two(&operation->ctx.jpake,
                                                  operation->buffer,
                                                  operation->buffer_length);
 
-            mbedtls_platform_zeroize(operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE);
+            mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer));
             operation->buffer_length = 0;
 
             if (ret != 0) {
@@ -807,113 +484,72 @@
             }
         }
 
-        if ((operation->state == PSA_PAKE_INPUT_X1_X2 &&
-             operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF) ||
-            (operation->state == PSA_PAKE_INPUT_X4S &&
-             operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF)) {
-            operation->state = PSA_PAKE_STATE_READY;
-            operation->input_step++;
-            operation->sequence = PSA_PAKE_SEQ_INVALID;
-        } else {
-            operation->sequence++;
-        }
-
         return PSA_SUCCESS;
     } else
+#else
+    (void) step;
+    (void) input;
+    (void) input_length;
 #endif
-    return PSA_ERROR_NOT_SUPPORTED;
+    { return PSA_ERROR_NOT_SUPPORTED; }
 }
 
-psa_status_t psa_pake_input(psa_pake_operation_t *operation,
-                            psa_pake_step_t step,
-                            const uint8_t *input,
-                            size_t input_length)
+psa_status_t mbedtls_psa_pake_input(mbedtls_psa_pake_operation_t *operation,
+                                    psa_crypto_driver_pake_step_t step,
+                                    const uint8_t *input,
+                                    size_t input_length)
 {
-    psa_status_t status = psa_pake_input_internal(
+    psa_status_t status = mbedtls_psa_pake_input_internal(
         operation, step, input, input_length);
 
-    if (status != PSA_SUCCESS) {
-        psa_pake_abort(operation);
-    }
-
     return status;
 }
 
-psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation,
-                                       psa_key_derivation_operation_t *output)
+psa_status_t mbedtls_psa_pake_get_implicit_key(
+    mbedtls_psa_pake_operation_t *operation,
+    uint8_t *output, size_t output_size,
+    size_t *output_length)
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
-
-    if (operation->alg == PSA_ALG_NONE ||
-        operation->state != PSA_PAKE_STATE_READY ||
-        operation->input_step != PSA_PAKE_STEP_DERIVE ||
-        operation->output_step != PSA_PAKE_STEP_DERIVE) {
-        status = PSA_ERROR_BAD_STATE;
-        goto error;
-    }
 
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
     if (operation->alg == PSA_ALG_JPAKE) {
-        ret = mbedtls_ecjpake_write_shared_key(&operation->ctx.ecjpake,
-                                               operation->buffer,
-                                               MBEDTLS_PSA_PAKE_BUFFER_SIZE,
-                                               &operation->buffer_length,
+        ret = mbedtls_ecjpake_write_shared_key(&operation->ctx.jpake,
+                                               output,
+                                               output_size,
+                                               output_length,
                                                mbedtls_psa_get_random,
                                                MBEDTLS_PSA_RANDOM_STATE);
         if (ret != 0) {
-            psa_pake_abort(operation);
             return mbedtls_ecjpake_to_psa_error(ret);
         }
 
-        status = psa_key_derivation_input_bytes(output,
-                                                PSA_KEY_DERIVATION_INPUT_SECRET,
-                                                operation->buffer,
-                                                operation->buffer_length);
-
-        mbedtls_platform_zeroize(operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE);
-
-        psa_pake_abort(operation);
-
-        return status;
+        return PSA_SUCCESS;
     } else
+#else
+    (void) output;
 #endif
-    status = PSA_ERROR_NOT_SUPPORTED;
-
-error:
-    psa_key_derivation_abort(output);
-    psa_pake_abort(operation);
-
-    return status;
+    { return PSA_ERROR_NOT_SUPPORTED; }
 }
 
-psa_status_t psa_pake_abort(psa_pake_operation_t *operation)
+psa_status_t mbedtls_psa_pake_abort(mbedtls_psa_pake_operation_t *operation)
 {
-    if (operation->alg == PSA_ALG_NONE) {
-        return PSA_SUCCESS;
-    }
+    mbedtls_platform_zeroize(operation->password, operation->password_len);
+    mbedtls_free(operation->password);
+    operation->password = NULL;
+    operation->password_len = 0;
 
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
     if (operation->alg == PSA_ALG_JPAKE) {
-        operation->input_step = PSA_PAKE_STEP_INVALID;
-        operation->output_step = PSA_PAKE_STEP_INVALID;
-        if (operation->password_len > 0) {
-            mbedtls_platform_zeroize(operation->password, operation->password_len);
-        }
-        mbedtls_free(operation->password);
-        operation->password = NULL;
-        operation->password_len = 0;
         operation->role = PSA_PAKE_ROLE_NONE;
-        mbedtls_platform_zeroize(operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE);
+        mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer));
         operation->buffer_length = 0;
         operation->buffer_offset = 0;
-        mbedtls_ecjpake_free(&operation->ctx.ecjpake);
+        mbedtls_ecjpake_free(&operation->ctx.jpake);
     }
 #endif
 
     operation->alg = PSA_ALG_NONE;
-    operation->state = PSA_PAKE_STATE_INVALID;
-    operation->sequence = PSA_PAKE_SEQ_INVALID;
 
     return PSA_SUCCESS;
 }
diff --git a/library/psa_crypto_pake.h b/library/psa_crypto_pake.h
new file mode 100644
index 0000000..001c987
--- /dev/null
+++ b/library/psa_crypto_pake.h
@@ -0,0 +1,171 @@
+/*
+ *  PSA PAKE layer on top of Mbed TLS software crypto
+ */
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef PSA_CRYPTO_PAKE_H
+#define PSA_CRYPTO_PAKE_H
+
+#include <psa/crypto.h>
+
+/** Set the session information for a password-authenticated key exchange.
+ *
+ * \note The signature of this function is that of a PSA driver
+ *       pake_setup entry point. This function behaves as a pake_setup
+ *       entry point as defined in the PSA driver interface specification for
+ *       transparent drivers.
+ *
+ * \param[in,out] operation     The operation object to set up. It must have
+ *                              been initialized but not set up yet.
+ * \param[in] inputs            Inputs required for PAKE operation (role, password,
+ *                              key lifetime, cipher suite)
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         The algorithm in \p cipher_suite is not a supported PAKE algorithm,
+ *         or the PAKE primitive in \p cipher_suite is not supported or not
+ *         compatible with the PAKE algorithm, or the hash algorithm in
+ *         \p cipher_suite is not supported or not compatible with the PAKE
+ *         algorithm and primitive.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ */
+psa_status_t mbedtls_psa_pake_setup(mbedtls_psa_pake_operation_t *operation,
+                                    const psa_crypto_driver_pake_inputs_t *inputs);
+
+
+/** Get output for a step of a password-authenticated key exchange.
+ *
+ * \note The signature of this function is that of a PSA driver
+ *       pake_output entry point. This function behaves as a pake_output
+ *       entry point as defined in the PSA driver interface specification for
+ *       transparent drivers.
+ *
+ * \param[in,out] operation    Active PAKE operation.
+ * \param step                 The step of the algorithm for which the output is
+ *                             requested.
+ * \param[out] output          Buffer where the output is to be written in the
+ *                             format appropriate for this driver \p step. Refer to
+ *                             the documentation of psa_crypto_driver_pake_step_t for
+ *                             more information.
+ * \param output_size          Size of the \p output buffer in bytes. This must
+ *                             be at least #PSA_PAKE_OUTPUT_SIZE(\p alg, \p
+ *                             primitive, \p step) where \p alg and
+ *                             \p primitive are the PAKE algorithm and primitive
+ *                             in the operation's cipher suite, and \p step is
+ *                             the output step.
+ *
+ * \param[out] output_length   On success, the number of bytes of the returned
+ *                             output.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ *         The size of the \p output buffer is too small.
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_DATA_CORRUPT
+ * \retval #PSA_ERROR_DATA_INVALID
+ */
+psa_status_t mbedtls_psa_pake_output(mbedtls_psa_pake_operation_t *operation,
+                                     psa_crypto_driver_pake_step_t step,
+                                     uint8_t *output,
+                                     size_t output_size,
+                                     size_t *output_length);
+
+/** Provide input for a step of a password-authenticated key exchange.
+ *
+ * \note The signature of this function is that of a PSA driver
+ *       pake_input entry point. This function behaves as a pake_input
+ *       entry point as defined in the PSA driver interface specification for
+ *       transparent drivers.
+ *
+ * \note The core checks that input_length is smaller than PSA_PAKE_INPUT_MAX_SIZE.
+ *
+ * \param[in,out] operation    Active PAKE operation.
+ * \param step                 The driver step for which the input is provided.
+ * \param[in] input            Buffer containing the input in the format
+ *                             appropriate for this \p step. Refer to the
+ *                             documentation of psa_crypto_driver_pake_step_t
+ *                             for more information.
+ * \param input_length         Size of the \p input buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ *         The verification fails for a zero-knowledge input step.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         the \p input is not valid for the \p operation's algorithm, cipher suite
+ *         or \p step.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         the \p input is not supported for the \p operation's algorithm, cipher
+ *         suite or \p step.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_DATA_CORRUPT
+ * \retval #PSA_ERROR_DATA_INVALID
+ */
+psa_status_t mbedtls_psa_pake_input(mbedtls_psa_pake_operation_t *operation,
+                                    psa_crypto_driver_pake_step_t step,
+                                    const uint8_t *input,
+                                    size_t input_length);
+
+/** Get implicitly confirmed shared secret from a PAKE.
+ *
+ * \note The signature of this function is that of a PSA driver
+ *       pake_get_implicit_key entry point. This function behaves as a
+ *       pake_get_implicit_key entry point as defined in the PSA driver
+ *       interface specification for transparent drivers.
+ *
+ * \param[in,out] operation    Active PAKE operation.
+ * \param[out] output          Output buffer for implicit key.
+ * \param      output_size     Size of the output buffer in bytes.
+ * \param[out] output_length   On success, the number of bytes of the implicit key.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         Input from a PAKE is not supported by the algorithm in the \p output
+ *         key derivation operation.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_DATA_CORRUPT
+ * \retval #PSA_ERROR_DATA_INVALID
+ */
+psa_status_t mbedtls_psa_pake_get_implicit_key(
+    mbedtls_psa_pake_operation_t *operation,
+    uint8_t *output, size_t output_size,
+    size_t *output_length);
+
+/** Abort a PAKE operation.
+ *
+ * \note The signature of this function is that of a PSA driver
+ *       pake_abort entry point. This function behaves as a pake_abort
+ *       entry point as defined in the PSA driver interface specification for
+ *       transparent drivers.
+ *
+ * \param[in,out] operation    The operation to abort.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ */
+psa_status_t mbedtls_psa_pake_abort(mbedtls_psa_pake_operation_t *operation);
+
+#endif /* PSA_CRYPTO_PAKE_H */
diff --git a/library/psa_crypto_se.c b/library/psa_crypto_se.c
index dee780f..9db3ded 100644
--- a/library/psa_crypto_se.c
+++ b/library/psa_crypto_se.c
@@ -22,7 +22,6 @@
 
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
 
-#include <assert.h>
 #include <stdint.h>
 #include <string.h>
 
@@ -313,10 +312,9 @@
     }
     /* Driver table entries are 0-initialized. 0 is not a valid driver
      * location because it means a transparent key. */
-#if defined(static_assert)
-    static_assert(PSA_KEY_LOCATION_LOCAL_STORAGE == 0,
-                  "Secure element support requires 0 to mean a local key");
-#endif
+    MBEDTLS_STATIC_ASSERT(PSA_KEY_LOCATION_LOCAL_STORAGE == 0,
+                          "Secure element support requires 0 to mean a local key");
+
     if (location == PSA_KEY_LOCATION_LOCAL_STORAGE) {
         return PSA_ERROR_INVALID_ARGUMENT;
     }
diff --git a/library/sha256.c b/library/sha256.c
index ca3fa5d..08822f4 100644
--- a/library/sha256.c
+++ b/library/sha256.c
@@ -23,7 +23,7 @@
  */
 
 #if defined(__aarch64__) && !defined(__ARM_FEATURE_CRYPTO) && \
-    defined(__clang__) &&  __clang_major__ < 18 && __clang_major__ > 3
+    defined(__clang__) && __clang_major__ >= 4
 /* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
  *
  * The intrinsic declaration are guarded by predefined ACLE macros in clang:
@@ -35,9 +35,14 @@
  * at the top of this file, before any includes.
  */
 #define __ARM_FEATURE_CRYPTO 1
-#define NEED_TARGET_OPTIONS
-#endif /* __aarch64__ && __clang__ &&
-          !__ARM_FEATURE_CRYPTO && __clang_major__ < 18 && __clang_major__ > 3 */
+/* See: https://arm-software.github.io/acle/main/acle.html#cryptographic-extensions
+ *
+ * `__ARM_FEATURE_CRYPTO` is deprecated, but we need to continue to specify it
+ * for older compilers.
+ */
+#define __ARM_FEATURE_SHA2   1
+#define MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG
+#endif
 
 #include "common.h"
 
@@ -55,7 +60,7 @@
 #  if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
     defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
 /* *INDENT-OFF* */
-#    if !defined(__ARM_FEATURE_CRYPTO) || defined(NEED_TARGET_OPTIONS)
+#    if !defined(__ARM_FEATURE_CRYPTO) || defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG)
 #      if defined(__clang__)
 #        if __clang_major__ < 4
 #          error "A more recent Clang is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
diff --git a/library/sha512.c b/library/sha512.c
index bc92a8d..67acfee 100644
--- a/library/sha512.c
+++ b/library/sha512.c
@@ -23,8 +23,7 @@
  */
 
 #if defined(__aarch64__) && !defined(__ARM_FEATURE_SHA512) && \
-    defined(__clang__) &&  __clang_major__ < 18 && \
-    __clang_major__ >= 13 && __clang_minor__ > 0 && __clang_patchlevel__ > 0
+    defined(__clang__) && __clang_major__ >= 7
 /* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
  *
  * The intrinsic declaration are guarded by predefined ACLE macros in clang:
@@ -36,11 +35,8 @@
  * at the top of this file, before any includes.
  */
 #define __ARM_FEATURE_SHA512 1
-#define NEED_TARGET_OPTIONS
-#endif /* __aarch64__ && __clang__ &&
-          !__ARM_FEATURE_SHA512 && __clang_major__ < 18 &&
-          __clang_major__ >= 13 && __clang_minor__ > 0 &&
-          __clang_patchlevel__ > 0 */
+#define MBEDTLS_ENABLE_ARM_SHA3_EXTENSIONS_COMPILER_FLAG
+#endif
 
 #include "common.h"
 
@@ -78,15 +74,11 @@
  * Clang == 13.0.0 same as clang 12 (only seen on macOS)
  * Clang >= 13.0.1 has __ARM_FEATURE_SHA512 and intrinsics
  */
-#    if !defined(__ARM_FEATURE_SHA512) || defined(NEED_TARGET_OPTIONS)
+#    if !defined(__ARM_FEATURE_SHA512) || defined(MBEDTLS_ENABLE_ARM_SHA3_EXTENSIONS_COMPILER_FLAG)
        /* Test Clang first, as it defines __GNUC__ */
 #      if defined(__clang__)
 #        if __clang_major__ < 7
 #          error "A more recent Clang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
-#        elif __clang_major__ < 13 || \
-              (__clang_major__ == 13 && __clang_minor__ == 0 && \
-               __clang_patchlevel__ == 0)
-           /* We implement the intrinsics with inline assembler, so don't error */
 #        else
 #          pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
 #          define MBEDTLS_POP_TARGET_PRAGMA
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index 1cad588..18c19f9 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -5599,8 +5599,10 @@
     n = (len < ssl->in_msglen)
         ? len : ssl->in_msglen;
 
-    memcpy(buf, ssl->in_offt, n);
-    ssl->in_msglen -= n;
+    if (len != 0) {
+        memcpy(buf, ssl->in_offt, n);
+        ssl->in_msglen -= n;
+    }
 
     /* Zeroising the plaintext buffer to erase unused application data
        from the memory. */
@@ -5676,7 +5678,9 @@
          */
         ssl->out_msglen  = len;
         ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
-        memcpy(ssl->out_msg, buf, len);
+        if (len > 0) {
+            memcpy(ssl->out_msg, buf, len);
+        }
 
         if ((ret = mbedtls_ssl_write_record(ssl, SSL_FORCE_FLUSH)) != 0) {
             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_record", ret);
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index c13f2f0..b17da06 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -25,8 +25,6 @@
 
 #if defined(MBEDTLS_SSL_TLS_C)
 
-#include <assert.h>
-
 #include "mbedtls/platform.h"
 
 #include "mbedtls/ssl.h"
@@ -1196,17 +1194,15 @@
         size_t sig_algs_len = 0;
         uint16_t *p;
 
-#if defined(static_assert)
-        static_assert(MBEDTLS_SSL_MAX_SIG_ALG_LIST_LEN
-                      <= (SIZE_MAX - (2 * sizeof(uint16_t))),
-                      "MBEDTLS_SSL_MAX_SIG_ALG_LIST_LEN too big");
-#endif
+        MBEDTLS_STATIC_ASSERT(MBEDTLS_SSL_MAX_SIG_ALG_LIST_LEN
+                              <= (SIZE_MAX - (2 * sizeof(uint16_t))),
+                              "MBEDTLS_SSL_MAX_SIG_ALG_LIST_LEN too big");
 
         for (md = sig_hashes; *md != MBEDTLS_MD_NONE; md++) {
             if (mbedtls_ssl_hash_from_md_alg(*md) == MBEDTLS_SSL_HASH_NONE) {
                 continue;
             }
-#if defined(MBEDTLS_ECDSA_C)
+#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
             sig_algs_len += sizeof(uint16_t);
 #endif
 
@@ -1234,7 +1230,7 @@
             if (hash == MBEDTLS_SSL_HASH_NONE) {
                 continue;
             }
-#if defined(MBEDTLS_ECDSA_C)
+#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
             *p = ((hash << 8) | MBEDTLS_SSL_SIG_ECDSA);
             p++;
 #endif
@@ -1949,14 +1945,19 @@
 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
+static const uint8_t jpake_server_id[] = { 's', 'e', 'r', 'v', 'e', 'r' };
+static const uint8_t jpake_client_id[] = { 'c', 'l', 'i', 'e', 'n', 't' };
+
 static psa_status_t mbedtls_ssl_set_hs_ecjpake_password_common(
     mbedtls_ssl_context *ssl,
     mbedtls_svc_key_id_t pwd)
 {
     psa_status_t status;
-    psa_pake_role_t psa_role;
     psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
-
+    const uint8_t *user = NULL;
+    size_t user_len = 0;
+    const uint8_t *peer = NULL;
+    size_t peer_len = 0;
     psa_pake_cs_set_algorithm(&cipher_suite, PSA_ALG_JPAKE);
     psa_pake_cs_set_primitive(&cipher_suite,
                               PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC,
@@ -1970,12 +1971,23 @@
     }
 
     if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
-        psa_role = PSA_PAKE_ROLE_SERVER;
+        user = jpake_server_id;
+        user_len = sizeof(jpake_server_id);
+        peer = jpake_client_id;
+        peer_len = sizeof(jpake_client_id);
     } else {
-        psa_role = PSA_PAKE_ROLE_CLIENT;
+        user = jpake_client_id;
+        user_len = sizeof(jpake_client_id);
+        peer = jpake_server_id;
+        peer_len = sizeof(jpake_server_id);
     }
 
-    status = psa_pake_set_role(&ssl->handshake->psa_pake_ctx, psa_role);
+    status = psa_pake_set_user(&ssl->handshake->psa_pake_ctx, user, user_len);
+    if (status != PSA_SUCCESS) {
+        return status;
+    }
+
+    status = psa_pake_set_peer(&ssl->handshake->psa_pake_ctx, peer, peer_len);
     if (status != PSA_SUCCESS) {
         return status;
     }
@@ -4979,22 +4991,25 @@
  */
 static uint16_t ssl_preset_default_sig_algs[] = {
 
-#if defined(MBEDTLS_ECDSA_C) &&  defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA) && \
+#if defined(MBEDTLS_PK_CAN_ECDSA_SOME) &&  \
+    defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA) && \
     defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
     MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256,
-#endif /* MBEDTLS_ECDSA_C && MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA &&
+#endif /* MBEDTLS_PK_CAN_ECDSA_SOME && MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA &&
           MBEDTLS_ECP_DP_SECP256R1_ENABLED */
 
-#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA) && \
+#if defined(MBEDTLS_PK_CAN_ECDSA_SOME) && \
+    defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA) && \
     defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
     MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384,
-#endif /* MBEDTLS_ECDSA_C && MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA&&
+#endif /* MBEDTLS_PK_CAN_ECDSA_SOME && MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA&&
           MBEDTLS_ECP_DP_SECP384R1_ENABLED */
 
-#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_HAS_ALG_SHA_512_VIA_MD_OR_PSA_BASED_ON_USE_PSA) && \
+#if defined(MBEDTLS_PK_CAN_ECDSA_SOME) && \
+    defined(MBEDTLS_HAS_ALG_SHA_512_VIA_MD_OR_PSA_BASED_ON_USE_PSA) && \
     defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
     MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512,
-#endif /* MBEDTLS_ECDSA_C && MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA&&
+#endif /* MBEDTLS_PK_CAN_ECDSA_SOME && MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA&&
           MBEDTLS_ECP_DP_SECP521R1_ENABLED */
 
 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \
@@ -5034,7 +5049,7 @@
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 static uint16_t ssl_tls12_preset_default_sig_algs[] = {
 #if defined(MBEDTLS_HAS_ALG_SHA_512_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
-#if defined(MBEDTLS_ECDSA_C)
+#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
     MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA512),
 #endif
 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
@@ -5045,7 +5060,7 @@
 #endif
 #endif /* MBEDTLS_HAS_ALG_SHA_512_VIA_MD_OR_PSA_BASED_ON_USE_PSA*/
 #if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
-#if defined(MBEDTLS_ECDSA_C)
+#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
     MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA384),
 #endif
 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
@@ -5056,7 +5071,7 @@
 #endif
 #endif /* MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA*/
 #if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
-#if defined(MBEDTLS_ECDSA_C)
+#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
     MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA256),
 #endif
 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c
index 0806f7f..631331d 100644
--- a/library/ssl_tls12_server.c
+++ b/library/ssl_tls12_server.c
@@ -1510,10 +1510,9 @@
             MBEDTLS_TLS_SIG_NONE
         };
 
-#if defined(static_assert)
-        static_assert(sizeof(default_sig_algs) / sizeof(default_sig_algs[0]) <=
-                      MBEDTLS_RECEIVED_SIG_ALGS_SIZE, "default_sig_algs is too big");
-#endif
+        MBEDTLS_STATIC_ASSERT(sizeof(default_sig_algs) / sizeof(default_sig_algs[0])
+                              <= MBEDTLS_RECEIVED_SIG_ALGS_SIZE,
+                              "default_sig_algs is too big");
 
         memcpy(received_sig_algs, default_sig_algs, sizeof(default_sig_algs));
     }
diff --git a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja
index aa11d4e..08da774 100644
--- a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja
+++ b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja
@@ -28,6 +28,7 @@
 #include "psa_crypto_driver_wrappers.h"
 #include "psa_crypto_hash.h"
 #include "psa_crypto_mac.h"
+#include "psa_crypto_pake.h"
 #include "psa_crypto_rsa.h"
 
 #include "mbedtls/platform.h"
@@ -2790,4 +2791,162 @@
     }
  }
 
+psa_status_t psa_driver_wrapper_pake_setup(
+    psa_pake_operation_t *operation,
+    const psa_crypto_driver_pake_inputs_t *inputs )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+    psa_key_location_t location =
+            PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime( &inputs->attributes ) );
+
+    switch( location )
+    {
+        case PSA_KEY_LOCATION_LOCAL_STORAGE:
+            /* Key is stored in the slot in export representation, so
+             * cycle through all known transparent accelerators */
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+            status = mbedtls_test_transparent_pake_setup(
+                        &operation->data.ctx.transparent_test_driver_ctx,
+                        inputs );
+            if( status == PSA_SUCCESS )
+                operation->id = MBEDTLS_TEST_TRANSPARENT_DRIVER_ID;
+            /* Declared with fallback == true */
+            if( status != PSA_ERROR_NOT_SUPPORTED )
+                return( status );
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+#if defined(MBEDTLS_PSA_BUILTIN_PAKE)
+            status = mbedtls_psa_pake_setup( &operation->data.ctx.mbedtls_ctx,
+                        inputs );
+            if( status == PSA_SUCCESS )
+                operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID;
+            return status;
+#endif
+            return( PSA_ERROR_NOT_SUPPORTED );
+        /* Add cases for opaque driver here */
+        default:
+            /* Key is declared with a lifetime not known to us */
+            (void)operation;
+            (void)inputs;
+            (void)status;
+            return( PSA_ERROR_INVALID_ARGUMENT );
+    }
+}
+psa_status_t psa_driver_wrapper_pake_output(
+    psa_pake_operation_t *operation,
+    psa_crypto_driver_pake_step_t step,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length )
+{
+    switch( operation->id )
+    {
+#if defined(MBEDTLS_PSA_BUILTIN_PAKE)
+        case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
+            return( mbedtls_psa_pake_output( &operation->data.ctx.mbedtls_ctx, step,
+                                             output, output_size, output_length ) );
+#endif /* MBEDTLS_PSA_BUILTIN_PAKE */
+
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
+            return( mbedtls_test_transparent_pake_output(
+                        &operation->data.ctx.transparent_test_driver_ctx,
+                        step, output, output_size, output_length ) );
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+        default:
+            (void) step;
+            (void) output;
+            (void) output_size;
+            (void) output_length;
+            return( PSA_ERROR_INVALID_ARGUMENT );
+    }
+}
+
+psa_status_t psa_driver_wrapper_pake_input(
+    psa_pake_operation_t *operation,
+    psa_crypto_driver_pake_step_t step,
+    const uint8_t *input,
+    size_t input_length )
+{
+    switch( operation->id )
+    {
+#if defined(MBEDTLS_PSA_BUILTIN_PAKE)
+        case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
+            return( mbedtls_psa_pake_input( &operation->data.ctx.mbedtls_ctx,
+                                            step, input,
+                                            input_length ) );
+#endif /* MBEDTLS_PSA_BUILTIN_PAKE */
+
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
+            return( mbedtls_test_transparent_pake_input(
+                        &operation->data.ctx.transparent_test_driver_ctx,
+                        step,
+                        input, input_length ) );
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+        default:
+            (void) step;
+            (void) input;
+            (void) input_length;
+            return( PSA_ERROR_INVALID_ARGUMENT );
+    }
+}
+
+psa_status_t psa_driver_wrapper_pake_get_implicit_key(
+    psa_pake_operation_t *operation,
+    uint8_t *output, size_t output_size,
+    size_t *output_length )
+{
+    switch( operation->id )
+    {
+#if defined(MBEDTLS_PSA_BUILTIN_PAKE)
+        case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
+            return( mbedtls_psa_pake_get_implicit_key( &operation->data.ctx.mbedtls_ctx,
+                                                       output, output_size, output_length ) );
+#endif /* MBEDTLS_PSA_BUILTIN_PAKE */
+
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
+            return( mbedtls_test_transparent_pake_get_implicit_key(
+                        &operation->data.ctx.transparent_test_driver_ctx,
+                        output, output_size, output_length ) );
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+        default:
+            (void) output;
+            (void) output_size;
+            (void) output_length;
+            return( PSA_ERROR_INVALID_ARGUMENT );
+    }
+}
+
+psa_status_t psa_driver_wrapper_pake_abort(
+    psa_pake_operation_t * operation )
+{
+    switch( operation->id )
+    {
+#if defined(MBEDTLS_PSA_BUILTIN_PAKE)
+        case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
+            return( mbedtls_psa_pake_abort( &operation->data.ctx.mbedtls_ctx ) );
+#endif /* MBEDTLS_PSA_BUILTIN_PAKE */
+
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
+            return( mbedtls_test_transparent_pake_abort(
+                        &operation->data.ctx.transparent_test_driver_ctx ) );
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+        default:
+            return( PSA_ERROR_INVALID_ARGUMENT );
+    }
+}
+
 #endif /* MBEDTLS_PSA_CRYPTO_C */
diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile
index 1b122ee..e638caf 100644
--- a/tests/data_files/Makefile
+++ b/tests/data_files/Makefile
@@ -1306,6 +1306,11 @@
 	$(FAKETIME) -f -3650d $(OPENSSL) req -x509 -subj="/C=NL/O=PKCS7/CN=PKCS7 Cert Expired" -sha256 -nodes -days 365  -newkey rsa:2048 -keyout pkcs7-rsa-expired.key -out pkcs7-rsa-expired.crt
 all_final += pkcs7-rsa-expired.crt
 
+# File with an otherwise valid signature signed with an expired cert
+pkcs7_data_rsa_expired.der: pkcs7-rsa-expired.key pkcs7-rsa-expired.crt pkcs7_data.bin
+	$(OPENSSL) smime -sign -binary -in pkcs7_data.bin -out $@ -md sha256 -inkey pkcs7-rsa-expired.key -signer pkcs7-rsa-expired.crt -noattr -outform DER -out $@
+all_final += pkcs7_data_rsa_expired.der
+
 # Convert signing certs to DER for testing PEM-free builds
 pkcs7-rsa-sha256-1.der: $(pkcs7_test_cert_1)
 	$(OPENSSL) x509 -in pkcs7-rsa-sha256-1.crt -out $@ -outform DER
@@ -1315,6 +1320,10 @@
 	$(OPENSSL) x509 -in pkcs7-rsa-sha256-2.crt -out $@ -outform DER
 all_final += pkcs7-rsa-sha256-2.der
 
+pkcs7-rsa-expired.der: pkcs7-rsa-expired.crt
+	$(OPENSSL) x509 -in pkcs7-rsa-expired.crt -out $@ -outform DER
+all_final += pkcs7-rsa-expired.der
+
 # pkcs7 signature file over zero-len data
 pkcs7_zerolendata_detached.der: pkcs7_zerolendata.bin pkcs7-rsa-sha256-1.key pkcs7-rsa-sha256-1.crt
 	$(OPENSSL) smime -sign -md sha256 -nocerts -noattr -in pkcs7_zerolendata.bin -inkey pkcs7-rsa-sha256-1.key -outform DER -binary -signer pkcs7-rsa-sha256-1.crt -out pkcs7_zerolendata_detached.der
@@ -1384,6 +1393,38 @@
 	echo 'a1' | xxd -r -p | dd of=$@ bs=1 seek=810 conv=notrunc
 all_final += pkcs7_signerInfo_2_invalid_tag.der
 
+# pkcs7 signature file with corrupted signer info[1]
+pkcs7_data_signed_badsigner1_badsize.der: pkcs7_data_3_signed.der
+	cp pkcs7_data_3_signed.der $@
+	echo '72' | xxd -p -r | dd of=$@ bs=1 seek=438 conv=notrunc
+all_final += pkcs7_data_signed_badsigner1_badsize.der
+
+pkcs7_data_signed_badsigner1_badtag.der: pkcs7_data_3_signed.der
+	cp pkcs7_data_3_signed.der $@
+	echo 'a1' | xxd -p -r | dd of=$@ bs=1 seek=442 conv=notrunc
+all_final += pkcs7_data_signed_badsigner1_badtag.der
+
+pkcs7_data_signed_badsigner1_fuzzbad.der: pkcs7_data_3_signed.der
+	cp pkcs7_data_3_signed.der $@
+	echo 'a1' | xxd -p -r | dd of=$@ bs=1 seek=550 conv=notrunc
+all_final += pkcs7_data_signed_badsigner1_fuzzbad.der
+
+# pkcs7 signature file with corrupted signer info[2]
+pkcs7_data_signed_badsigner2_badsize.der: pkcs7_data_3_signed.der
+	cp pkcs7_data_3_signed.der $@
+	echo '72'| xxd -p -r | dd of=$@ bs=1 seek=813 conv=notrunc
+all_final += pkcs7_data_signed_badsigner2_badsize
+
+pkcs7_data_signed_badsigner2_badtag.der: pkcs7_data_3_signed.der
+	cp pkcs7_data_3_signed.der $@
+	echo 'a1'| xxd -p -r | dd of=$@ bs=1 seek=817 conv=notrunc
+all_final += pkcs7_data_signed_badsigner2_badtag
+
+pkcs7_data_signed_badsigner2_fuzzbad.der: pkcs7_data_3_signed.der
+	cp pkcs7_data_3_signed.der $@
+	echo 'a1'| xxd -p -r | dd of=$@ bs=1 seek=925 conv=notrunc
+all_final += pkcs7_data_signed_badsigner2_fuzzbad
+
 # pkcs7 file with version 2
 pkcs7_data_cert_signed_v2.der: pkcs7_data_cert_signed_sha256.der
 	cp pkcs7_data_cert_signed_sha256.der $@
diff --git a/tests/data_files/pkcs7-rsa-expired.der b/tests/data_files/pkcs7-rsa-expired.der
new file mode 100644
index 0000000..508ec5c
--- /dev/null
+++ b/tests/data_files/pkcs7-rsa-expired.der
Binary files differ
diff --git a/tests/data_files/pkcs7_data_no_signers.der b/tests/data_files/pkcs7_data_no_signers.der
new file mode 100644
index 0000000..b75c991
--- /dev/null
+++ b/tests/data_files/pkcs7_data_no_signers.der
Binary files differ
diff --git a/tests/data_files/pkcs7_data_rsa_expired.der b/tests/data_files/pkcs7_data_rsa_expired.der
new file mode 100644
index 0000000..63af49d
--- /dev/null
+++ b/tests/data_files/pkcs7_data_rsa_expired.der
Binary files differ
diff --git a/tests/data_files/pkcs7_data_signed_badsigner1_badsize.der b/tests/data_files/pkcs7_data_signed_badsigner1_badsize.der
new file mode 100644
index 0000000..da7f3a9
--- /dev/null
+++ b/tests/data_files/pkcs7_data_signed_badsigner1_badsize.der
Binary files differ
diff --git a/tests/data_files/pkcs7_data_signed_badsigner1_badtag.der b/tests/data_files/pkcs7_data_signed_badsigner1_badtag.der
new file mode 100644
index 0000000..402b910
--- /dev/null
+++ b/tests/data_files/pkcs7_data_signed_badsigner1_badtag.der
Binary files differ
diff --git a/tests/data_files/pkcs7_data_signed_badsigner1_fuzzbad.der b/tests/data_files/pkcs7_data_signed_badsigner1_fuzzbad.der
new file mode 100644
index 0000000..e19c54a
--- /dev/null
+++ b/tests/data_files/pkcs7_data_signed_badsigner1_fuzzbad.der
Binary files differ
diff --git a/tests/data_files/pkcs7_data_signed_badsigner2_badsize.der b/tests/data_files/pkcs7_data_signed_badsigner2_badsize.der
new file mode 100644
index 0000000..6b12b80
--- /dev/null
+++ b/tests/data_files/pkcs7_data_signed_badsigner2_badsize.der
Binary files differ
diff --git a/tests/data_files/pkcs7_data_signed_badsigner2_badtag.der b/tests/data_files/pkcs7_data_signed_badsigner2_badtag.der
new file mode 100644
index 0000000..7929444
--- /dev/null
+++ b/tests/data_files/pkcs7_data_signed_badsigner2_badtag.der
Binary files differ
diff --git a/tests/data_files/pkcs7_data_signed_badsigner2_fuzzbad.der b/tests/data_files/pkcs7_data_signed_badsigner2_fuzzbad.der
new file mode 100644
index 0000000..b52bb78
--- /dev/null
+++ b/tests/data_files/pkcs7_data_signed_badsigner2_fuzzbad.der
Binary files differ
diff --git a/tests/include/test/drivers/crypto_config_test_driver_extension.h b/tests/include/test/drivers/crypto_config_test_driver_extension.h
index fbfe8da..26c432c 100644
--- a/tests/include/test/drivers/crypto_config_test_driver_extension.h
+++ b/tests/include/test/drivers/crypto_config_test_driver_extension.h
@@ -158,6 +158,14 @@
 #endif
 #endif
 
+#if defined(PSA_WANT_ALG_JPAKE)
+#if defined(MBEDTLS_PSA_ACCEL_ALG_JPAKE)
+#undef MBEDTLS_PSA_ACCEL_ALG_JPAKE
+#else
+#define MBEDTLS_PSA_ACCEL_ALG_JPAKE 1
+#endif
+#endif
+
 #if defined(PSA_WANT_KEY_TYPE_AES)
 #if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_AES)
 #undef MBEDTLS_PSA_ACCEL_KEY_TYPE_AES
@@ -206,6 +214,30 @@
 #endif
 #endif
 
+#if defined(PSA_WANT_ALG_TLS12_PRF)
+#if defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF)
+#undef MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF
+#else
+#define MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF 1
+#endif
+#endif
+
+#if defined(PSA_WANT_ALG_TLS12_PSK_TO_MS)
+#if defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS)
+#undef MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS
+#else
+#define MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS 1
+#endif
+#endif
+
+#if defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS)
+#if defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_ECJPAKE_TO_PMS)
+#undef MBEDTLS_PSA_ACCEL_ALG_TLS12_ECJPAKE_TO_PMS
+#else
+#define MBEDTLS_PSA_ACCEL_ALG_TLS12_ECJPAKE_TO_PMS 1
+#endif
+#endif
+
 #define MBEDTLS_PSA_ACCEL_ALG_CBC_MAC 1
 #define MBEDTLS_PSA_ACCEL_ALG_CCM 1
 #define MBEDTLS_PSA_ACCEL_ALG_CMAC 1
@@ -218,8 +250,6 @@
 #define MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP 1
 #define MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT 1
 #define MBEDTLS_PSA_ACCEL_ALG_STREAM_CIPHER 1
-#define MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF 1
-#define MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS 1
 
 #if defined(MBEDTLS_PSA_ACCEL_ALG_ECDSA)
 #if defined(MBEDTLS_PSA_ACCEL_ALG_ECDH)
diff --git a/tests/include/test/drivers/pake.h b/tests/include/test/drivers/pake.h
new file mode 100644
index 0000000..331ee49
--- /dev/null
+++ b/tests/include/test/drivers/pake.h
@@ -0,0 +1,87 @@
+/*
+ * Test driver for PAKE driver entry points.
+ */
+/*  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef PSA_CRYPTO_TEST_DRIVERS_PAKE_H
+#define PSA_CRYPTO_TEST_DRIVERS_PAKE_H
+
+#include "mbedtls/build_info.h"
+
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+#include <psa/crypto_driver_common.h>
+
+typedef struct {
+    /* If not PSA_SUCCESS, return this error code instead of processing the
+     * function call. */
+    psa_status_t forced_status;
+    /* PAKE driver setup is executed on the first call to
+       pake_output/pake_input (added to distinguish forced statuses). */
+    psa_status_t forced_setup_status;
+    /* Count the amount of times PAKE driver functions are called. */
+    struct {
+        unsigned long total;
+        unsigned long setup;
+        unsigned long input;
+        unsigned long output;
+        unsigned long implicit_key;
+        unsigned long abort;
+    } hits;
+    /* Status returned by the last PAKE driver function call. */
+    psa_status_t driver_status;
+    /* Output returned by pake_output */
+    void *forced_output;
+    size_t forced_output_length;
+} mbedtls_test_driver_pake_hooks_t;
+
+#define MBEDTLS_TEST_DRIVER_PAKE_INIT { PSA_SUCCESS, PSA_SUCCESS, { 0, 0, 0, 0, 0, 0 }, PSA_SUCCESS, \
+                                        NULL, 0 }
+static inline mbedtls_test_driver_pake_hooks_t
+mbedtls_test_driver_pake_hooks_init(void)
+{
+    const mbedtls_test_driver_pake_hooks_t v = MBEDTLS_TEST_DRIVER_PAKE_INIT;
+    return v;
+}
+
+extern mbedtls_test_driver_pake_hooks_t mbedtls_test_driver_pake_hooks;
+
+psa_status_t mbedtls_test_transparent_pake_setup(
+    mbedtls_transparent_test_driver_pake_operation_t *operation,
+    const psa_crypto_driver_pake_inputs_t *inputs);
+
+psa_status_t mbedtls_test_transparent_pake_output(
+    mbedtls_transparent_test_driver_pake_operation_t *operation,
+    psa_crypto_driver_pake_step_t step,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length);
+
+psa_status_t mbedtls_test_transparent_pake_input(
+    mbedtls_transparent_test_driver_pake_operation_t *operation,
+    psa_crypto_driver_pake_step_t step,
+    const uint8_t *input,
+    size_t input_length);
+
+psa_status_t mbedtls_test_transparent_pake_get_implicit_key(
+    mbedtls_transparent_test_driver_pake_operation_t *operation,
+    uint8_t *output, size_t output_size, size_t *output_length);
+
+psa_status_t mbedtls_test_transparent_pake_abort(
+    mbedtls_transparent_test_driver_pake_operation_t *operation);
+
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_TEST_DRIVERS_PAKE_H */
diff --git a/tests/include/test/drivers/test_driver.h b/tests/include/test/drivers/test_driver.h
index 0a65b40..541ee03 100644
--- a/tests/include/test/drivers/test_driver.h
+++ b/tests/include/test/drivers/test_driver.h
@@ -38,6 +38,7 @@
 #include "test/drivers/signature.h"
 #include "test/drivers/asymmetric_encryption.h"
 #include "test/drivers/key_agreement.h"
+#include "test/drivers/pake.h"
 
 #endif /* PSA_CRYPTO_DRIVER_TEST */
 #endif /* PSA_CRYPTO_TEST_DRIVER_H */
diff --git a/tests/include/test/macros.h b/tests/include/test/macros.h
index 2eba0c1..ab8260b 100644
--- a/tests/include/test/macros.h
+++ b/tests/include/test/macros.h
@@ -253,27 +253,4 @@
  */
 #define MAX(x, y) ((x) > (y) ? (x) : (y))
 
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n, b, i)                            \
-    {                                                       \
-        (n) = ((uint32_t) (b)[(i)] << 24)             \
-              | ((uint32_t) (b)[(i) + 1] << 16)             \
-              | ((uint32_t) (b)[(i) + 2] <<  8)             \
-              | ((uint32_t) (b)[(i) + 3]);            \
-    }
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n, b, i)                            \
-    {                                                       \
-        (b)[(i)] = (unsigned char) ((n) >> 24);       \
-        (b)[(i) + 1] = (unsigned char) ((n) >> 16);       \
-        (b)[(i) + 2] = (unsigned char) ((n) >>  8);       \
-        (b)[(i) + 3] = (unsigned char) ((n));       \
-    }
-#endif
-
 #endif /* TEST_MACROS_H */
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 2e283d4..b76ba57 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -2111,14 +2111,13 @@
         # 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
     # Restartable feature is not yet supported by PSA. Once it will in
     # the future, the following line could be removed (see issues
     # 6061, 6332 and following ones)
     scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
+    # Dynamic secure element support is a deprecated feature and needs to be disabled here.
+    # This is done to have the same form of psa_key_attributes_s for libdriver and library.
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
 }
 
 # Keep in sync with component_test_psa_crypto_config_reference_ecdsa_use_psa
@@ -2313,7 +2312,8 @@
     msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated ECDH + USE_PSA"
     make test
 
-    # ssl-opt.sh later (probably doesn't pass right now)
+    msg "test: ssl-opt.sh"
+    tests/ssl-opt.sh
 }
 
 # Keep in sync with component_test_psa_crypto_config_accel_ecdh_use_psa.
@@ -2332,7 +2332,8 @@
     msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with reference ECDH + USE_PSA"
     make test
 
-    # ssl-opt.sh later when the accel component is ready
+    msg "test: ssl-opt.sh"
+    tests/ssl-opt.sh
 }
 
 component_test_psa_crypto_config_accel_rsa_signature () {
@@ -2477,6 +2478,10 @@
     scripts/config.py unset MBEDTLS_PKCS7_C
     scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC
     scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_DETERMINISTIC_ECDSA
+
+    # Dynamic secure element support is a deprecated feature and needs to be disabled here.
+    # This is done to have the same form of psa_key_attributes_s for libdriver and library.
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
 }
 
 # Note that component_test_psa_crypto_config_reference_hash_use_psa
@@ -2615,6 +2620,41 @@
     make test
 }
 
+component_test_psa_crypto_config_accel_pake() {
+    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated PAKE"
+
+    # Start with full
+    scripts/config.py full
+
+    # 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
+
+    loc_accel_list="ALG_JPAKE"
+    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"
+
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
+
+    # Make build-in fallback not available
+    scripts/config.py unset MBEDTLS_ECJPAKE_C
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+
+    # Dynamic secure element support is a deprecated feature and needs to be disabled here.
+    # This is done to have the same form of psa_key_attributes_s for libdriver and library.
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
+
+    loc_accel_flags="$loc_accel_flags $( echo "$loc_accel_list" | sed 's/[^ ]* */-DMBEDTLS_PSA_ACCEL_&/g' )"
+    make CFLAGS="$ASAN_CFLAGS -Werror -I../tests/include -I../tests -I../../tests -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_TEST_LIBTESTDRIVER1 $loc_accel_flags" LDFLAGS="-ltestdriver1 $ASAN_CFLAGS"
+
+    not grep mbedtls_ecjpake_init library/ecjpake.o
+
+    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated PAKE"
+    make test
+}
+
 component_test_psa_crypto_config_no_driver() {
     # full plus MBEDTLS_PSA_CRYPTO_CONFIG
     msg "build: full + MBEDTLS_PSA_CRYPTO_CONFIG minus MBEDTLS_PSA_CRYPTO_DRIVERS"
@@ -3659,6 +3699,11 @@
     # ARM Compiler 6 - Target ARMv8.2-A - AArch64
     armc6_build_test "-O1 --target=aarch64-arm-none-eabi -march=armv8.2-a+crypto"
 }
+support_build_armcc () {
+    armc5_cc="$ARMC5_BIN_DIR/armcc"
+    armc6_cc="$ARMC6_BIN_DIR/armclang"
+    (check_tools "$armc5_cc" "$armc6_cc" > /dev/null 2>&1)
+}
 
 component_test_tls13_only () {
     msg "build: default config with MBEDTLS_SSL_PROTO_TLS1_3, without MBEDTLS_SSL_PROTO_TLS1_2"
@@ -3801,8 +3846,8 @@
     make WINDOWS_BUILD=1 clean
 }
 support_build_mingw() {
-    case $(i686-w64-mingw32-gcc -dumpversion) in
-        [0-5]*) false;;
+    case $(i686-w64-mingw32-gcc -dumpversion 2>/dev/null) in
+        [0-5]*|"") false;;
         *) true;;
     esac
 }
diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py
index 3fd24e9..49ff218 100755
--- a/tests/scripts/analyze_outcomes.py
+++ b/tests/scripts/analyze_outcomes.py
@@ -96,7 +96,7 @@
             if component_ref in entry:
                 reference_test_passed = True
         if(reference_test_passed and not driver_test_passed):
-            print(key)
+            Results.log(key)
             result = False
     return result
 
@@ -131,7 +131,7 @@
     """Perform coverage analysis."""
     del args # unused
     outcomes = read_outcome_file(outcome_file)
-    print("\n*** Analyze coverage ***\n")
+    Results.log("\n*** Analyze coverage ***\n")
     results = analyze_outcomes(outcomes)
     return results.error_count == 0
 
@@ -140,7 +140,7 @@
     ignored_suites = ['test_suite_' + x for x in args['ignored_suites']]
 
     outcomes = read_outcome_file(outcome_file)
-    print("\n*** Analyze driver {} vs reference {} ***\n".format(
+    Results.log("\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_suites,
@@ -213,7 +213,7 @@
 
         if options.list:
             for task in TASKS:
-                print(task)
+                Results.log(task)
             sys.exit(0)
 
         result = True
@@ -225,7 +225,7 @@
 
             for task in tasks:
                 if task not in TASKS:
-                    print('Error: invalid task: {}'.format(task))
+                    Results.log('Error: invalid task: {}'.format(task))
                     sys.exit(1)
 
         for task in TASKS:
@@ -235,7 +235,7 @@
 
         if result is False:
             sys.exit(1)
-        print("SUCCESS :-)")
+        Results.log("SUCCESS :-)")
     except Exception: # pylint: disable=broad-except
         # Print the backtrace and exit explicitly with our chosen status.
         traceback.print_exc()
diff --git a/tests/src/drivers/test_driver_pake.c b/tests/src/drivers/test_driver_pake.c
new file mode 100644
index 0000000..9c72483
--- /dev/null
+++ b/tests/src/drivers/test_driver_pake.c
@@ -0,0 +1,212 @@
+/*
+ * Test driver for MAC entry points.
+ */
+/*  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include <test/helpers.h>
+
+#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS) && defined(PSA_CRYPTO_DRIVER_TEST)
+#include "psa_crypto_pake.h"
+
+#include "test/drivers/pake.h"
+#include "string.h"
+
+#if defined(MBEDTLS_TEST_LIBTESTDRIVER1)
+#include "libtestdriver1/library/psa_crypto_pake.h"
+#endif
+
+mbedtls_test_driver_pake_hooks_t mbedtls_test_driver_pake_hooks =
+    MBEDTLS_TEST_DRIVER_PAKE_INIT;
+
+
+psa_status_t mbedtls_test_transparent_pake_setup(
+    mbedtls_transparent_test_driver_pake_operation_t *operation,
+    const psa_crypto_driver_pake_inputs_t *inputs)
+{
+    mbedtls_test_driver_pake_hooks.hits.total++;
+    mbedtls_test_driver_pake_hooks.hits.setup++;
+
+    if (mbedtls_test_driver_pake_hooks.forced_setup_status != PSA_SUCCESS) {
+        mbedtls_test_driver_pake_hooks.driver_status =
+            mbedtls_test_driver_pake_hooks.forced_setup_status;
+    } else {
+#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
+        defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_PAKE)
+        mbedtls_test_driver_pake_hooks.driver_status =
+            libtestdriver1_mbedtls_psa_pake_setup(
+                operation, (const libtestdriver1_psa_crypto_driver_pake_inputs_t *) inputs);
+#elif defined(MBEDTLS_PSA_BUILTIN_PAKE)
+        mbedtls_test_driver_pake_hooks.driver_status =
+            mbedtls_psa_pake_setup(
+                operation, inputs);
+#else
+        (void) operation;
+        (void) inputs;
+        mbedtls_test_driver_pake_hooks.driver_status = PSA_ERROR_NOT_SUPPORTED;
+#endif
+    }
+
+    return mbedtls_test_driver_pake_hooks.driver_status;
+}
+
+psa_status_t mbedtls_test_transparent_pake_output(
+    mbedtls_transparent_test_driver_pake_operation_t *operation,
+    psa_crypto_driver_pake_step_t step,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length)
+{
+    mbedtls_test_driver_pake_hooks.hits.total++;
+    mbedtls_test_driver_pake_hooks.hits.output++;
+
+    if (mbedtls_test_driver_pake_hooks.forced_output != NULL) {
+        if (output_size < mbedtls_test_driver_pake_hooks.forced_output_length) {
+            return PSA_ERROR_BUFFER_TOO_SMALL;
+        }
+
+        memcpy(output,
+               mbedtls_test_driver_pake_hooks.forced_output,
+               mbedtls_test_driver_pake_hooks.forced_output_length);
+        *output_length = mbedtls_test_driver_pake_hooks.forced_output_length;
+
+        return mbedtls_test_driver_pake_hooks.forced_status;
+    }
+
+    if (mbedtls_test_driver_pake_hooks.forced_status != PSA_SUCCESS) {
+        mbedtls_test_driver_pake_hooks.driver_status =
+            mbedtls_test_driver_pake_hooks.forced_status;
+    } else {
+#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
+        defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_PAKE)
+        mbedtls_test_driver_pake_hooks.driver_status =
+            libtestdriver1_mbedtls_psa_pake_output(
+                operation, step, output, output_size, output_length);
+#elif defined(MBEDTLS_PSA_BUILTIN_PAKE)
+        mbedtls_test_driver_pake_hooks.driver_status =
+            mbedtls_psa_pake_output(
+                operation, step, output, output_size, output_length);
+#else
+        (void) operation;
+        (void) step;
+        (void) output;
+        (void) output_size;
+        (void) output_length;
+        mbedtls_test_driver_pake_hooks.driver_status = PSA_ERROR_NOT_SUPPORTED;
+#endif
+    }
+
+    return mbedtls_test_driver_pake_hooks.driver_status;
+}
+
+psa_status_t mbedtls_test_transparent_pake_input(
+    mbedtls_transparent_test_driver_pake_operation_t *operation,
+    psa_crypto_driver_pake_step_t step,
+    const uint8_t *input,
+    size_t input_length)
+{
+    mbedtls_test_driver_pake_hooks.hits.total++;
+    mbedtls_test_driver_pake_hooks.hits.input++;
+
+    if (mbedtls_test_driver_pake_hooks.forced_status != PSA_SUCCESS) {
+        mbedtls_test_driver_pake_hooks.driver_status =
+            mbedtls_test_driver_pake_hooks.forced_status;
+    } else {
+#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
+        defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_PAKE)
+        mbedtls_test_driver_pake_hooks.driver_status =
+            libtestdriver1_mbedtls_psa_pake_input(
+                operation, step, input, input_length);
+#elif defined(MBEDTLS_PSA_BUILTIN_PAKE)
+        mbedtls_test_driver_pake_hooks.driver_status =
+            mbedtls_psa_pake_input(
+                operation, step, input, input_length);
+#else
+        (void) operation;
+        (void) step;
+        (void) input;
+        (void) input_length;
+        mbedtls_test_driver_pake_hooks.driver_status = PSA_ERROR_NOT_SUPPORTED;
+#endif
+    }
+
+    return mbedtls_test_driver_pake_hooks.driver_status;
+}
+
+psa_status_t mbedtls_test_transparent_pake_get_implicit_key(
+    mbedtls_transparent_test_driver_pake_operation_t *operation,
+    uint8_t *output, size_t output_size, size_t *output_length)
+{
+    mbedtls_test_driver_pake_hooks.hits.total++;
+    mbedtls_test_driver_pake_hooks.hits.implicit_key++;
+
+    if (mbedtls_test_driver_pake_hooks.forced_status != PSA_SUCCESS) {
+        mbedtls_test_driver_pake_hooks.driver_status =
+            mbedtls_test_driver_pake_hooks.forced_status;
+    } else {
+#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
+        defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_PAKE)
+        mbedtls_test_driver_pake_hooks.driver_status =
+            libtestdriver1_mbedtls_psa_pake_get_implicit_key(
+                operation,  output, output_size, output_length);
+#elif defined(MBEDTLS_PSA_BUILTIN_PAKE)
+        mbedtls_test_driver_pake_hooks.driver_status =
+            mbedtls_psa_pake_get_implicit_key(
+                operation, output, output_size, output_length);
+#else
+        (void) operation;
+        (void) output;
+        (void) output_size;
+        (void) output_length;
+        mbedtls_test_driver_pake_hooks.driver_status = PSA_ERROR_NOT_SUPPORTED;
+#endif
+    }
+
+    return mbedtls_test_driver_pake_hooks.driver_status;
+}
+
+psa_status_t mbedtls_test_transparent_pake_abort(
+    mbedtls_transparent_test_driver_pake_operation_t *operation)
+{
+    mbedtls_test_driver_pake_hooks.hits.total++;
+    mbedtls_test_driver_pake_hooks.hits.abort++;
+
+#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
+    defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_PAKE)
+    mbedtls_test_driver_pake_hooks.driver_status =
+        libtestdriver1_mbedtls_psa_pake_abort(
+            operation);
+#elif defined(MBEDTLS_PSA_BUILTIN_PAKE)
+    mbedtls_test_driver_pake_hooks.driver_status =
+        mbedtls_psa_pake_abort(
+            operation);
+#else
+    (void) operation;
+    mbedtls_test_driver_pake_hooks.driver_status = PSA_ERROR_NOT_SUPPORTED;
+#endif
+
+
+    if (mbedtls_test_driver_pake_hooks.forced_status != PSA_SUCCESS &&
+        mbedtls_test_driver_pake_hooks.driver_status == PSA_SUCCESS) {
+        mbedtls_test_driver_pake_hooks.driver_status =
+            mbedtls_test_driver_pake_hooks.forced_status;
+    }
+
+
+    return mbedtls_test_driver_pake_hooks.driver_status;
+}
+
+#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS && PSA_CRYPTO_DRIVER_TEST */
diff --git a/tests/src/random.c b/tests/src/random.c
index e74e689..5ca333a 100644
--- a/tests/src/random.c
+++ b/tests/src/random.c
@@ -36,6 +36,7 @@
 #include <string.h>
 
 #include <mbedtls/entropy.h>
+#include "../../library/alignment.h"
 
 int mbedtls_test_rnd_std_rand(void *rng_state,
                               unsigned char *output,
@@ -137,7 +138,7 @@
                          + info->v0) ^ (sum + k[(sum>>11) & 3]);
         }
 
-        PUT_UINT32_BE(info->v0, result, 0);
+        MBEDTLS_PUT_UINT32_BE(info->v0, result, 0);
         memcpy(out, result, use_len);
         len -= use_len;
         out += 4;
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 5ce2d03..e2b1e04 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -395,7 +395,8 @@
 
     case "$1" in
         *server5*|\
-        *server7*)
+        *server7*|\
+        *dir-maxpath*)
             if [ "$3" = "TLS13" ]; then
                 # In case of TLS13 the support for ECDSA is enough
                 requires_pk_alg "ECDSA"
@@ -1450,7 +1451,7 @@
 #       detect_required_features() function), it does NOT guarantee that the
 #       result is accurate. It does not check other conditions, such as:
 #       - MBEDTLS_SSL_PROTO_TLS1_x can be disabled to selectively remove
-#         TLS 1.2/1.3 suppport
+#         TLS 1.2/1.3 support
 #       - we can force a ciphersuite which contains "WITH" in its name, meaning
 #         that we are going to use TLS 1.2
 #       - etc etc
@@ -1965,6 +1966,7 @@
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_X509_CRT_PARSE_C
 requires_config_enabled MBEDTLS_RSA_C
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
 requires_hash_alg SHA_256
 run_test    "Opaque key for client authentication: ECDHE-RSA" \
             "$P_SRV auth_mode=required crt_file=data_files/server2-sha256.crt \
@@ -2244,6 +2246,7 @@
 requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
 requires_config_enabled MBEDTLS_X509_CRT_PARSE_C
 requires_config_enabled MBEDTLS_RSA_C
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
 requires_hash_alg SHA_256
 run_test    "Opaque key for server authentication: ECDHE-RSA" \
             "$P_SRV key_opaque=1 crt_file=data_files/server2-sha256.crt \
@@ -2330,6 +2333,7 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_hash_alg SHA_256
 requires_config_disabled MBEDTLS_X509_REMOVE_INFO
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
 run_test    "Opaque keys for server authentication: RSA keys with different algs" \
             "$P_SRV auth_mode=required key_opaque=1 crt_file=data_files/server2-sha256.crt \
              key_file=data_files/server2.key key_opaque_algs=rsa-sign-pss,none \
@@ -2394,6 +2398,7 @@
 requires_config_enabled MBEDTLS_X509_CRT_PARSE_C
 requires_config_enabled MBEDTLS_RSA_C
 requires_hash_alg SHA_256
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
 run_test    "Opaque key for client/server authentication: ECDHE-RSA" \
             "$P_SRV auth_mode=required key_opaque=1 crt_file=data_files/server2-sha256.crt \
              key_file=data_files/server2.key  key_opaque_algs=rsa-sign-pkcs1,none" \
@@ -5622,7 +5627,6 @@
 # are in place so that the semantics are consistent with the test description.
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
 run_test    "Authentication: server max_int chain, client default" \
             "$P_SRV crt_file=data_files/dir-maxpath/c09.pem \
                     key_file=data_files/dir-maxpath/09.key" \
@@ -5632,7 +5636,6 @@
 
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
 run_test    "Authentication: server max_int+1 chain, client default" \
             "$P_SRV crt_file=data_files/dir-maxpath/c10.pem \
                     key_file=data_files/dir-maxpath/10.key" \
@@ -5642,8 +5645,6 @@
 
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
 run_test    "Authentication: server max_int+1 chain, client optional" \
             "$P_SRV crt_file=data_files/dir-maxpath/c10.pem \
                     key_file=data_files/dir-maxpath/10.key" \
@@ -5654,8 +5655,6 @@
 
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
 run_test    "Authentication: server max_int+1 chain, client none" \
             "$P_SRV crt_file=data_files/dir-maxpath/c10.pem \
                     key_file=data_files/dir-maxpath/10.key" \
@@ -5666,7 +5665,6 @@
 
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
 run_test    "Authentication: client max_int+1 chain, server default" \
             "$P_SRV ca_file=data_files/dir-maxpath/00.crt" \
             "$P_CLI crt_file=data_files/dir-maxpath/c10.pem \
@@ -5676,7 +5674,6 @@
 
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
 run_test    "Authentication: client max_int+1 chain, server optional" \
             "$P_SRV ca_file=data_files/dir-maxpath/00.crt auth_mode=optional" \
             "$P_CLI crt_file=data_files/dir-maxpath/c10.pem \
@@ -5686,7 +5683,6 @@
 
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
 run_test    "Authentication: client max_int+1 chain, server required" \
             "$P_SRV ca_file=data_files/dir-maxpath/00.crt auth_mode=required" \
             "$P_CLI crt_file=data_files/dir-maxpath/c10.pem \
@@ -5696,7 +5692,6 @@
 
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
 run_test    "Authentication: client max_int chain, server required" \
             "$P_SRV ca_file=data_files/dir-maxpath/00.crt auth_mode=required" \
             "$P_CLI crt_file=data_files/dir-maxpath/c09.pem \
@@ -5928,8 +5923,6 @@
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
 run_test    "Authentication, CA callback: server max_int chain, client default" \
             "$P_SRV crt_file=data_files/dir-maxpath/c09.pem \
                     key_file=data_files/dir-maxpath/09.key" \
@@ -5941,8 +5934,6 @@
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
 run_test    "Authentication, CA callback: server max_int+1 chain, client default" \
             "$P_SRV crt_file=data_files/dir-maxpath/c10.pem \
                     key_file=data_files/dir-maxpath/10.key" \
@@ -5954,8 +5945,6 @@
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
 run_test    "Authentication, CA callback: server max_int+1 chain, client optional" \
             "$P_SRV crt_file=data_files/dir-maxpath/c10.pem \
                     key_file=data_files/dir-maxpath/10.key" \
@@ -5968,8 +5957,6 @@
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
 run_test    "Authentication, CA callback: client max_int+1 chain, server optional" \
             "$P_SRV ca_callback=1 debug_level=3 ca_file=data_files/dir-maxpath/00.crt auth_mode=optional" \
             "$P_CLI crt_file=data_files/dir-maxpath/c10.pem \
@@ -5981,8 +5968,6 @@
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
 run_test    "Authentication, CA callback: client max_int+1 chain, server required" \
             "$P_SRV ca_callback=1 debug_level=3 ca_file=data_files/dir-maxpath/00.crt auth_mode=required" \
             "$P_CLI crt_file=data_files/dir-maxpath/c10.pem \
@@ -5994,8 +5979,6 @@
 requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
 requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
-requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
 run_test    "Authentication, CA callback: client max_int chain, server required" \
             "$P_SRV ca_callback=1 debug_level=3 ca_file=data_files/dir-maxpath/00.crt auth_mode=required" \
             "$P_CLI crt_file=data_files/dir-maxpath/c09.pem \
diff --git a/tests/suites/test_suite_pkcs7.data b/tests/suites/test_suite_pkcs7.data
index da8146b..13fcaa6 100644
--- a/tests/suites/test_suite_pkcs7.data
+++ b/tests/suites/test_suite_pkcs7.data
@@ -10,6 +10,10 @@
 depends_on:MBEDTLS_SHA256_C
 pkcs7_parse:"data_files/pkcs7_data_without_cert_signed.der":MBEDTLS_PKCS7_SIGNED_DATA
 
+PKCS7 Signed Data Parse with zero signers
+depends_on:MBEDTLS_SHA256_C
+pkcs7_parse:"data_files/pkcs7_data_no_signers.der":MBEDTLS_PKCS7_SIGNED_DATA
+
 PKCS7 Signed Data Parse Fail with multiple certs #4
 depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
 pkcs7_parse:"data_files/pkcs7_data_multiple_certs_signed.der":MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE
@@ -19,17 +23,45 @@
 pkcs7_parse:"data_files/pkcs7_data_signed_badcert.der":MBEDTLS_ERR_PKCS7_INVALID_CERT
 
 PKCS7 Signed Data Parse Fail with disabled alg #5.1
-depends_on:MBEDTLS_RSA_C:!MBEDTLS_SHA512_C
+depends_on:MBEDTLS_RSA_C:!MBEDTLS_HAS_ALG_SHA_512_VIA_LOWLEVEL_OR_PSA
 pkcs7_parse:"data_files/pkcs7_data_cert_signed_sha512.der":MBEDTLS_ERR_PKCS7_INVALID_ALG
 
 PKCS7 Parse Fail with Inlined Content Info #5.2
 depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
 pkcs7_parse:"data_files/pkcs7_data_with_signature.der":MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE
 
+PKCS7 Signed Data Parse Fail with no RSA #5.3
+depends_on:MBEDTLS_SHA256_C:!MBEDTLS_RSA_C
+pkcs7_parse:"data_files/pkcs7_data_cert_signed_sha256.der":MBEDTLS_ERR_PKCS7_INVALID_CERT
+
 PKCS7 Signed Data Parse Fail with corrupted signer info #6
 depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
 pkcs7_parse:"data_files/pkcs7_data_signed_badsigner.der":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO,MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)
 
+PKCS7 Signed Data Parse Fail with corrupted signer info[1] invalid size #6.1
+depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
+pkcs7_parse:"data_files/pkcs7_data_signed_badsigner1_badsize.der":MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO
+
+PKCS7 Signed Data Parse Fail with corrupted signer info[2] invalid size #6.2
+depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
+pkcs7_parse:"data_files/pkcs7_data_signed_badsigner2_badsize.der":MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO
+
+PKCS7 Signed Data Parse Fail with corrupted signer info[1] unexpected tag #6.3
+depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
+pkcs7_parse:"data_files/pkcs7_data_signed_badsigner1_badtag.der":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO,MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)
+
+PKCS7 Signed Data Parse Fail with corrupted signer info[2] unexpected tag #6.4
+depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
+pkcs7_parse:"data_files/pkcs7_data_signed_badsigner2_badtag.der":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO,MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)
+
+PKCS7 Signed Data Parse Fail with corrupted signer info[1] fuzz bad #6.5
+depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
+pkcs7_parse:"data_files/pkcs7_data_signed_badsigner1_fuzzbad.der":MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO
+
+PKCS7 Signed Data Parse Fail with corrupted signer info[2] fuzz bad #6.6
+depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
+pkcs7_parse:"data_files/pkcs7_data_signed_badsigner2_fuzzbad.der":MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO
+
 PKCS7 Signed Data Parse Fail Version other than 1 #7
 depends_on:MBEDTLS_SHA256_C
 pkcs7_parse:"data_files/pkcs7_data_cert_signed_v2.der":MBEDTLS_ERR_PKCS7_INVALID_VERSION
@@ -43,7 +75,7 @@
 pkcs7_verify:"data_files/pkcs7_zerolendata_detached.der":"data_files/pkcs7-rsa-sha256-1.der":"data_files/pkcs7_zerolendata.bin":0:0
 
 PKCS7 Signed Data Verification Fail zero-len data
-depends_on:MBEDTLS_SHA1_C:MBEDTLS_SHA256_C
+depends_on:MBEDTLS_SHA1_C:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
 pkcs7_verify:"data_files/pkcs7_zerolendata_detached.der":"data_files/pkcs7-rsa-sha256-2.der":"data_files/pkcs7_zerolendata.bin":0:MBEDTLS_ERR_RSA_VERIFY_FAILED
 
 PKCS7 Signed Data Verification Pass SHA256 #9
@@ -63,19 +95,19 @@
 pkcs7_verify:"data_files/pkcs7_data_cert_signed_sha512.der":"data_files/pkcs7-rsa-sha256-1.der":"data_files/pkcs7_data.bin":0:0
 
 PKCS7 Signed Data Verification Fail because of different certificate #12
-depends_on:MBEDTLS_SHA256_C
+depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
 pkcs7_verify:"data_files/pkcs7_data_cert_signed_sha256.der":"data_files/pkcs7-rsa-sha256-2.der":"data_files/pkcs7_data.bin":0:MBEDTLS_ERR_RSA_VERIFY_FAILED
 
 PKCS7 Signed Data Verification Fail because of different data hash #13
-depends_on:MBEDTLS_SHA256_C
+depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
 pkcs7_verify:"data_files/pkcs7_data_cert_signed_sha256.der":"data_files/pkcs7-rsa-sha256-1.der":"data_files/pkcs7_data_1.bin":0:MBEDTLS_ERR_RSA_VERIFY_FAILED
 
 PKCS7 Signed Data Parse Failure Corrupt signerInfo.issuer #15.1
-depends_on:MBEDTLS_SHA256_C
+depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
 pkcs7_parse:"data_files/pkcs7_signerInfo_issuer_invalid_size.der":MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO
 
 PKCS7 Signed Data Parse Failure Corrupt signerInfo.serial #15.2
-depends_on:MBEDTLS_SHA256_C
+depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
 pkcs7_parse:"data_files/pkcs7_signerInfo_serial_invalid_size.der":MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO
 
 PKCS7 Signed Data Parse Fail Corrupt signerInfos[2] (6213931373035520)
@@ -95,7 +127,7 @@
 pkcs7_verify:"data_files/pkcs7_data_multiple_signed.der":"data_files/pkcs7-rsa-sha256-1.crt data_files/pkcs7-rsa-sha256-2.crt":"data_files/pkcs7_data.bin":0:0
 
 PKCS7 Signed Data Verify with multiple(3) signers #16.1
-depends_on:MBEDTLS_SHA256_C
+depends_on:MBEDTLS_SHA256_C:!MBEDTLS_MEMORY_BUFFER_ALLOC_C
 pkcs7_verify:"data_files/pkcs7_data_3_signed.der":"data_files/pkcs7-rsa-sha256-1.crt data_files/pkcs7-rsa-sha256-2.crt data_files/pkcs7-rsa-sha256-3.crt":"data_files/pkcs7_data.bin":0:0
 
 PKCS7 Signed Data Hash Verify with multiple signers #17
@@ -106,10 +138,22 @@
 depends_on:MBEDTLS_SHA256_C:MBEDTLS_SHA512_C
 pkcs7_verify:"data_files/pkcs7_data_multiple_signed.der":"data_files/pkcs7-rsa-sha256-1.crt data_files/pkcs7-rsa-sha256-2.crt":"data_files/pkcs7_data.bin":MBEDTLS_MD_SHA512:MBEDTLS_ERR_PKCS7_VERIFY_FAIL
 
-PKCS7 Signed Data Verify Fail Expired Cert #19
-depends_on:MBEDTLS_SHA256_C
+PKCS7 Signed Data Verify Pass Expired Cert #19 no TIME_DATE
+depends_on:MBEDTLS_SHA256_C:!MBEDTLS_HAVE_TIME_DATE
+pkcs7_verify:"data_files/pkcs7_data_rsa_expired.der":"data_files/pkcs7-rsa-expired.crt":"data_files/pkcs7_data.bin":0:0
+
+PKCS7 Signed Data Verify Fail Expired Cert #19 have DATE_TIME
+depends_on:MBEDTLS_SHA256_C:MBEDTLS_HAVE_TIME_DATE
 pkcs7_verify:"data_files/pkcs7_data_cert_signed_sha256.der":"data_files/pkcs7-rsa-expired.crt":"data_files/pkcs7_data.bin":0:MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID
 
+PKCS7 Signed Data Verify Fail Expired Cert #19 no DATE_TIME 1
+depends_on:MBEDTLS_SHA256_C:!MBEDTLS_HAVE_TIME_DATE:MBEDTLS_RSA_C
+pkcs7_verify:"data_files/pkcs7_data_cert_signed_sha256.der":"data_files/pkcs7-rsa-expired.crt":"data_files/pkcs7_data.bin":0:MBEDTLS_ERR_RSA_VERIFY_FAILED
+
+PKCS7 Signed Data Verify Fail Expired Cert #19 no TIME_DATE 2
+depends_on:MBEDTLS_SHA256_C:!MBEDTLS_HAVE_TIME_DATE:MBEDTLS_RSA_C
+pkcs7_verify:"data_files/pkcs7_data_rsa_expired.der":"data_files/pkcs7-rsa-expired.crt":"data_files/pkcs7_data_1.bin":0:MBEDTLS_ERR_RSA_VERIFY_FAILED
+
 PKCS7 Parse Failure Invalid ASN1: Add null byte to start #20.0
 depends_on:MBEDTLS_SHA256_C
 pkcs7_asn1_fail:"003082050006092a864886f70d010702a08204f1308204ed020101310f300d06096086480165030402010500300b06092a864886f70d010701a082034d3082034930820231a00302010202147bdeddd2444cd1cdfe5c41a8102c89b7df2e6cbf300d06092a864886f70d01010b05003034310b3009060355040613024e4c310e300c060355040a0c05504b4353373115301306035504030c0c504b43533720436572742031301e170d3232313032383136313035365a170d3233313032383136313035365a3034310b3009060355040613024e4c310e300c060355040a0c05504b4353373115301306035504030c0c504b4353372043657274203130820122300d06092a864886f70d01010105000382010f003082010a0282010100c8b6cf69899cd1f0ebb4ca645c05e70e0d2efeddcc61d089cbd515a39a3579b92343b61ec750060fb4ed37876332400e425f1d376c7e75c2973314edf4bb30c8f8dd03b9fcff955a245d49137ad6e60056cac19552a865d52187187cc042c9c49e3e3a9c17a534b453cdabc0cb113b4f63f5b3174b9ee9902b1910d11496a279a74326adcfee10bfd9e7ebafbb377be9b63959165d13dd5751171cadad3c1d3adac68bc8011d61b54cf60178be36839a89ac91ab419e3ca37d6ba881d25518c4db68bca6f7c83602f699a86b17fb1e773bcbe74bb93a49b251ae86428b5740e1868bb1d6fab9e28712e98ec319ad8fca4d73010c4b09c4b80458961e7cf083530203010001a3533051301d0603551d0e041604148aeee5947cc67c5dd515a76e2a7ecd31ee52fdc8301f0603551d230418301680148aeee5947cc67c5dd515a76e2a7ecd31ee52fdc8300f0603551d130101ff040530030101ff300d06092a864886f70d01010b05000382010100821d6b98cd457debd2b081aca27ebecd4f93acc828443b39eabffa9fa4e9e4543b46fcc31e2b5b48177903dea6969ac4a2cc6570650390f1b08d43a4c2f975c7ed8bf3356c7218380212451a8f11de46553cbcd65b4254ddb8f66834eb21dda2a8f33b581e1484557aca1b94ee8931ddf16037b7a7171321a91936afc27ffce395de75d5f70cb8b5aee05ff507088d65af1e43966cd42cbe6f7facf8dae055dd8222b1696521723f81245178595c985ae917fd4b3998773e1a97b7bd10085446f4259bcc09a454929282c1b89b71ed587a775e0a3d4536341f45dae969e806c96fefc71067776c02ba22122b9199b14c0c28c04487509070b97f3dd2d6d972733182017730820173020101304c3034310b3009060355040613024e4c310e300c060355040a0c05504b4353373115301306035504030c0c504b4353372043657274203102147bdeddd2444cd1cdfe5c41a8102c89b7df2e6cbf300d06096086480165030402010500300d06092a864886f70d0101010500048201005becd87195c1deff90c24c91269b55b3f069bc225c326c314c1a51786ffe14c830be4e4bc73cba36c97677b44168279be91e7cdf7c19386ae21862719d13a3a0fff0803d460962f2cda8371484873252c3d7054db8143e2b081a3816ed0804ca5099ae5fece83d5c2c3783b1988b4b46dc94e55587a107ea1546bf22d28a097f652a4066dc2965269069af2f5176bb8ce9ca6d11f96757f03204f756703587d00ad424796c92fc7aeb6f494431999eda30990e4f5773632ed258fe0276673599da6fce35cdad7726a0bb024cad996b88e0cb98854ceb5c0b6ec748d9f9ce6a6cd437858bacb814618a272ff3a415c6e07f3db0988777fdec845a97bf7d102dd0"
diff --git a/tests/suites/test_suite_pkcs7.function b/tests/suites/test_suite_pkcs7.function
index 91fe47b..cc032ac 100644
--- a/tests/suites/test_suite_pkcs7.function
+++ b/tests/suites/test_suite_pkcs7.function
@@ -7,10 +7,11 @@
 #include "mbedtls/oid.h"
 #include "sys/types.h"
 #include "sys/stat.h"
+#include "mbedtls/rsa.h"
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
- * depends_on:MBEDTLS_PKCS7_C:MBEDTLS_RSA_C
+ * depends_on:MBEDTLS_PKCS7_C
  * END_DEPENDENCIES
  */
 /* BEGIN_SUITE_HELPERS */
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index a2beeed..eddac7f 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -4485,6 +4485,18 @@
 depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
 verify_hash:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f"
 
+PSA verify hash: deterministic ECDSA SECP256R1 SHA-256
+depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
+verify_hash:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f"
+
+PSA verify hash: deterministic ECDSA SECP256R1 SHA-384
+depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_384:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA
+verify_hash:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_384):"59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c3553bcdb9c666fa90125a3c79f90397bdf5f6a13de828684f":"dbf3b9a150a2ec12ec4b16ff7d37be2fe354a357cb267af4296ccfda3acca2d796989f63eb192e4c43a7ff0d0b7f493b1334dfb3c32375351debcdd532f41e13"
+
+PSA verify hash: deterministic ECDSA SECP384R1 SHA-256
+depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_384
+verify_hash:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04d9c662b50ba29ca47990450e043aeaf4f0c69b15676d112f622a71c93059af999691c5680d2b44d111579db12f4a413a2ed5c45fcfb67b5b63e00b91ebe59d09a6b1ac2c0c4282aa12317ed5914f999bc488bb132e8342cc36f2ca5e3379c747":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"bed412df472eef873fb0839f91a6867d1c6824d4c5781d4b851faa43c7df904d99dbdd28c0d2fd3a4a006e89d34993a120aff166deb4974e96449a7ffe93c66726ad9443b14b87330c86bdde3faff5fd1cbfdc9afe46f8090376f9664cb116b4"
+
 PSA vrfy hash int: ECDSA SECP256R1, good
 depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECP_R1_256
 verify_hash_interruptible:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED
@@ -4493,6 +4505,18 @@
 depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
 verify_hash_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED
 
+PSA vrfy hash: det ECDSA SECP256R1 SHA-256
+depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
+verify_hash_interruptible:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED
+
+PSA vrfy hash: det ECDSA SECP256R1 SHA-384
+depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_384:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA
+verify_hash_interruptible:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_384):"59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c3553bcdb9c666fa90125a3c79f90397bdf5f6a13de828684f":"dbf3b9a150a2ec12ec4b16ff7d37be2fe354a357cb267af4296ccfda3acca2d796989f63eb192e4c43a7ff0d0b7f493b1334dfb3c32375351debcdd532f41e13":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED
+
+PSA vrfy hash: det ECDSA SECP384R1 SHA-256
+depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_384
+verify_hash_interruptible:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04d9c662b50ba29ca47990450e043aeaf4f0c69b15676d112f622a71c93059af999691c5680d2b44d111579db12f4a413a2ed5c45fcfb67b5b63e00b91ebe59d09a6b1ac2c0c4282aa12317ed5914f999bc488bb132e8342cc36f2ca5e3379c747":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"bed412df472eef873fb0839f91a6867d1c6824d4c5781d4b851faa43c7df904d99dbdd28c0d2fd3a4a006e89d34993a120aff166deb4974e96449a7ffe93c66726ad9443b14b87330c86bdde3faff5fd1cbfdc9afe46f8090376f9664cb116b4":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED
+
 PSA verify hash: ECDSA SECP256R1, wrong signature size (correct but ASN1-encoded)
 depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECP_R1_256
 verify_hash_fail:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"304502206a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151022100ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_ERROR_INVALID_SIGNATURE
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 182443a..231b47f 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -6479,7 +6479,7 @@
  * Note: This test can currently only handle ECDSA.
  *
  * 1. Test interruptible sign hash with known outcomes (deterministic ECDSA
- *    only).
+ *    and private keys / keypairs only).
  *
  * 2. Test the number of calls to psa_sign_hash_complete() required are as
  *    expected for different max_ops values.
@@ -6870,9 +6870,9 @@
  *
  * Note: This test can currently only handle ECDSA.
  *
- * 1. Test that we can sign an input hash with the given key and then afterwards
- *    verify that signature. This is currently the only way to test non
- *    deterministic ECDSA, but this test can also handle deterministic.
+ * 1. Test that we can sign an input hash with the given keypair and then
+ *    afterwards verify that signature. This is currently the only way to test
+ *    non deterministic ECDSA, but this test can also handle deterministic.
  *
  * 2. Test that after corrupting the hash, the verification detects an invalid
  *    signature.
@@ -7075,7 +7075,8 @@
  * Note: This test can currently only handle ECDSA.
  *
  * 1. Test interruptible verify hash with known outcomes (deterministic ECDSA
- *    only).
+ *    only). Given this test only does verification it can accept public keys as
+ *    well as private keys / keypairs.
  *
  * 2. Test the number of calls to psa_verify_hash_complete() required are as
  *    expected for different max_ops values.
diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.data b/tests/suites/test_suite_psa_crypto_driver_wrappers.data
index 843bc82..311ce08 100644
--- a/tests/suites/test_suite_psa_crypto_driver_wrappers.data
+++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.data
@@ -820,3 +820,48 @@
 PSA AEAD decrypt setup, AES-GCM, 144 bytes #1, insufficient memory
 depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
 aead_decrypt_setup:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c87281":"4365847fe0b7b7fbed325953df344a96":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":PSA_ERROR_INSUFFICIENT_MEMORY:PSA_ERROR_INSUFFICIENT_MEMORY
+
+PSA PAKE transparent driver: setup(via input) in-driver forced status
+pake_operations:"abcd":PSA_ERROR_GENERIC_ERROR:PSA_SUCCESS:"":PSA_ERROR_GENERIC_ERROR:0
+
+PSA PAKE transparent driver: setup(via output) in-driver forced status
+pake_operations:"abcd":PSA_ERROR_GENERIC_ERROR:PSA_SUCCESS:"":PSA_ERROR_GENERIC_ERROR:1
+
+PSA PAKE transparent driver: input in-driver forced status
+pake_operations:"abcd":PSA_SUCCESS:PSA_ERROR_GENERIC_ERROR:"":PSA_ERROR_GENERIC_ERROR:2
+
+PSA PAKE transparent driver: output in-driver forced status
+pake_operations:"abcd":PSA_SUCCESS:PSA_ERROR_GENERIC_ERROR:"":PSA_ERROR_GENERIC_ERROR:3
+
+PSA PAKE transparent driver: output in-driver forced output
+pake_operations:"abcd":PSA_SUCCESS:PSA_SUCCESS:"1234":PSA_SUCCESS:3
+
+PSA PAKE transparent driver: get_key in-driver forced status
+pake_operations:"abcd":PSA_SUCCESS:PSA_ERROR_GENERIC_ERROR:"":PSA_ERROR_GENERIC_ERROR:4
+
+PSA PAKE transparent driver: abort in-driver forced status
+pake_operations:"abcd":PSA_SUCCESS:PSA_ERROR_GENERIC_ERROR:"":PSA_ERROR_GENERIC_ERROR:5
+
+PSA PAKE transparent driver: setup(via input) fallback not available
+depends_on:!MBEDTLS_PSA_BUILTIN_PAKE
+pake_operations:"abcd":PSA_ERROR_NOT_SUPPORTED:PSA_SUCCESS:"":PSA_ERROR_NOT_SUPPORTED:0
+
+PSA PAKE transparent driver: setup(via output) fallback not available
+depends_on:!MBEDTLS_PSA_BUILTIN_PAKE
+pake_operations:"abcd":PSA_ERROR_NOT_SUPPORTED:PSA_SUCCESS:"":PSA_ERROR_NOT_SUPPORTED:1
+
+PSA PAKE transparent driver: input fallback not available
+depends_on:!MBEDTLS_PSA_BUILTIN_PAKE
+pake_operations:"abcd":PSA_ERROR_NOT_SUPPORTED:PSA_SUCCESS:"":PSA_ERROR_NOT_SUPPORTED:2
+
+PSA PAKE transparent driver: output fallback not available
+depends_on:!MBEDTLS_PSA_BUILTIN_PAKE
+pake_operations:"abcd":PSA_ERROR_NOT_SUPPORTED:PSA_SUCCESS:"":PSA_ERROR_NOT_SUPPORTED:3
+
+PSA PAKE: ecjpake rounds transparent driver: in-driver success
+depends_on:PSA_WANT_ALG_JPAKE:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PSK_TO_MS
+ecjpake_rounds:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"abcdef":0:1
+
+PSA PAKE: ecjpake rounds transparent driver: fallback success
+depends_on:PSA_WANT_ALG_JPAKE:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PSK_TO_MS:MBEDTLS_PSA_BUILTIN_ALG_JPAKE
+ecjpake_rounds:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"abcdef":0:0
diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function
index 8bb3e35..56f4d1d 100644
--- a/tests/suites/test_suite_psa_crypto_driver_wrappers.function
+++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.function
@@ -1,6 +1,419 @@
 /* BEGIN_HEADER */
 #include "test/drivers/test_driver.h"
 
+/* Auxiliary variables for pake tests.
+   Global to silent the compiler when unused. */
+size_t pake_expected_hit_count = 0;
+int pake_in_driver = 0;
+
+/* The only two JPAKE user/peer identifiers supported for the time being. */
+static const uint8_t jpake_server_id[] = { 's', 'e', 'r', 'v', 'e', 'r' };
+static const uint8_t jpake_client_id[] = { 'c', 'l', 'i', 'e', 'n', 't' };
+
+#if defined(PSA_WANT_ALG_JPAKE) && defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) && \
+    defined(PSA_WANT_ECC_SECP_R1_256) && defined(PSA_WANT_ALG_SHA_256)
+static void ecjpake_do_round(psa_algorithm_t alg, unsigned int primitive,
+                             psa_pake_operation_t *server,
+                             psa_pake_operation_t *client,
+                             int client_input_first,
+                             int round)
+{
+    unsigned char *buffer0 = NULL, *buffer1 = NULL;
+    size_t buffer_length = (
+        PSA_PAKE_OUTPUT_SIZE(alg, primitive, PSA_PAKE_STEP_KEY_SHARE) +
+        PSA_PAKE_OUTPUT_SIZE(alg, primitive, PSA_PAKE_STEP_ZK_PUBLIC) +
+        PSA_PAKE_OUTPUT_SIZE(alg, primitive, PSA_PAKE_STEP_ZK_PROOF)) * 2;
+    /* The output should be exactly this size according to the spec */
+    const size_t expected_size_key_share =
+        PSA_PAKE_OUTPUT_SIZE(alg, primitive, PSA_PAKE_STEP_KEY_SHARE);
+    /* The output should be exactly this size according to the spec */
+    const size_t expected_size_zk_public =
+        PSA_PAKE_OUTPUT_SIZE(alg, primitive, PSA_PAKE_STEP_ZK_PUBLIC);
+    /* The output can be smaller: the spec allows stripping leading zeroes */
+    const size_t max_expected_size_zk_proof =
+        PSA_PAKE_OUTPUT_SIZE(alg, primitive, PSA_PAKE_STEP_ZK_PROOF);
+    size_t buffer0_off = 0;
+    size_t buffer1_off = 0;
+    size_t s_g1_len, s_g2_len, s_a_len;
+    size_t s_g1_off, s_g2_off, s_a_off;
+    size_t s_x1_pk_len, s_x2_pk_len, s_x2s_pk_len;
+    size_t s_x1_pk_off, s_x2_pk_off, s_x2s_pk_off;
+    size_t s_x1_pr_len, s_x2_pr_len, s_x2s_pr_len;
+    size_t s_x1_pr_off, s_x2_pr_off, s_x2s_pr_off;
+    size_t c_g1_len, c_g2_len, c_a_len;
+    size_t c_g1_off, c_g2_off, c_a_off;
+    size_t c_x1_pk_len, c_x2_pk_len, c_x2s_pk_len;
+    size_t c_x1_pk_off, c_x2_pk_off, c_x2s_pk_off;
+    size_t c_x1_pr_len, c_x2_pr_len, c_x2s_pr_len;
+    size_t c_x1_pr_off, c_x2_pr_off, c_x2s_pr_off;
+    psa_status_t status;
+
+    ASSERT_ALLOC(buffer0, buffer_length);
+    ASSERT_ALLOC(buffer1, buffer_length);
+
+    switch (round) {
+        case 1:
+            /* Server first round Output */
+            PSA_ASSERT(psa_pake_output(server, PSA_PAKE_STEP_KEY_SHARE,
+                                       buffer0 + buffer0_off,
+                                       512 - buffer0_off, &s_g1_len));
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(s_g1_len, expected_size_key_share);
+            s_g1_off = buffer0_off;
+            buffer0_off += s_g1_len;
+            PSA_ASSERT(psa_pake_output(server, PSA_PAKE_STEP_ZK_PUBLIC,
+                                       buffer0 + buffer0_off,
+                                       512 - buffer0_off, &s_x1_pk_len));
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(s_x1_pk_len, expected_size_zk_public);
+            s_x1_pk_off = buffer0_off;
+            buffer0_off += s_x1_pk_len;
+            PSA_ASSERT(psa_pake_output(server, PSA_PAKE_STEP_ZK_PROOF,
+                                       buffer0 + buffer0_off,
+                                       512 - buffer0_off, &s_x1_pr_len));
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_LE_U(s_x1_pr_len, max_expected_size_zk_proof);
+            s_x1_pr_off = buffer0_off;
+            buffer0_off += s_x1_pr_len;
+            PSA_ASSERT(psa_pake_output(server, PSA_PAKE_STEP_KEY_SHARE,
+                                       buffer0 + buffer0_off,
+                                       512 - buffer0_off, &s_g2_len));
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(s_g2_len, expected_size_key_share);
+            s_g2_off = buffer0_off;
+            buffer0_off += s_g2_len;
+            PSA_ASSERT(psa_pake_output(server, PSA_PAKE_STEP_ZK_PUBLIC,
+                                       buffer0 + buffer0_off,
+                                       512 - buffer0_off, &s_x2_pk_len));
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(s_x2_pk_len, expected_size_zk_public);
+            s_x2_pk_off = buffer0_off;
+            buffer0_off += s_x2_pk_len;
+            PSA_ASSERT(psa_pake_output(server, PSA_PAKE_STEP_ZK_PROOF,
+                                       buffer0 + buffer0_off,
+                                       512 - buffer0_off, &s_x2_pr_len));
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_LE_U(s_x2_pr_len, max_expected_size_zk_proof);
+            s_x2_pr_off = buffer0_off;
+            buffer0_off += s_x2_pr_len;
+
+            if (client_input_first == 1) {
+                /* Client first round Input */
+                status = psa_pake_input(client, PSA_PAKE_STEP_KEY_SHARE,
+                                        buffer0 + s_g1_off, s_g1_len);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                           pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+                TEST_EQUAL(status, PSA_SUCCESS);
+
+                status = psa_pake_input(client, PSA_PAKE_STEP_ZK_PUBLIC,
+                                        buffer0 + s_x1_pk_off,
+                                        s_x1_pk_len);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                           pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+                TEST_EQUAL(status, PSA_SUCCESS);
+
+                status = psa_pake_input(client, PSA_PAKE_STEP_ZK_PROOF,
+                                        buffer0 + s_x1_pr_off,
+                                        s_x1_pr_len);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                           pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+                TEST_EQUAL(status, PSA_SUCCESS);
+
+                status = psa_pake_input(client, PSA_PAKE_STEP_KEY_SHARE,
+                                        buffer0 + s_g2_off,
+                                        s_g2_len);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                           pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+                TEST_EQUAL(status, PSA_SUCCESS);
+
+                status = psa_pake_input(client, PSA_PAKE_STEP_ZK_PUBLIC,
+                                        buffer0 + s_x2_pk_off,
+                                        s_x2_pk_len);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                           pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+                TEST_EQUAL(status, PSA_SUCCESS);
+
+                status = psa_pake_input(client, PSA_PAKE_STEP_ZK_PROOF,
+                                        buffer0 + s_x2_pr_off,
+                                        s_x2_pr_len);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                           pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+                TEST_EQUAL(status, PSA_SUCCESS);
+            }
+
+            /* Adjust for indirect client driver setup in first pake_output call. */
+            pake_expected_hit_count++;
+
+            /* Client first round Output */
+            PSA_ASSERT(psa_pake_output(client, PSA_PAKE_STEP_KEY_SHARE,
+                                       buffer1 + buffer1_off,
+                                       512 - buffer1_off, &c_g1_len));
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(c_g1_len, expected_size_key_share);
+            c_g1_off = buffer1_off;
+            buffer1_off += c_g1_len;
+            PSA_ASSERT(psa_pake_output(client, PSA_PAKE_STEP_ZK_PUBLIC,
+                                       buffer1 + buffer1_off,
+                                       512 - buffer1_off, &c_x1_pk_len));
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(c_x1_pk_len, expected_size_zk_public);
+            c_x1_pk_off = buffer1_off;
+            buffer1_off += c_x1_pk_len;
+            PSA_ASSERT(psa_pake_output(client, PSA_PAKE_STEP_ZK_PROOF,
+                                       buffer1 + buffer1_off,
+                                       512 - buffer1_off, &c_x1_pr_len));
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_LE_U(c_x1_pr_len, max_expected_size_zk_proof);
+            c_x1_pr_off = buffer1_off;
+            buffer1_off += c_x1_pr_len;
+            PSA_ASSERT(psa_pake_output(client, PSA_PAKE_STEP_KEY_SHARE,
+                                       buffer1 + buffer1_off,
+                                       512 - buffer1_off, &c_g2_len));
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(c_g2_len, expected_size_key_share);
+            c_g2_off = buffer1_off;
+            buffer1_off += c_g2_len;
+            PSA_ASSERT(psa_pake_output(client, PSA_PAKE_STEP_ZK_PUBLIC,
+                                       buffer1 + buffer1_off,
+                                       512 - buffer1_off, &c_x2_pk_len));
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(c_x2_pk_len, expected_size_zk_public);
+            c_x2_pk_off = buffer1_off;
+            buffer1_off += c_x2_pk_len;
+            PSA_ASSERT(psa_pake_output(client, PSA_PAKE_STEP_ZK_PROOF,
+                                       buffer1 + buffer1_off,
+                                       512 - buffer1_off, &c_x2_pr_len));
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_LE_U(c_x2_pr_len, max_expected_size_zk_proof);
+            c_x2_pr_off = buffer1_off;
+            buffer1_off += c_x2_pr_len;
+
+            if (client_input_first == 0) {
+                /* Client first round Input */
+                status = psa_pake_input(client, PSA_PAKE_STEP_KEY_SHARE,
+                                        buffer0 + s_g1_off, s_g1_len);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                           pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+                TEST_EQUAL(status, PSA_SUCCESS);
+
+                status = psa_pake_input(client, PSA_PAKE_STEP_ZK_PUBLIC,
+                                        buffer0 + s_x1_pk_off,
+                                        s_x1_pk_len);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                           pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+                TEST_EQUAL(status, PSA_SUCCESS);
+
+                status = psa_pake_input(client, PSA_PAKE_STEP_ZK_PROOF,
+                                        buffer0 + s_x1_pr_off,
+                                        s_x1_pr_len);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                           pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+                TEST_EQUAL(status, PSA_SUCCESS);
+
+                status = psa_pake_input(client, PSA_PAKE_STEP_KEY_SHARE,
+                                        buffer0 + s_g2_off,
+                                        s_g2_len);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                           pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+                TEST_EQUAL(status, PSA_SUCCESS);
+
+                status = psa_pake_input(client, PSA_PAKE_STEP_ZK_PUBLIC,
+                                        buffer0 + s_x2_pk_off,
+                                        s_x2_pk_len);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                           pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+                TEST_EQUAL(status, PSA_SUCCESS);
+
+                status = psa_pake_input(client, PSA_PAKE_STEP_ZK_PROOF,
+                                        buffer0 + s_x2_pr_off,
+                                        s_x2_pr_len);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                           pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+                TEST_EQUAL(status, PSA_SUCCESS);
+            }
+
+            /* Server first round Input */
+            status = psa_pake_input(server, PSA_PAKE_STEP_KEY_SHARE,
+                                    buffer1 + c_g1_off, c_g1_len);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(status, PSA_SUCCESS);
+
+            status = psa_pake_input(server, PSA_PAKE_STEP_ZK_PUBLIC,
+                                    buffer1 + c_x1_pk_off, c_x1_pk_len);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(status, PSA_SUCCESS);
+
+            status = psa_pake_input(server, PSA_PAKE_STEP_ZK_PROOF,
+                                    buffer1 + c_x1_pr_off, c_x1_pr_len);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(status, PSA_SUCCESS);
+
+            status = psa_pake_input(server, PSA_PAKE_STEP_KEY_SHARE,
+                                    buffer1 + c_g2_off, c_g2_len);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(status, PSA_SUCCESS);
+
+            status = psa_pake_input(server, PSA_PAKE_STEP_ZK_PUBLIC,
+                                    buffer1 + c_x2_pk_off, c_x2_pk_len);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(status, PSA_SUCCESS);
+
+            status = psa_pake_input(server, PSA_PAKE_STEP_ZK_PROOF,
+                                    buffer1 + c_x2_pr_off, c_x2_pr_len);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(status, PSA_SUCCESS);
+
+            break;
+
+        case 2:
+            /* Server second round Output */
+            buffer0_off = 0;
+
+            PSA_ASSERT(psa_pake_output(server, PSA_PAKE_STEP_KEY_SHARE,
+                                       buffer0 + buffer0_off,
+                                       512 - buffer0_off, &s_a_len));
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(s_a_len, expected_size_key_share);
+            s_a_off = buffer0_off;
+            buffer0_off += s_a_len;
+            PSA_ASSERT(psa_pake_output(server, PSA_PAKE_STEP_ZK_PUBLIC,
+                                       buffer0 + buffer0_off,
+                                       512 - buffer0_off, &s_x2s_pk_len));
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(s_x2s_pk_len, expected_size_zk_public);
+            s_x2s_pk_off = buffer0_off;
+            buffer0_off += s_x2s_pk_len;
+            PSA_ASSERT(psa_pake_output(server, PSA_PAKE_STEP_ZK_PROOF,
+                                       buffer0 + buffer0_off,
+                                       512 - buffer0_off, &s_x2s_pr_len));
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_LE_U(s_x2s_pr_len, max_expected_size_zk_proof);
+            s_x2s_pr_off = buffer0_off;
+            buffer0_off += s_x2s_pr_len;
+
+            if (client_input_first == 1) {
+                /* Client second round Input */
+                status = psa_pake_input(client, PSA_PAKE_STEP_KEY_SHARE,
+                                        buffer0 + s_a_off, s_a_len);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                           pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+                TEST_EQUAL(status, PSA_SUCCESS);
+
+                status = psa_pake_input(client, PSA_PAKE_STEP_ZK_PUBLIC,
+                                        buffer0 + s_x2s_pk_off,
+                                        s_x2s_pk_len);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                           pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+                TEST_EQUAL(status, PSA_SUCCESS);
+
+                status = psa_pake_input(client, PSA_PAKE_STEP_ZK_PROOF,
+                                        buffer0 + s_x2s_pr_off,
+                                        s_x2s_pr_len);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                           pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+                TEST_EQUAL(status, PSA_SUCCESS);
+            }
+
+            /* Client second round Output */
+            buffer1_off = 0;
+
+            PSA_ASSERT(psa_pake_output(client, PSA_PAKE_STEP_KEY_SHARE,
+                                       buffer1 + buffer1_off,
+                                       512 - buffer1_off, &c_a_len));
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(c_a_len, expected_size_key_share);
+            c_a_off = buffer1_off;
+            buffer1_off += c_a_len;
+            PSA_ASSERT(psa_pake_output(client, PSA_PAKE_STEP_ZK_PUBLIC,
+                                       buffer1 + buffer1_off,
+                                       512 - buffer1_off, &c_x2s_pk_len));
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(c_x2s_pk_len, expected_size_zk_public);
+            c_x2s_pk_off = buffer1_off;
+            buffer1_off += c_x2s_pk_len;
+            PSA_ASSERT(psa_pake_output(client, PSA_PAKE_STEP_ZK_PROOF,
+                                       buffer1 + buffer1_off,
+                                       512 - buffer1_off, &c_x2s_pr_len));
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_LE_U(c_x2s_pr_len, max_expected_size_zk_proof);
+            c_x2s_pr_off = buffer1_off;
+            buffer1_off += c_x2s_pr_len;
+
+            if (client_input_first == 0) {
+                /* Client second round Input */
+                status = psa_pake_input(client, PSA_PAKE_STEP_KEY_SHARE,
+                                        buffer0 + s_a_off, s_a_len);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                           pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+                TEST_EQUAL(status, PSA_SUCCESS);
+
+                status = psa_pake_input(client, PSA_PAKE_STEP_ZK_PUBLIC,
+                                        buffer0 + s_x2s_pk_off,
+                                        s_x2s_pk_len);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                           pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+                TEST_EQUAL(status, PSA_SUCCESS);
+
+                status = psa_pake_input(client, PSA_PAKE_STEP_ZK_PROOF,
+                                        buffer0 + s_x2s_pr_off,
+                                        s_x2s_pr_len);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                           pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+                TEST_EQUAL(status, PSA_SUCCESS);
+            }
+
+            /* Server second round Input */
+            status = psa_pake_input(server, PSA_PAKE_STEP_KEY_SHARE,
+                                    buffer1 + c_a_off, c_a_len);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(status, PSA_SUCCESS);
+
+            status = psa_pake_input(server, PSA_PAKE_STEP_ZK_PUBLIC,
+                                    buffer1 + c_x2s_pk_off, c_x2s_pk_len);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(status, PSA_SUCCESS);
+
+            status = psa_pake_input(server, PSA_PAKE_STEP_ZK_PROOF,
+                                    buffer1 + c_x2s_pr_off, c_x2s_pr_len);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+                       pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+            TEST_EQUAL(status, PSA_SUCCESS);
+
+            break;
+    }
+
+exit:
+    mbedtls_free(buffer0);
+    mbedtls_free(buffer1);
+}
+#endif /* PSA_WANT_ALG_JPAKE */
+
 #if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY)
 /* Sanity checks on the output of RSA encryption.
  *
@@ -2567,3 +2980,304 @@
     PSA_DONE();
 }
 /* END_CASE */
+
+/* BEGIN_CASE depends_on:PSA_WANT_ALG_JPAKE */
+void pake_operations(data_t *pw_data, int forced_status_setup_arg, int forced_status_arg,
+                     data_t *forced_output, int expected_status_arg,
+                     int fut)
+{
+    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_status_t forced_status = forced_status_arg;
+    psa_status_t forced_status_setup = forced_status_setup_arg;
+    psa_status_t expected_status = expected_status_arg;
+    psa_pake_operation_t operation = psa_pake_operation_init();
+    psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
+    psa_key_derivation_operation_t implicit_key =
+        PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_pake_primitive_t primitive = PSA_PAKE_PRIMITIVE(
+        PSA_PAKE_PRIMITIVE_TYPE_ECC,
+        PSA_ECC_FAMILY_SECP_R1, 256);
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    unsigned char *input_buffer = NULL;
+    const size_t size_key_share = PSA_PAKE_INPUT_SIZE(PSA_ALG_JPAKE, primitive,
+                                                      PSA_PAKE_STEP_KEY_SHARE);
+    unsigned char *output_buffer = NULL;
+    size_t output_len = 0;
+    size_t output_size = PSA_PAKE_OUTPUT_SIZE(PSA_ALG_JPAKE, primitive,
+                                              PSA_PAKE_STEP_KEY_SHARE);
+    int in_driver = (forced_status_setup_arg == PSA_SUCCESS);
+
+    ASSERT_ALLOC(input_buffer,
+                 PSA_PAKE_INPUT_SIZE(PSA_ALG_JPAKE, primitive,
+                                     PSA_PAKE_STEP_KEY_SHARE));
+    memset(input_buffer, 0xAA, size_key_share);
+
+    ASSERT_ALLOC(output_buffer,
+                 PSA_PAKE_INPUT_SIZE(PSA_ALG_JPAKE, primitive,
+                                     PSA_PAKE_STEP_KEY_SHARE));
+    memset(output_buffer, 0x55, output_size);
+
+    PSA_INIT();
+
+    mbedtls_test_driver_pake_hooks = mbedtls_test_driver_pake_hooks_init();
+
+    if (pw_data->len > 0) {
+        psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE);
+        psa_set_key_algorithm(&attributes, PSA_ALG_JPAKE);
+        psa_set_key_type(&attributes, PSA_KEY_TYPE_PASSWORD);
+        PSA_ASSERT(psa_import_key(&attributes, pw_data->x, pw_data->len,
+                                  &key));
+    }
+
+    psa_pake_cs_set_algorithm(&cipher_suite, PSA_ALG_JPAKE);
+    psa_pake_cs_set_primitive(&cipher_suite, primitive);
+    psa_pake_cs_set_hash(&cipher_suite, PSA_ALG_SHA_256);
+
+    mbedtls_test_driver_pake_hooks.forced_status = forced_status_setup;
+
+    /* Collecting input stage (no driver entry points) */
+
+    TEST_EQUAL(psa_pake_setup(&operation, &cipher_suite),
+               PSA_SUCCESS);
+
+    PSA_ASSERT(psa_pake_set_user(&operation, jpake_server_id, sizeof(jpake_server_id)));
+    PSA_ASSERT(psa_pake_set_peer(&operation, jpake_client_id, sizeof(jpake_client_id)));
+
+    TEST_EQUAL(psa_pake_set_password_key(&operation, key),
+               PSA_SUCCESS);
+
+    TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total, 0);
+
+    /* Computation stage (driver entry points) */
+
+    switch (fut) {
+        case 0: /* setup (via input) */
+            /* --- psa_pake_input (driver: setup, input) --- */
+            mbedtls_test_driver_pake_hooks.forced_setup_status = forced_status_setup;
+            mbedtls_test_driver_pake_hooks.forced_status = forced_status;
+            TEST_EQUAL(psa_pake_input(&operation, PSA_PAKE_STEP_KEY_SHARE,
+                                      input_buffer, size_key_share),
+                       expected_status);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total, 1);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.setup, 1);
+            break;
+
+        case 1: /* setup (via output) */
+            /* --- psa_pake_output (driver: setup, output) --- */
+            mbedtls_test_driver_pake_hooks.forced_setup_status = forced_status_setup;
+            mbedtls_test_driver_pake_hooks.forced_status = forced_status;
+            TEST_EQUAL(psa_pake_output(&operation, PSA_PAKE_STEP_KEY_SHARE,
+                                       output_buffer, output_size, &output_len),
+                       expected_status);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total, 1);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.setup, 1);
+            break;
+
+        case 2: /* input */
+            /* --- psa_pake_input (driver: setup, input, abort) --- */
+            mbedtls_test_driver_pake_hooks.forced_setup_status = forced_status_setup;
+            mbedtls_test_driver_pake_hooks.forced_status = forced_status;
+            TEST_EQUAL(psa_pake_input(&operation, PSA_PAKE_STEP_KEY_SHARE,
+                                      input_buffer, size_key_share),
+                       expected_status);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total, in_driver ? 3 : 1);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.setup, 1);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.input, in_driver ? 1 : 0);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.abort, in_driver ? 1 : 0);
+            break;
+
+        case 3: /* output */
+            /* --- psa_pake_output (driver: setup, output, (abort)) --- */
+            mbedtls_test_driver_pake_hooks.forced_setup_status = forced_status_setup;
+            mbedtls_test_driver_pake_hooks.forced_status = forced_status;
+            if (forced_output->len > 0) {
+                mbedtls_test_driver_pake_hooks.forced_output = forced_output->x;
+                mbedtls_test_driver_pake_hooks.forced_output_length = forced_output->len;
+            }
+            TEST_EQUAL(psa_pake_output(&operation, PSA_PAKE_STEP_KEY_SHARE,
+                                       output_buffer, output_size, &output_len),
+                       expected_status);
+
+            if (forced_output->len > 0) {
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total, in_driver ? 2 : 1);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.setup, 1);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.output, in_driver ? 1 : 0);
+                TEST_EQUAL(output_len, forced_output->len);
+                TEST_EQUAL(memcmp(output_buffer, forced_output->x, output_len), 0);
+            } else {
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total, in_driver ? 3 : 1);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.setup, 1);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.output, in_driver ? 1 : 0);
+                TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.abort, in_driver ? 1 : 0);
+            }
+            break;
+
+        case 4: /* get_implicit_key */
+            /* Call driver setup indirectly */
+            TEST_EQUAL(psa_pake_input(&operation, PSA_PAKE_STEP_KEY_SHARE,
+                                      input_buffer, size_key_share),
+                       PSA_SUCCESS);
+
+            /* Simulate that we are ready to get implicit key. */
+            operation.computation_stage.jpake.input_step = PSA_PAKE_STEP_DERIVE;
+            operation.computation_stage.jpake.output_step = PSA_PAKE_STEP_DERIVE;
+
+            /* --- psa_pake_get_implicit_key --- */
+            mbedtls_test_driver_pake_hooks.forced_status = forced_status;
+            memset(&mbedtls_test_driver_pake_hooks.hits, 0,
+                   sizeof(mbedtls_test_driver_pake_hooks.hits));
+            TEST_EQUAL(psa_pake_get_implicit_key(&operation, &implicit_key),
+                       expected_status);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total, 2);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.implicit_key, 1);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.abort, 1);
+
+            break;
+
+        case 5: /* abort */
+            /* Call driver setup indirectly */
+            TEST_EQUAL(psa_pake_input(&operation, PSA_PAKE_STEP_KEY_SHARE,
+                                      input_buffer, size_key_share),
+                       PSA_SUCCESS);
+
+            /* --- psa_pake_abort --- */
+            mbedtls_test_driver_pake_hooks.forced_status = forced_status;
+            memset(&mbedtls_test_driver_pake_hooks.hits, 0,
+                   sizeof(mbedtls_test_driver_pake_hooks.hits));
+            TEST_EQUAL(psa_pake_abort(&operation), expected_status);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total, 1);
+            TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.abort, 1);
+            break;
+
+        default:
+            break;
+    }
+
+    /* Clean up */
+    mbedtls_test_driver_pake_hooks.forced_setup_status = PSA_SUCCESS;
+    mbedtls_test_driver_pake_hooks.forced_status = PSA_SUCCESS;
+    TEST_EQUAL(psa_pake_abort(&operation), PSA_SUCCESS);
+exit:
+    /*
+     * Key attributes may have been returned by psa_get_key_attributes()
+     * thus reset them as required.
+     */
+    psa_reset_key_attributes(&attributes);
+    mbedtls_free(input_buffer);
+    mbedtls_free(output_buffer);
+    psa_destroy_key(key);
+    mbedtls_test_driver_pake_hooks =
+        mbedtls_test_driver_pake_hooks_init();
+    PSA_DONE();
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:PSA_WANT_ALG_JPAKE:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 */
+void ecjpake_rounds(int alg_arg, int primitive_arg, int hash_arg,
+                    int derive_alg_arg, data_t *pw_data,
+                    int client_input_first, int in_driver)
+{
+    psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
+    psa_pake_operation_t server = psa_pake_operation_init();
+    psa_pake_operation_t client = psa_pake_operation_init();
+    psa_algorithm_t alg = alg_arg;
+    psa_algorithm_t hash_alg = hash_arg;
+    psa_algorithm_t derive_alg = derive_alg_arg;
+    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_key_derivation_operation_t server_derive =
+        PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t client_derive =
+        PSA_KEY_DERIVATION_OPERATION_INIT;
+    pake_in_driver = in_driver;
+    /* driver setup is called indirectly through pake_output/pake_input */
+    if (pake_in_driver) {
+        pake_expected_hit_count = 2;
+    } else {
+        pake_expected_hit_count = 1;
+    }
+
+    PSA_INIT();
+
+    mbedtls_test_driver_pake_hooks = mbedtls_test_driver_pake_hooks_init();
+
+    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE);
+    psa_set_key_algorithm(&attributes, alg);
+    psa_set_key_type(&attributes, PSA_KEY_TYPE_PASSWORD);
+    PSA_ASSERT(psa_import_key(&attributes, pw_data->x, pw_data->len,
+                              &key));
+
+    psa_pake_cs_set_algorithm(&cipher_suite, alg);
+    psa_pake_cs_set_primitive(&cipher_suite, primitive_arg);
+    psa_pake_cs_set_hash(&cipher_suite, hash_alg);
+
+    /* Get shared key */
+    PSA_ASSERT(psa_key_derivation_setup(&server_derive, derive_alg));
+    PSA_ASSERT(psa_key_derivation_setup(&client_derive, derive_alg));
+
+    if (PSA_ALG_IS_TLS12_PSK_TO_MS(derive_alg)) {
+        PSA_ASSERT(psa_key_derivation_input_bytes(&server_derive,
+                                                  PSA_KEY_DERIVATION_INPUT_SEED,
+                                                  (const uint8_t *) "", 0));
+        PSA_ASSERT(psa_key_derivation_input_bytes(&client_derive,
+                                                  PSA_KEY_DERIVATION_INPUT_SEED,
+                                                  (const uint8_t *) "", 0));
+    }
+
+    if (!pake_in_driver) {
+        mbedtls_test_driver_pake_hooks.forced_setup_status = PSA_ERROR_NOT_SUPPORTED;
+    }
+
+    PSA_ASSERT(psa_pake_setup(&server, &cipher_suite));
+    TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total, 0);
+    PSA_ASSERT(psa_pake_setup(&client, &cipher_suite));
+    TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total, 0);
+
+
+    PSA_ASSERT(psa_pake_set_user(&server, jpake_server_id, sizeof(jpake_server_id)));
+    PSA_ASSERT(psa_pake_set_peer(&server, jpake_client_id, sizeof(jpake_client_id)));
+    TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total, 0);
+    PSA_ASSERT(psa_pake_set_user(&client, jpake_client_id, sizeof(jpake_client_id)));
+    PSA_ASSERT(psa_pake_set_peer(&client, jpake_server_id, sizeof(jpake_server_id)));
+    TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total, 0);
+    PSA_ASSERT(psa_pake_set_password_key(&server, key));
+    TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total, 0);
+    PSA_ASSERT(psa_pake_set_password_key(&client, key));
+    TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total, 0);
+
+    /* First round */
+    ecjpake_do_round(alg, primitive_arg, &server, &client,
+                     client_input_first, 1);
+
+    /* Second round */
+    ecjpake_do_round(alg, primitive_arg, &server, &client,
+                     client_input_first, 2);
+
+    /* After the key is obtained operation is aborted.
+       Adapt counter of expected hits. */
+    if (pake_in_driver) {
+        pake_expected_hit_count++;
+    }
+
+    PSA_ASSERT(psa_pake_get_implicit_key(&server, &server_derive));
+    TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+               pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+
+    /* After the key is obtained operation is aborted.
+       Adapt counter of expected hits. */
+    if (pake_in_driver) {
+        pake_expected_hit_count++;
+    }
+
+    PSA_ASSERT(psa_pake_get_implicit_key(&client, &client_derive));
+    TEST_EQUAL(mbedtls_test_driver_pake_hooks.hits.total,
+               pake_in_driver ? pake_expected_hit_count++ : pake_expected_hit_count);
+exit:
+    psa_key_derivation_abort(&server_derive);
+    psa_key_derivation_abort(&client_derive);
+    psa_destroy_key(key);
+    psa_pake_abort(&server);
+    psa_pake_abort(&client);
+    PSA_DONE();
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_psa_crypto_pake.data b/tests/suites/test_suite_psa_crypto_pake.data
index f447ef0..6215703 100644
--- a/tests/suites/test_suite_psa_crypto_pake.data
+++ b/tests/suites/test_suite_psa_crypto_pake.data
@@ -1,98 +1,106 @@
 PSA PAKE: uninitialized access to psa_pake_operation_t
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:ERR_INJECT_UNINITIALIZED_ACCESS:PSA_ERROR_BAD_STATE
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"client":"server":0:ERR_INJECT_UNINITIALIZED_ACCESS:PSA_ERROR_BAD_STATE
 
 PSA PAKE: invalid alg
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_SHA_256:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:ERR_IN_SETUP:PSA_ERROR_INVALID_ARGUMENT
+ecjpake_setup:PSA_ALG_SHA_256:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"client":"server":0:ERR_IN_SETUP:PSA_ERROR_INVALID_ARGUMENT
 
 PSA PAKE: invalid primitive type
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_DH, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:ERR_IN_SETUP:PSA_ERROR_NOT_SUPPORTED
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_DH, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"client":"server":0:ERR_IN_OUTPUT:PSA_ERROR_NOT_SUPPORTED
 
 PSA PAKE: invalid primitive family
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_K1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:ERR_IN_SETUP:PSA_ERROR_NOT_SUPPORTED
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_K1, 256):PSA_ALG_SHA_256:"client":"server":0:ERR_IN_OUTPUT:PSA_ERROR_NOT_SUPPORTED
 
 PSA PAKE: invalid primitive bits
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 128):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:ERR_IN_SETUP:PSA_ERROR_NOT_SUPPORTED
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 128):PSA_ALG_SHA_256:"client":"server":0:ERR_IN_OUTPUT:PSA_ERROR_NOT_SUPPORTED
 
 PSA PAKE: invalid hash
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_1:PSA_PAKE_ROLE_SERVER:0:ERR_IN_SETUP:PSA_ERROR_NOT_SUPPORTED
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_1:"client":"server":0:ERR_IN_OUTPUT:PSA_ERROR_NOT_SUPPORTED
 
 PSA PAKE: duplicate a valid setup
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:ERR_INJECT_DUPLICATE_SETUP:PSA_ERROR_BAD_STATE
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"client":"server":0:ERR_INJECT_DUPLICATE_SETUP:PSA_ERROR_BAD_STATE
 
-PSA PAKE: ecjpake setup invalid role NONE
+PSA PAKE: ecjpake setup role
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_NONE:0:ERR_IN_SET_ROLE:PSA_ERROR_NOT_SUPPORTED
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"client":"server":0:ERR_INJECT_SET_ROLE:PSA_ERROR_INVALID_ARGUMENT
 
 PSA PAKE: wrong password key type
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_HMAC:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:ERR_IN_SET_PASSWORD_KEY:PSA_ERROR_INVALID_ARGUMENT
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_HMAC:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"client":"server":0:ERR_IN_SET_PASSWORD_KEY:PSA_ERROR_INVALID_ARGUMENT
 
 PSA PAKE: wrong password key usage
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_ENCRYPT:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:ERR_IN_SET_PASSWORD_KEY:PSA_ERROR_NOT_PERMITTED
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_ENCRYPT:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"client":"server":0:ERR_IN_SET_PASSWORD_KEY:PSA_ERROR_NOT_PERMITTED
+
+PSA PAKE: set empty user
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"":"server":0:ERR_IN_SET_USER:PSA_ERROR_INVALID_ARGUMENT
+
+PSA PAKE: set empty peer
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"client":"":0:ERR_IN_SET_PEER:PSA_ERROR_INVALID_ARGUMENT
 
 PSA PAKE: set invalid user
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:ERR_INJECT_INVALID_USER:PSA_ERROR_INVALID_ARGUMENT
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"aaaa":"server":0:ERR_IN_SET_USER:PSA_ERROR_NOT_SUPPORTED
 
 PSA PAKE: set invalid peer
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:ERR_INJECT_INVALID_PEER:PSA_ERROR_INVALID_ARGUMENT
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"client":"aaaa":0:ERR_IN_SET_PEER:PSA_ERROR_NOT_SUPPORTED
 
-PSA PAKE: set user
+PSA PAKE: user already set
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:ERR_INJECT_SET_USER:PSA_ERROR_NOT_SUPPORTED
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"client":"server":0:ERR_DUPLICATE_SET_USER:PSA_ERROR_BAD_STATE
 
-PSA PAKE: set peer
+PSA PAKE: peer already set
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:ERR_INJECT_SET_PEER:PSA_ERROR_NOT_SUPPORTED
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"client":"server":0:ERR_DUPLICATE_SET_PEER:PSA_ERROR_BAD_STATE
+
+PSA PAKE: user and peer both servers
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"server":"server":0:ERR_IN_OUTPUT:PSA_ERROR_NOT_SUPPORTED
+
+PSA PAKE: user and peer both clients
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"client":"client":0:ERR_IN_OUTPUT:PSA_ERROR_NOT_SUPPORTED
 
 PSA PAKE: invalid input
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:1:ERR_INJECT_EMPTY_IO_BUFFER:PSA_ERROR_INVALID_ARGUMENT
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"client":"server":1:ERR_INJECT_EMPTY_IO_BUFFER:PSA_ERROR_INVALID_ARGUMENT
 
 PSA PAKE: unkown input step
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:1:ERR_INJECT_UNKNOWN_STEP:PSA_ERROR_INVALID_ARGUMENT
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"client":"server":1:ERR_INJECT_UNKNOWN_STEP:PSA_ERROR_INVALID_ARGUMENT
 
 PSA PAKE: invalid first input step
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:1:ERR_INJECT_INVALID_FIRST_STEP:PSA_ERROR_BAD_STATE
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"client":"server":1:ERR_INJECT_INVALID_FIRST_STEP:PSA_ERROR_BAD_STATE
 
 PSA PAKE: input buffer too large
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:1:ERR_INJECT_WRONG_BUFFER_SIZE:PSA_ERROR_INVALID_ARGUMENT
-
-PSA PAKE: valid input operation after a failure
-depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:1:ERR_INJECT_VALID_OPERATION_AFTER_FAILURE:PSA_ERROR_BAD_STATE
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"client":"server":1:ERR_INJECT_WRONG_BUFFER_SIZE:PSA_ERROR_INVALID_ARGUMENT
 
 PSA PAKE: invalid output
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:ERR_INJECT_EMPTY_IO_BUFFER:PSA_ERROR_INVALID_ARGUMENT
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"client":"server":0:ERR_INJECT_EMPTY_IO_BUFFER:PSA_ERROR_INVALID_ARGUMENT
 
 PSA PAKE: unkown output step
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:ERR_INJECT_UNKNOWN_STEP:PSA_ERROR_INVALID_ARGUMENT
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"client":"server":0:ERR_INJECT_UNKNOWN_STEP:PSA_ERROR_INVALID_ARGUMENT
 
 PSA PAKE: invalid first output step
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:ERR_INJECT_INVALID_FIRST_STEP:PSA_ERROR_BAD_STATE
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"client":"server":0:ERR_INJECT_INVALID_FIRST_STEP:PSA_ERROR_BAD_STATE
 
 PSA PAKE: output buffer too small
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:ERR_INJECT_WRONG_BUFFER_SIZE:PSA_ERROR_BUFFER_TOO_SMALL
-
-PSA PAKE: valid output operation after a failure
-depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
-ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:ERR_INJECT_VALID_OPERATION_AFTER_FAILURE:PSA_ERROR_BAD_STATE
+ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:"client":"server":0:ERR_INJECT_WRONG_BUFFER_SIZE:PSA_ERROR_BUFFER_TOO_SMALL
 
 PSA PAKE: check rounds w/o forced errors
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PSK_TO_MS
@@ -201,3 +209,18 @@
 PSA PAKE: ecjpake size macros
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
 ecjpake_size_macros:
+
+PSA PAKE: input getters: password
+pake_input_getters_password
+
+PSA PAKE: input getters: cipher suite
+pake_input_getters_cipher_suite
+
+PSA PAKE: input getters: role
+pake_input_getters_role
+
+PSA PAKE: input getters: user
+pake_input_getters_user
+
+PSA PAKE: input getters: peer
+pake_input_getters_peer
diff --git a/tests/suites/test_suite_psa_crypto_pake.function b/tests/suites/test_suite_psa_crypto_pake.function
index 4dffa3b..88f24dd 100644
--- a/tests/suites/test_suite_psa_crypto_pake.function
+++ b/tests/suites/test_suite_psa_crypto_pake.function
@@ -8,10 +8,11 @@
     /* errors forced internally in the code */
     ERR_INJECT_UNINITIALIZED_ACCESS,
     ERR_INJECT_DUPLICATE_SETUP,
-    ERR_INJECT_INVALID_USER,
-    ERR_INJECT_INVALID_PEER,
     ERR_INJECT_SET_USER,
     ERR_INJECT_SET_PEER,
+    ERR_INJECT_SET_ROLE,
+    ERR_DUPLICATE_SET_USER,
+    ERR_DUPLICATE_SET_PEER,
     ERR_INJECT_EMPTY_IO_BUFFER,
     ERR_INJECT_UNKNOWN_STEP,
     ERR_INJECT_INVALID_FIRST_STEP,
@@ -39,6 +40,8 @@
     ERR_INJECT_ROUND2_SERVER_ZK_PROOF,
     /* erros issued from the .data file */
     ERR_IN_SETUP,
+    ERR_IN_SET_USER,
+    ERR_IN_SET_PEER,
     ERR_IN_SET_ROLE,
     ERR_IN_SET_PASSWORD_KEY,
     ERR_IN_INPUT,
@@ -50,6 +53,10 @@
     PAKE_ROUND_TWO
 } pake_round_t;
 
+/* The only two JPAKE user/peer identifiers supported for the time being. */
+static const uint8_t jpake_server_id[] = { 's', 'e', 'r', 'v', 'e', 'r' };
+static const uint8_t jpake_client_id[] = { 'c', 'l', 'i', 'e', 'n', 't' };
+
 /*
  * Inject an error on the specified buffer ONLY it this is the correct stage.
  * Offset 7 is arbitrary, but chosen because it's "in the middle" of the part
@@ -537,7 +544,7 @@
 
 /* BEGIN_CASE depends_on:PSA_WANT_ALG_JPAKE */
 void ecjpake_setup(int alg_arg, int key_type_pw_arg, int key_usage_pw_arg,
-                   int primitive_arg, int hash_arg, int role_arg,
+                   int primitive_arg, int hash_arg, char *user_arg, char *peer_arg,
                    int test_input,
                    int err_stage_arg,
                    int expected_error_arg)
@@ -549,7 +556,6 @@
     psa_key_type_t key_type_pw = key_type_pw_arg;
     psa_key_usage_t key_usage_pw = key_usage_pw_arg;
     psa_algorithm_t hash_alg = hash_arg;
-    psa_pake_role_t role = role_arg;
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     ecjpake_error_stage_t err_stage = err_stage_arg;
@@ -557,8 +563,12 @@
     psa_status_t status;
     unsigned char *output_buffer = NULL;
     size_t output_len = 0;
-    const uint8_t unsupp_id[] = "abcd";
     const uint8_t password[] = "abcd";
+    uint8_t *user = (uint8_t *) user_arg;
+    uint8_t *peer = (uint8_t *) peer_arg;
+    size_t user_len = strlen(user_arg);
+    size_t peer_len = strlen(peer_arg);
+
     psa_key_derivation_operation_t key_derivation =
         PSA_KEY_DERIVATION_OPERATION_INIT;
 
@@ -581,19 +591,19 @@
     PSA_ASSERT(psa_pake_abort(&operation));
 
     if (err_stage == ERR_INJECT_UNINITIALIZED_ACCESS) {
-        TEST_EQUAL(psa_pake_set_user(&operation, NULL, 0),
+        TEST_EQUAL(psa_pake_set_user(&operation, user, user_len),
                    expected_error);
-        TEST_EQUAL(psa_pake_set_peer(&operation, NULL, 0),
+        TEST_EQUAL(psa_pake_set_peer(&operation, peer, peer_len),
                    expected_error);
         TEST_EQUAL(psa_pake_set_password_key(&operation, key),
                    expected_error);
-        TEST_EQUAL(psa_pake_set_role(&operation, role),
+        TEST_EQUAL(psa_pake_set_role(&operation, PSA_PAKE_ROLE_SERVER),
                    expected_error);
         TEST_EQUAL(psa_pake_output(&operation, PSA_PAKE_STEP_KEY_SHARE,
-                                   NULL, 0, NULL),
+                                   output_buffer, 0, &output_len),
                    expected_error);
         TEST_EQUAL(psa_pake_input(&operation, PSA_PAKE_STEP_KEY_SHARE,
-                                  NULL, 0),
+                                  output_buffer, 0),
                    expected_error);
         TEST_EQUAL(psa_pake_get_implicit_key(&operation, &key_derivation),
                    expected_error);
@@ -606,24 +616,27 @@
     SETUP_CONDITIONAL_CHECK_STEP(psa_pake_setup(&operation, &cipher_suite),
                                  ERR_INJECT_DUPLICATE_SETUP);
 
-    SETUP_ALWAYS_CHECK_STEP(psa_pake_set_role(&operation, role),
+    SETUP_CONDITIONAL_CHECK_STEP(psa_pake_set_role(&operation, PSA_PAKE_ROLE_SERVER),
+                                 ERR_INJECT_SET_ROLE);
+
+    SETUP_ALWAYS_CHECK_STEP(psa_pake_set_role(&operation, PSA_PAKE_ROLE_NONE),
                             ERR_IN_SET_ROLE);
 
+    SETUP_ALWAYS_CHECK_STEP(psa_pake_set_user(&operation, user, user_len),
+                            ERR_IN_SET_USER);
+
+    SETUP_ALWAYS_CHECK_STEP(psa_pake_set_peer(&operation, peer, peer_len),
+                            ERR_IN_SET_PEER);
+
+    SETUP_CONDITIONAL_CHECK_STEP(psa_pake_set_user(&operation, user, user_len),
+                                 ERR_DUPLICATE_SET_USER);
+
+    SETUP_CONDITIONAL_CHECK_STEP(psa_pake_set_peer(&operation, peer, peer_len),
+                                 ERR_DUPLICATE_SET_PEER);
+
     SETUP_ALWAYS_CHECK_STEP(psa_pake_set_password_key(&operation, key),
                             ERR_IN_SET_PASSWORD_KEY);
 
-    SETUP_CONDITIONAL_CHECK_STEP(psa_pake_set_user(&operation, NULL, 0),
-                                 ERR_INJECT_INVALID_USER);
-
-    SETUP_CONDITIONAL_CHECK_STEP(psa_pake_set_peer(&operation, NULL, 0),
-                                 ERR_INJECT_INVALID_PEER);
-
-    SETUP_CONDITIONAL_CHECK_STEP(psa_pake_set_user(&operation, unsupp_id, 4),
-                                 ERR_INJECT_SET_USER);
-
-    SETUP_CONDITIONAL_CHECK_STEP(psa_pake_set_peer(&operation, unsupp_id, 4),
-                                 ERR_INJECT_SET_PEER);
-
     const size_t size_key_share = PSA_PAKE_INPUT_SIZE(alg, primitive,
                                                       PSA_PAKE_STEP_KEY_SHARE);
     const size_t size_zk_public = PSA_PAKE_INPUT_SIZE(alg, primitive,
@@ -633,7 +646,8 @@
 
     if (test_input) {
         SETUP_CONDITIONAL_CHECK_STEP(psa_pake_input(&operation,
-                                                    PSA_PAKE_STEP_ZK_PROOF,  NULL, 0),
+                                                    PSA_PAKE_STEP_ZK_PROOF,
+                                                    output_buffer, 0),
                                      ERR_INJECT_EMPTY_IO_BUFFER);
 
         SETUP_CONDITIONAL_CHECK_STEP(psa_pake_input(&operation,
@@ -665,7 +679,8 @@
     } else {
         SETUP_CONDITIONAL_CHECK_STEP(psa_pake_output(&operation,
                                                      PSA_PAKE_STEP_ZK_PROOF,
-                                                     NULL, 0, NULL),
+                                                     output_buffer, 0,
+                                                     &output_len),
                                      ERR_INJECT_EMPTY_IO_BUFFER);
 
         SETUP_CONDITIONAL_CHECK_STEP(psa_pake_output(&operation,
@@ -728,6 +743,7 @@
     psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE);
     psa_set_key_algorithm(&attributes, alg);
     psa_set_key_type(&attributes, PSA_KEY_TYPE_PASSWORD);
+
     PSA_ASSERT(psa_import_key(&attributes, pw_data->x, pw_data->len,
                               &key));
 
@@ -738,8 +754,10 @@
     PSA_ASSERT(psa_pake_setup(&server, &cipher_suite));
     PSA_ASSERT(psa_pake_setup(&client, &cipher_suite));
 
-    PSA_ASSERT(psa_pake_set_role(&server, PSA_PAKE_ROLE_SERVER));
-    PSA_ASSERT(psa_pake_set_role(&client, PSA_PAKE_ROLE_CLIENT));
+    PSA_ASSERT(psa_pake_set_user(&server, jpake_server_id, sizeof(jpake_server_id)));
+    PSA_ASSERT(psa_pake_set_peer(&server, jpake_client_id, sizeof(jpake_client_id)));
+    PSA_ASSERT(psa_pake_set_user(&client, jpake_client_id, sizeof(jpake_client_id)));
+    PSA_ASSERT(psa_pake_set_peer(&client, jpake_server_id, sizeof(jpake_server_id)));
 
     PSA_ASSERT(psa_pake_set_password_key(&server, key));
     PSA_ASSERT(psa_pake_set_password_key(&client, key));
@@ -813,8 +831,10 @@
     PSA_ASSERT(psa_pake_setup(&server, &cipher_suite));
     PSA_ASSERT(psa_pake_setup(&client, &cipher_suite));
 
-    PSA_ASSERT(psa_pake_set_role(&server, PSA_PAKE_ROLE_SERVER));
-    PSA_ASSERT(psa_pake_set_role(&client, PSA_PAKE_ROLE_CLIENT));
+    PSA_ASSERT(psa_pake_set_user(&server, jpake_server_id, sizeof(jpake_server_id)));
+    PSA_ASSERT(psa_pake_set_peer(&server, jpake_client_id, sizeof(jpake_client_id)));
+    PSA_ASSERT(psa_pake_set_user(&client, jpake_client_id, sizeof(jpake_client_id)));
+    PSA_ASSERT(psa_pake_set_peer(&client, jpake_server_id, sizeof(jpake_server_id)));
 
     PSA_ASSERT(psa_pake_set_password_key(&server, key));
     PSA_ASSERT(psa_pake_set_password_key(&client, key));
@@ -905,3 +925,253 @@
               PSA_PAKE_INPUT_MAX_SIZE);
 }
 /* END_CASE */
+
+/* BEGIN_CASE depends_on:PSA_WANT_ALG_JPAKE */
+void pake_input_getters_password()
+{
+    psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
+    psa_pake_operation_t operation = psa_pake_operation_init();
+    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    const char *password = "password";
+    uint8_t password_ret[20] = { 0 }; // max key length is 20 bytes
+    size_t password_len_ret = 0;
+    size_t buffer_len_ret = 0;
+
+    psa_pake_primitive_t primitive = PSA_PAKE_PRIMITIVE(
+        PSA_PAKE_PRIMITIVE_TYPE_ECC,
+        PSA_ECC_FAMILY_SECP_R1, 256);
+
+    PSA_INIT();
+
+    psa_pake_cs_set_algorithm(&cipher_suite, PSA_ALG_JPAKE);
+    psa_pake_cs_set_primitive(&cipher_suite, primitive);
+    psa_pake_cs_set_hash(&cipher_suite, PSA_ALG_SHA_256);
+
+    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE);
+    psa_set_key_algorithm(&attributes, PSA_ALG_JPAKE);
+    psa_set_key_type(&attributes, PSA_KEY_TYPE_PASSWORD);
+
+    PSA_ASSERT(psa_pake_setup(&operation, &cipher_suite));
+
+    PSA_ASSERT(psa_import_key(&attributes, (uint8_t *) password, strlen(password), &key));
+
+    TEST_EQUAL(psa_crypto_driver_pake_get_password(&operation.data.inputs,
+                                                   (uint8_t *) &password_ret,
+                                                   10, &buffer_len_ret),
+               PSA_ERROR_BAD_STATE);
+
+    TEST_EQUAL(psa_crypto_driver_pake_get_password_len(&operation.data.inputs, &password_len_ret),
+               PSA_ERROR_BAD_STATE);
+
+    PSA_ASSERT(psa_pake_set_password_key(&operation, key));
+
+    TEST_EQUAL(psa_crypto_driver_pake_get_password_len(&operation.data.inputs, &password_len_ret),
+               PSA_SUCCESS);
+
+    TEST_EQUAL(password_len_ret, strlen(password));
+
+    TEST_EQUAL(psa_crypto_driver_pake_get_password(&operation.data.inputs,
+                                                   (uint8_t *) &password_ret,
+                                                   password_len_ret - 1,
+                                                   &buffer_len_ret),
+               PSA_ERROR_BUFFER_TOO_SMALL);
+
+    TEST_EQUAL(psa_crypto_driver_pake_get_password(&operation.data.inputs,
+                                                   (uint8_t *) &password_ret,
+                                                   password_len_ret,
+                                                   &buffer_len_ret),
+               PSA_SUCCESS);
+
+    TEST_EQUAL(buffer_len_ret, strlen(password));
+    PSA_ASSERT(memcmp(password_ret, password, buffer_len_ret));
+exit:
+    PSA_ASSERT(psa_destroy_key(key));
+    PSA_ASSERT(psa_pake_abort(&operation));
+    PSA_DONE();
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:PSA_WANT_ALG_JPAKE */
+void pake_input_getters_cipher_suite()
+{
+    psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
+    psa_pake_operation_t operation = psa_pake_operation_init();
+    psa_pake_cipher_suite_t cipher_suite_ret = psa_pake_cipher_suite_init();
+
+    psa_pake_primitive_t primitive = PSA_PAKE_PRIMITIVE(
+        PSA_PAKE_PRIMITIVE_TYPE_ECC,
+        PSA_ECC_FAMILY_SECP_R1, 256);
+
+    PSA_INIT();
+
+    psa_pake_cs_set_algorithm(&cipher_suite, PSA_ALG_JPAKE);
+    psa_pake_cs_set_primitive(&cipher_suite, primitive);
+    psa_pake_cs_set_hash(&cipher_suite, PSA_ALG_SHA_256);
+
+    TEST_EQUAL(psa_crypto_driver_pake_get_cipher_suite(&operation.data.inputs, &cipher_suite_ret),
+               PSA_ERROR_BAD_STATE);
+
+    PSA_ASSERT(psa_pake_setup(&operation, &cipher_suite));
+
+    TEST_EQUAL(psa_crypto_driver_pake_get_cipher_suite(&operation.data.inputs, &cipher_suite_ret),
+               PSA_SUCCESS);
+
+    PSA_ASSERT(memcmp(&cipher_suite_ret, &cipher_suite, sizeof(cipher_suite)));
+
+exit:
+    PSA_ASSERT(psa_pake_abort(&operation));
+    PSA_DONE();
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:PSA_WANT_ALG_JPAKE */
+void pake_input_getters_role()
+{
+    psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
+    psa_pake_operation_t operation = psa_pake_operation_init();
+    psa_pake_role_t role_ret = PSA_PAKE_ROLE_NONE;
+
+    psa_pake_primitive_t primitive = PSA_PAKE_PRIMITIVE(
+        PSA_PAKE_PRIMITIVE_TYPE_ECC,
+        PSA_ECC_FAMILY_SECP_R1, 256);
+
+    PSA_INIT();
+
+    psa_pake_cs_set_algorithm(&cipher_suite, PSA_ALG_JPAKE);
+    psa_pake_cs_set_primitive(&cipher_suite, primitive);
+    psa_pake_cs_set_hash(&cipher_suite, PSA_ALG_SHA_256);
+
+    PSA_ASSERT(psa_pake_setup(&operation, &cipher_suite));
+
+    TEST_EQUAL(psa_crypto_driver_pake_get_role(&operation.data.inputs, &role_ret),
+               PSA_ERROR_BAD_STATE);
+
+    /* Role can not be set directly using psa_pake_set_role(). It is set by the core
+       based on given user/peer identifiers. Simulate that Role is already set. */
+    operation.data.inputs.role = PSA_PAKE_ROLE_SERVER;
+    TEST_EQUAL(psa_crypto_driver_pake_get_role(&operation.data.inputs, &role_ret),
+               PSA_SUCCESS);
+
+    TEST_EQUAL(role_ret, PSA_PAKE_ROLE_SERVER);
+exit:
+    PSA_ASSERT(psa_pake_abort(&operation));
+    PSA_DONE();
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:PSA_WANT_ALG_JPAKE */
+void pake_input_getters_user()
+{
+    psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
+    psa_pake_operation_t operation = psa_pake_operation_init();
+    const uint8_t user[] = { 's', 'e', 'r', 'v', 'e', 'r' };
+    const size_t user_len = sizeof(user);
+    uint8_t user_ret[20] = { 0 }; // max user length is 20 bytes
+    size_t user_len_ret = 0;
+    size_t buffer_len_ret = 0;
+
+    psa_pake_primitive_t primitive = PSA_PAKE_PRIMITIVE(
+        PSA_PAKE_PRIMITIVE_TYPE_ECC,
+        PSA_ECC_FAMILY_SECP_R1, 256);
+
+    PSA_INIT();
+
+    psa_pake_cs_set_algorithm(&cipher_suite, PSA_ALG_JPAKE);
+    psa_pake_cs_set_primitive(&cipher_suite, primitive);
+    psa_pake_cs_set_hash(&cipher_suite, PSA_ALG_SHA_256);
+
+    PSA_ASSERT(psa_pake_setup(&operation, &cipher_suite));
+
+    TEST_EQUAL(psa_crypto_driver_pake_get_user(&operation.data.inputs,
+                                               (uint8_t *) &user_ret,
+                                               10, &buffer_len_ret),
+               PSA_ERROR_BAD_STATE);
+
+    TEST_EQUAL(psa_crypto_driver_pake_get_user_len(&operation.data.inputs, &user_len_ret),
+               PSA_ERROR_BAD_STATE);
+
+    PSA_ASSERT(psa_pake_set_user(&operation, user, user_len));
+
+    TEST_EQUAL(psa_crypto_driver_pake_get_user_len(&operation.data.inputs, &user_len_ret),
+               PSA_SUCCESS);
+
+    TEST_EQUAL(user_len_ret, user_len);
+
+    TEST_EQUAL(psa_crypto_driver_pake_get_user(&operation.data.inputs,
+                                               (uint8_t *) &user_ret,
+                                               user_len_ret - 1,
+                                               &buffer_len_ret),
+               PSA_ERROR_BUFFER_TOO_SMALL);
+
+    TEST_EQUAL(psa_crypto_driver_pake_get_user(&operation.data.inputs,
+                                               (uint8_t *) &user_ret,
+                                               user_len_ret,
+                                               &buffer_len_ret),
+               PSA_SUCCESS);
+
+    TEST_EQUAL(buffer_len_ret, user_len);
+    PSA_ASSERT(memcmp(user_ret, user, buffer_len_ret));
+exit:
+    PSA_ASSERT(psa_pake_abort(&operation));
+    PSA_DONE();
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:PSA_WANT_ALG_JPAKE */
+void pake_input_getters_peer()
+{
+    psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
+    psa_pake_operation_t operation = psa_pake_operation_init();
+    const uint8_t peer[] = { 's', 'e', 'r', 'v', 'e', 'r' };
+    const size_t peer_len = sizeof(peer);
+    uint8_t peer_ret[20] = { 0 }; // max peer length is 20 bytes
+    size_t peer_len_ret = 0;
+    size_t buffer_len_ret = 0;
+
+    psa_pake_primitive_t primitive = PSA_PAKE_PRIMITIVE(
+        PSA_PAKE_PRIMITIVE_TYPE_ECC,
+        PSA_ECC_FAMILY_SECP_R1, 256);
+
+    PSA_INIT();
+
+    psa_pake_cs_set_algorithm(&cipher_suite, PSA_ALG_JPAKE);
+    psa_pake_cs_set_primitive(&cipher_suite, primitive);
+    psa_pake_cs_set_hash(&cipher_suite, PSA_ALG_SHA_256);
+
+    PSA_ASSERT(psa_pake_setup(&operation, &cipher_suite));
+
+    TEST_EQUAL(psa_crypto_driver_pake_get_peer(&operation.data.inputs,
+                                               (uint8_t *) &peer_ret,
+                                               10, &buffer_len_ret),
+               PSA_ERROR_BAD_STATE);
+
+    TEST_EQUAL(psa_crypto_driver_pake_get_peer_len(&operation.data.inputs, &peer_len_ret),
+               PSA_ERROR_BAD_STATE);
+
+    PSA_ASSERT(psa_pake_set_peer(&operation, peer, peer_len));
+
+    TEST_EQUAL(psa_crypto_driver_pake_get_peer_len(&operation.data.inputs, &peer_len_ret),
+               PSA_SUCCESS);
+
+    TEST_EQUAL(peer_len_ret, peer_len);
+
+    TEST_EQUAL(psa_crypto_driver_pake_get_peer(&operation.data.inputs,
+                                               (uint8_t *) &peer_ret,
+                                               peer_len_ret - 1,
+                                               &buffer_len_ret),
+               PSA_ERROR_BUFFER_TOO_SMALL);
+
+    TEST_EQUAL(psa_crypto_driver_pake_get_peer(&operation.data.inputs,
+                                               (uint8_t *) &peer_ret,
+                                               peer_len_ret,
+                                               &buffer_len_ret),
+               PSA_SUCCESS);
+
+    TEST_EQUAL(buffer_len_ret, peer_len);
+    PSA_ASSERT(memcmp(peer_ret, peer, buffer_len_ret));
+exit:
+    PSA_ASSERT(psa_pake_abort(&operation));
+    PSA_DONE();
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data
index 928a7ce..c47f292 100644
--- a/tests/suites/test_suite_ssl.data
+++ b/tests/suites/test_suite_ssl.data
@@ -280,11 +280,11 @@
 handshake_cipher:"TLS-DHE-RSA-WITH-AES-256-CBC-SHA256":MBEDTLS_PK_RSA:0
 
 Handshake, ECDHE-ECDSA-WITH-AES-256-CCM
-depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 handshake_cipher:"TLS-ECDHE-ECDSA-WITH-AES-256-CCM":MBEDTLS_PK_ECDSA:0
 
 Handshake, ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384
-depends_on:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_CAMELLIA_C:MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+depends_on:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_CAMELLIA_C:MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
 handshake_cipher:"TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384":MBEDTLS_PK_ECDSA:0
 
 Handshake, PSK-WITH-AES-128-CBC-SHA
@@ -308,11 +308,11 @@
 handshake_cipher:"TLS-DHE-RSA-WITH-AES-256-CBC-SHA256":MBEDTLS_PK_RSA:1
 
 DTLS Handshake, ECDHE-ECDSA-WITH-AES-256-CCM
-depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 handshake_cipher:"TLS-ECDHE-ECDSA-WITH-AES-256-CCM":MBEDTLS_PK_ECDSA:1
 
 DTLS Handshake, ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384
-depends_on:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_CAMELLIA_C:MBEDTLS_SSL_PROTO_DTLS:MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+depends_on:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_CAMELLIA_C:MBEDTLS_SSL_PROTO_DTLS:MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
 handshake_cipher:"TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384":MBEDTLS_PK_ECDSA:1
 
 DTLS Handshake, PSK-WITH-AES-128-CBC-SHA
@@ -420,23 +420,23 @@
 handshake_ciphersuite_select:"TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384":MBEDTLS_PK_RSA:"":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_ALG_NONE:PSA_KEY_USAGE_DERIVE:MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE:0
 
 Handshake, select ECDHE-ECDSA-WITH-AES-256-CCM, non-opaque
-depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_AES_C:MBEDTLS_CCM_C:MBEDTLS_ECDSA_C:MBEDTLS_ECDH_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_AES_C:MBEDTLS_CCM_C:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECDH_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 handshake_ciphersuite_select:"TLS-ECDHE-ECDSA-WITH-AES-256-CCM":MBEDTLS_PK_ECDSA:"":PSA_ALG_NONE:PSA_ALG_NONE:0:0:MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM
 
 Handshake, select ECDHE-ECDSA-WITH-AES-256-CCM, opaque, PSA_ALG_ANY_HASH
-depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_AES_C:MBEDTLS_CCM_C:MBEDTLS_ECDSA_C:MBEDTLS_ECDH_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED:MBEDTLS_USE_PSA_CRYPTO
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_AES_C:MBEDTLS_CCM_C:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECDH_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED:MBEDTLS_USE_PSA_CRYPTO
 handshake_ciphersuite_select:"TLS-ECDHE-ECDSA-WITH-AES-256-CCM":MBEDTLS_PK_ECDSA:"":PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_ALG_NONE:PSA_KEY_USAGE_SIGN_HASH:0:MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM
 
 Handshake, select ECDHE-ECDSA-WITH-AES-256-CCM, opaque, PSA_ALG_SHA_256
-depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_AES_C:MBEDTLS_CCM_C:MBEDTLS_ECDSA_C:MBEDTLS_ECDH_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED:MBEDTLS_USE_PSA_CRYPTO
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_AES_C:MBEDTLS_CCM_C:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECDH_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED:MBEDTLS_USE_PSA_CRYPTO
 handshake_ciphersuite_select:"TLS-ECDHE-ECDSA-WITH-AES-256-CCM":MBEDTLS_PK_ECDSA:"":PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_ALG_NONE:PSA_KEY_USAGE_SIGN_HASH:0:MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM
 
 Handshake, select ECDHE-ECDSA-WITH-AES-256-CCM, opaque, bad alg
-depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_AES_C:MBEDTLS_CCM_C:MBEDTLS_ECDSA_C:MBEDTLS_ECDH_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED:MBEDTLS_USE_PSA_CRYPTO
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_AES_C:MBEDTLS_CCM_C:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECDH_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED:MBEDTLS_USE_PSA_CRYPTO
 handshake_ciphersuite_select:"TLS-ECDHE-ECDSA-WITH-AES-256-CCM":MBEDTLS_PK_ECDSA:"":PSA_ALG_ECDH:PSA_ALG_NONE:PSA_KEY_USAGE_SIGN_HASH:MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE:0
 
 Handshake, select ECDHE-ECDSA-WITH-AES-256-CCM, opaque, bad usage
-depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_AES_C:MBEDTLS_CCM_C:MBEDTLS_ECDSA_C:MBEDTLS_ECDH_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED:MBEDTLS_USE_PSA_CRYPTO
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_AES_C:MBEDTLS_CCM_C:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECDH_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED:MBEDTLS_USE_PSA_CRYPTO
 handshake_ciphersuite_select:"TLS-ECDHE-ECDSA-WITH-AES-256-CCM":MBEDTLS_PK_ECDSA:"":PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_ALG_NONE:PSA_KEY_USAGE_DERIVE:MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE:0
 
 Handshake, select ECDH-RSA-WITH-AES-256-CBC-SHA384, non-opaque
@@ -456,23 +456,23 @@
 handshake_ciphersuite_select:"TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384":MBEDTLS_PK_ECDSA:"":PSA_ALG_ECDH:PSA_ALG_NONE:PSA_KEY_USAGE_DECRYPT:MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE:0
 
 Handshake, select ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384, non-opaque
-depends_on:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_ECDSA_C:MBEDTLS_ECDH_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_CAMELLIA_C:MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+depends_on:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECDH_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_CAMELLIA_C:MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
 handshake_ciphersuite_select:"TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384":MBEDTLS_PK_ECDSA:"":PSA_ALG_NONE:PSA_ALG_NONE:0:0:MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
 
 Handshake, select ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384, opaque, PSA_ALG_ANY_HASH
-depends_on:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_ECDSA_C:MBEDTLS_ECDH_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_CAMELLIA_C:MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED:MBEDTLS_USE_PSA_CRYPTO
+depends_on:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECDH_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_CAMELLIA_C:MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED:MBEDTLS_USE_PSA_CRYPTO
 handshake_ciphersuite_select:"TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384":MBEDTLS_PK_ECDSA:"":PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_ALG_ECDH:PSA_KEY_USAGE_SIGN_HASH|PSA_KEY_USAGE_DERIVE:0:MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
 
 Handshake, select ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384, opaque, PSA_ALG_SHA_384
-depends_on:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_ECDSA_C:MBEDTLS_ECDH_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_CAMELLIA_C:MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED:MBEDTLS_USE_PSA_CRYPTO
+depends_on:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECDH_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_CAMELLIA_C:MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED:MBEDTLS_USE_PSA_CRYPTO
 handshake_ciphersuite_select:"TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384":MBEDTLS_PK_ECDSA:"":PSA_ALG_ECDSA(PSA_ALG_SHA_384):PSA_ALG_ECDH:PSA_KEY_USAGE_SIGN_HASH|PSA_KEY_USAGE_DERIVE:0:MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
 
 Handshake, select ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384, opaque, missing alg
-depends_on:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_ECDSA_C:MBEDTLS_ECDH_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_CAMELLIA_C:MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED:MBEDTLS_USE_PSA_CRYPTO
+depends_on:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECDH_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_CAMELLIA_C:MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED:MBEDTLS_USE_PSA_CRYPTO
 handshake_ciphersuite_select:"TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384":MBEDTLS_PK_ECDSA:"":PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_ALG_NONE:PSA_KEY_USAGE_SIGN_HASH|PSA_KEY_USAGE_DERIVE:MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE:0
 
 Handshake, select ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384, opaque, missing usage
-depends_on:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_ECDSA_C:MBEDTLS_ECDH_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_CAMELLIA_C:MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED:MBEDTLS_USE_PSA_CRYPTO
+depends_on:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECDH_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_CAMELLIA_C:MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED:MBEDTLS_USE_PSA_CRYPTO
 handshake_ciphersuite_select:"TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384":MBEDTLS_PK_ECDSA:"":PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_ALG_ECDH:PSA_KEY_USAGE_SIGN_HASH:MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE:0
 
 Sending app data via TLS, MFL=512 without fragmentation
@@ -3133,7 +3133,7 @@
 # - App data payload: 70696e67
 # - Complete record:  1703030015c74061535eb12f5f25a781957874742ab7fb305dd5
 # - Padding used: No (== granularity 1)
-depends_on:MBEDTLS_AES_C:MBEDTLS_ECDSA_C:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+depends_on:MBEDTLS_AES_C:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 ssl_tls13_record_protection:MBEDTLS_TLS1_3_AES_128_GCM_SHA256:MBEDTLS_SSL_IS_CLIENT:0:1:"0b6d22c8ff68097ea871c672073773bf":"1b13dd9f8d8f17091d34b349":"49134b95328f279f0183860589ac6707":"bc4dd5f7b98acff85466261d":"70696e67":"c74061535eb12f5f25a781957874742ab7fb305dd5"
 
 SSL TLS 1.3 Record Encryption, tls13.ulfheim.net Example #2
@@ -3144,7 +3144,7 @@
 # - App data payload: 706f6e67
 # - Complete record:  1703030015370e5f168afa7fb16b663ecdfca3dbb81931a90ca7
 # - Padding used: No (== granularity 1)
-depends_on:MBEDTLS_AES_C:MBEDTLS_ECDSA_C:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+depends_on:MBEDTLS_AES_C:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 ssl_tls13_record_protection:MBEDTLS_TLS1_3_AES_128_GCM_SHA256:MBEDTLS_SSL_IS_SERVER:1:1:"0b6d22c8ff68097ea871c672073773bf":"1b13dd9f8d8f17091d34b349":"49134b95328f279f0183860589ac6707":"bc4dd5f7b98acff85466261d":"706f6e67":"370e5f168afa7fb16b663ecdfca3dbb81931a90ca7"
 
 SSL TLS 1.3 Record Encryption RFC 8448 Example #1
@@ -3163,7 +3163,7 @@
 #                     62 97 4e 1f 5a 62 92 a2 97 70 14 bd 1e 3d ea e6
 #                     3a ee bb 21 69 49 15 e4
 # - Padding used: No (== granularity 1)
-depends_on:MBEDTLS_AES_C:MBEDTLS_ECDSA_C:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+depends_on:MBEDTLS_AES_C:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 ssl_tls13_record_protection:MBEDTLS_TLS1_3_AES_128_GCM_SHA256:MBEDTLS_SSL_IS_CLIENT:0:1:"9f02283b6c9c07efc26bb9f2ac92e356":"cf782b88dd83549aadf1e984":"17422dda596ed5d9acd890e3c63f5051":"5b78923dee08579033e523d9":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031":"a23f7054b62c94d0affafe8228ba55cbefacea42f914aa66bcab3f2b9819a8a5b46b395bd54a9a20441e2b62974e1f5a6292a2977014bd1e3deae63aeebb21694915e4"
 
 SSL TLS 1.3 Record Encryption RFC 8448 Example #2
@@ -3182,12 +3182,12 @@
 #                     fc c4 9c 4b f2 e5 f0 a2 1c 00 47 c2 ab f3 32 54
 #                     0d d0 32 e1 67 c2 95 5d
 # - Padding used: No (== granularity 1)
-depends_on:MBEDTLS_AES_C:MBEDTLS_ECDSA_C:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+depends_on:MBEDTLS_AES_C:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 ssl_tls13_record_protection:MBEDTLS_TLS1_3_AES_128_GCM_SHA256:MBEDTLS_SSL_IS_SERVER:1:1:"9f02283b6c9c07efc26bb9f2ac92e356":"cf782b88dd83549aadf1e984":"17422dda596ed5d9acd890e3c63f5051":"5b78923dee08579033e523d9":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031":"2e937e11ef4ac740e538ad36005fc4a46932fc3225d05f82aa1b36e30efaf97d90e6dffc602dcb501a59a8fcc49c4bf2e5f0a21c0047c2abf332540dd032e167c2955d"
 
 SSL TLS 1.3 Key schedule: Application secrets derivation helper
 # Vector from RFC 8448
-depends_on:MBEDTLS_AES_C:MBEDTLS_ECDSA_C:PSA_WANT_ALG_SHA_256:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+depends_on:MBEDTLS_AES_C:MBEDTLS_PK_CAN_ECDSA_SOME:PSA_WANT_ALG_SHA_256:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 ssl_tls13_derive_application_secrets:PSA_ALG_SHA_256:"e2d32d4ed66dd37897a0e80c84107503ce58bf8aad4cb55a5002d77ecb890ece":"b0aeffc46a2cfe33114e6fd7d51f9f04b1ca3c497dab08934a774a9d9ad7dbf3":"2abbf2b8e381d23dbebe1dd2a7d16a8bf484cb4950d23fb7fb7fa8547062d9a1":"cc21f1bf8feb7dd5fa505bd9c4b468a9984d554a993dc49e6d285598fb672691":"3fd93d4ffddc98e64b14dd107aedf8ee4add23f4510f58a4592d0b201bee56b4"
 
 SSL TLS 1.3 Key schedule: Resumption secrets derivation helper
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index 9e37259..9dfb7ed 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -1165,6 +1165,12 @@
                                int buf_len, int *written,
                                const int expected_fragments)
 {
+    /* Verify that calling mbedtls_ssl_write with a NULL buffer and zero length is
+     * a valid no-op for TLS connections. */
+    if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
+        TEST_ASSERT(mbedtls_ssl_write(ssl, NULL, 0) == 0);
+    }
+
     int ret = mbedtls_ssl_write(ssl, buf + *written, buf_len - *written);
     if (ret > 0) {
         *written += ret;
@@ -1203,6 +1209,12 @@
                               int buf_len, int *read,
                               int *fragments, const int expected_fragments)
 {
+    /* Verify that calling mbedtls_ssl_write with a NULL buffer and zero length is
+     * a valid no-op for TLS connections. */
+    if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
+        TEST_ASSERT(mbedtls_ssl_read(ssl, NULL, 0) == 0);
+    }
+
     int ret = mbedtls_ssl_read(ssl, buf + *read, buf_len - *read);
     if (ret > 0) {
         (*fragments)++;
@@ -5685,7 +5697,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ECDSA_C */
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_PK_CAN_ECDSA_SOME */
 void raw_key_agreement_fail(int bad_server_ecdhe_key)
 {
     enum { BUFFSIZE = 17000 };