Added framework as a flattened directory

Signed-off-by: Minos Galanakis <minos.galanakis@arm.com>
diff --git a/framework/tests/include/test/arguments.h b/framework/tests/include/test/arguments.h
new file mode 100644
index 0000000..6d267b6
--- /dev/null
+++ b/framework/tests/include/test/arguments.h
@@ -0,0 +1,26 @@
+/**
+ * \file arguments.h
+ *
+ * \brief Manipulation of test arguments.
+ *
+ * Much of the code is in host_test.function, to be migrated here later.
+ */
+
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef TEST_ARGUMENTS_H
+#define TEST_ARGUMENTS_H
+
+#include "mbedtls/build_info.h"
+#include <stdint.h>
+#include <stdlib.h>
+
+typedef union {
+    size_t len;
+    intmax_t sint;
+} mbedtls_test_argument_t;
+
+#endif /* TEST_ARGUMENTS_H */
diff --git a/framework/tests/include/test/asn1_helpers.h b/framework/tests/include/test/asn1_helpers.h
new file mode 100644
index 0000000..2eb9171
--- /dev/null
+++ b/framework/tests/include/test/asn1_helpers.h
@@ -0,0 +1,38 @@
+/** Helper functions for tests that manipulate ASN.1 data.
+ */
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef ASN1_HELPERS_H
+#define ASN1_HELPERS_H
+
+#include "test/helpers.h"
+
+/** Skip past an INTEGER in an ASN.1 buffer.
+ *
+ * Mark the current test case as failed in any of the following conditions:
+ * - The buffer does not start with an ASN.1 INTEGER.
+ * - The integer's size or parity does not match the constraints expressed
+ *   through \p min_bits, \p max_bits and \p must_be_odd.
+ *
+ * \param p             Upon entry, `*p` points to the first byte of the
+ *                      buffer to parse.
+ *                      On successful return, `*p` points to the first byte
+ *                      after the parsed INTEGER.
+ *                      On failure, `*p` is unspecified.
+ * \param end           The end of the ASN.1 buffer.
+ * \param min_bits      Fail the test case if the integer does not have at
+ *                      least this many significant bits.
+ * \param max_bits      Fail the test case if the integer has more than
+ *                      this many significant bits.
+ * \param must_be_odd   Fail the test case if the integer is even.
+ *
+ * \return              \c 0 if the test failed, otherwise 1.
+ */
+int mbedtls_test_asn1_skip_integer(unsigned char **p, const unsigned char *end,
+                                   size_t min_bits, size_t max_bits,
+                                   int must_be_odd);
+
+#endif /* ASN1_HELPERS_H */
diff --git a/framework/tests/include/test/bignum_codepath_check.h b/framework/tests/include/test/bignum_codepath_check.h
new file mode 100644
index 0000000..3d72be1
--- /dev/null
+++ b/framework/tests/include/test/bignum_codepath_check.h
@@ -0,0 +1,94 @@
+/** Support for path tracking in optionally safe bignum functions
+ *
+ * The functions are called when an optionally safe path is taken and logs it with a single
+ * variable. This variable is at any time in one of three states:
+ *      - MBEDTLS_MPI_IS_TEST: No optionally safe path has been taken since the last reset
+ *      - MBEDTLS_MPI_IS_SECRET: Only safe paths were teken since the last reset
+ *      - MBEDTLS_MPI_IS_PUBLIC: At least one unsafe path has been taken since the last reset
+ *
+ * Use a simple global variable to track execution path. Making it work with multithreading
+ * isn't worth the effort as multithreaded tests add little to no value here.
+ */
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef BIGNUM_CODEPATH_CHECK_H
+#define BIGNUM_CODEPATH_CHECK_H
+
+#include "bignum_core.h"
+
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+
+extern int mbedtls_codepath_check;
+
+/**
+ * \brief         Setup the codepath test hooks used by optionally safe bignum functions to signal
+ *                the path taken.
+ */
+void mbedtls_codepath_test_hooks_setup(void);
+
+/**
+ * \brief         Teardown the codepath test hooks used by optionally safe bignum functions to
+ *                signal the path taken.
+ */
+void mbedtls_codepath_test_hooks_teardown(void);
+
+/**
+ * \brief         Reset the state of the codepath to the initial state.
+ */
+static inline void mbedtls_codepath_reset(void)
+{
+    mbedtls_codepath_check = MBEDTLS_MPI_IS_TEST;
+}
+
+/** Check the codepath taken and fail if it doesn't match.
+ *
+ * When a function returns with an error, it can do so before reaching any interesting codepath. The
+ * same can happen if a parameter to the function is zero. In these cases we need to allow
+ * the codepath tracking variable to still have its initial "not set" value.
+ *
+ * This macro expands to an instruction, not an expression.
+ * It may jump to the \c exit label.
+ *
+ * \param path      The expected codepath.
+ *                  This expression may be evaluated multiple times.
+ * \param ret       The expected return value.
+ * \param E         The MPI parameter that can cause shortcuts.
+ */
+#define ASSERT_BIGNUM_CODEPATH(path, ret, E)                            \
+    do {                                                                \
+        if ((ret) != 0 || (E).n == 0) {                                 \
+            TEST_ASSERT(mbedtls_codepath_check == (path) ||             \
+                        mbedtls_codepath_check == MBEDTLS_MPI_IS_TEST); \
+        } else {                                                        \
+            TEST_EQUAL(mbedtls_codepath_check, (path));                 \
+        }                                                               \
+    } while (0)
+
+/** Check the codepath taken and fail if it doesn't match.
+ *
+ * When a function returns with an error, it can do so before reaching any interesting codepath. In
+ * this case we need to allow the codepath tracking variable to still have its
+ * initial "not set" value.
+ *
+ * This macro expands to an instruction, not an expression.
+ * It may jump to the \c exit label.
+ *
+ * \param path      The expected codepath.
+ *                  This expression may be evaluated multiple times.
+ * \param ret       The expected return value.
+ */
+#define ASSERT_RSA_CODEPATH(path, ret)                                  \
+    do {                                                                \
+        if ((ret) != 0) {                                               \
+            TEST_ASSERT(mbedtls_codepath_check == (path) ||             \
+                        mbedtls_codepath_check == MBEDTLS_MPI_IS_TEST); \
+        } else {                                                        \
+            TEST_EQUAL(mbedtls_codepath_check, (path));                 \
+        }                                                               \
+    } while (0)
+#endif /* MBEDTLS_TEST_HOOKS && !MBEDTLS_THREADING_C */
+
+#endif /* BIGNUM_CODEPATH_CHECK_H */
diff --git a/framework/tests/include/test/bignum_helpers.h b/framework/tests/include/test/bignum_helpers.h
new file mode 100644
index 0000000..a5e49cb
--- /dev/null
+++ b/framework/tests/include/test/bignum_helpers.h
@@ -0,0 +1,98 @@
+/**
+ * \file bignum_helpers.h
+ *
+ * \brief   This file contains the prototypes of helper functions for
+ *          bignum-related testing.
+ */
+
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef TEST_BIGNUM_HELPERS_H
+#define TEST_BIGNUM_HELPERS_H
+
+#include <mbedtls/build_info.h>
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+#include <mbedtls/bignum.h>
+#include <bignum_mod.h>
+
+/** Allocate and populate a core MPI from a test case argument.
+ *
+ * This function allocates exactly as many limbs as necessary to fit
+ * the length of the input. In other words, it preserves leading zeros.
+ *
+ * The limb array is allocated with mbedtls_calloc() and must later be
+ * freed with mbedtls_free().
+ *
+ * \param[in,out] pX    The address where a pointer to the allocated limb
+ *                      array will be stored.
+ *                      \c *pX must be null on entry.
+ *                      On exit, \c *pX is null on error or if the number
+ *                      of limbs is 0.
+ * \param[out] plimbs   The address where the number of limbs will be stored.
+ * \param[in] input     The test argument to read.
+ *                      It is interpreted as a hexadecimal representation
+ *                      of a non-negative integer.
+ *
+ * \return \c 0 on success, an \c MBEDTLS_ERR_MPI_xxx error code otherwise.
+ */
+int mbedtls_test_read_mpi_core(mbedtls_mpi_uint **pX, size_t *plimbs,
+                               const char *input);
+
+/** Read a modulus from a hexadecimal string.
+ *
+ * This function allocates exactly as many limbs as necessary to fit
+ * the length of the input. In other words, it preserves leading zeros.
+ *
+ * The limb array is allocated with mbedtls_calloc() and must later be
+ * freed with mbedtls_free(). You can do that by calling
+ * mbedtls_test_mpi_mod_modulus_free_with_limbs().
+ *
+ * \param[in,out] N     A modulus structure. It must be initialized, but
+ *                      not set up.
+ * \param[in] s         The null-terminated hexadecimal string to read from.
+ * \param int_rep       The desired representation of residues.
+ *
+ * \return \c 0 on success, an \c MBEDTLS_ERR_MPI_xxx error code otherwise.
+ */
+int mbedtls_test_read_mpi_modulus(mbedtls_mpi_mod_modulus *N,
+                                  const char *s,
+                                  mbedtls_mpi_mod_rep_selector int_rep);
+
+/** Free a modulus and its limbs.
+ *
+ * \param[in] N         A modulus structure such that there is no other
+ *                      reference to `N->p`.
+ */
+void mbedtls_test_mpi_mod_modulus_free_with_limbs(mbedtls_mpi_mod_modulus *N);
+
+/** Read an MPI from a hexadecimal string.
+ *
+ * Like mbedtls_mpi_read_string(), but with tighter guarantees around
+ * edge cases.
+ *
+ * - This function guarantees that if \p s begins with '-' then the sign
+ *   bit of the result will be negative, even if the value is 0.
+ *   When this function encounters such a "negative 0", it calls
+ *   mbedtls_test_increment_case_uses_negative_0().
+ * - The size of the result is exactly the minimum number of limbs needed to fit
+ *   the digits in the input. In particular, this function constructs a bignum
+ *   with 0 limbs for an empty string, and a bignum with leading 0 limbs if the
+ *   string has sufficiently many leading 0 digits. This is important so that
+ *   the "0 (null)" and "0 (1 limb)" and "leading zeros" test cases do what they
+ *   claim.
+ *
+ * \param[out] X        The MPI object to populate. It must be initialized.
+ * \param[in] s         The null-terminated hexadecimal string to read from.
+ *
+ * \return \c 0 on success, an \c MBEDTLS_ERR_MPI_xxx error code otherwise.
+ */
+int mbedtls_test_read_mpi(mbedtls_mpi *X, const char *s);
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#endif /* TEST_BIGNUM_HELPERS_H */
diff --git a/framework/tests/include/test/constant_flow.h b/framework/tests/include/test/constant_flow.h
new file mode 100644
index 0000000..c5658eb
--- /dev/null
+++ b/framework/tests/include/test/constant_flow.h
@@ -0,0 +1,71 @@
+/**
+ * \file constant_flow.h
+ *
+ * \brief   This file contains tools to ensure tested code has constant flow.
+ */
+
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef TEST_CONSTANT_FLOW_H
+#define TEST_CONSTANT_FLOW_H
+
+#include "mbedtls/build_info.h"
+
+/*
+ * This file defines the two macros
+ *
+ *  #define TEST_CF_SECRET(ptr, size)
+ *  #define TEST_CF_PUBLIC(ptr, size)
+ *
+ * that can be used in tests to mark a memory area as secret (no branch or
+ * memory access should depend on it) or public (default, only needs to be
+ * marked explicitly when it was derived from secret data).
+ *
+ * Arguments:
+ * - ptr: a pointer to the memory area to be marked
+ * - size: the size in bytes of the memory area
+ *
+ * Implementation:
+ * The basic idea is that of ctgrind <https://github.com/agl/ctgrind>: we can
+ * re-use tools that were designed for checking use of uninitialized memory.
+ * This file contains two implementations: one based on MemorySanitizer, the
+ * other on valgrind's memcheck. If none of them is enabled, dummy macros that
+ * do nothing are defined for convenience.
+ *
+ * \note #TEST_CF_SECRET must be called directly from within a .function file,
+ *       not indirectly via a macro defined under tests/include or a function
+ *       under tests/src. This is because we only run Valgrind for constant
+ *       flow on test suites that have greppable annotations inside them (see
+ *       `skip_suites_without_constant_flow` in `tests/scripts/all.sh`).
+ */
+
+#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN)
+#include <sanitizer/msan_interface.h>
+
+/* Use macros to avoid messing up with origin tracking */
+#define TEST_CF_SECRET  __msan_allocated_memory
+// void __msan_allocated_memory(const volatile void* data, size_t size);
+#define TEST_CF_PUBLIC  __msan_unpoison
+// void __msan_unpoison(const volatile void *a, size_t size);
+
+#elif defined(MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND)
+#include <valgrind/memcheck.h>
+
+#define TEST_CF_SECRET  VALGRIND_MAKE_MEM_UNDEFINED
+// VALGRIND_MAKE_MEM_UNDEFINED(_qzz_addr, _qzz_len)
+#define TEST_CF_PUBLIC  VALGRIND_MAKE_MEM_DEFINED
+// VALGRIND_MAKE_MEM_DEFINED(_qzz_addr, _qzz_len)
+
+#else /* MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN ||
+         MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND */
+
+#define TEST_CF_SECRET(ptr, size)
+#define TEST_CF_PUBLIC(ptr, size)
+
+#endif /* MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN ||
+          MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND */
+
+#endif /* TEST_CONSTANT_FLOW_H */
diff --git a/framework/tests/include/test/drivers/aead.h b/framework/tests/include/test/drivers/aead.h
new file mode 100644
index 0000000..a033e39
--- /dev/null
+++ b/framework/tests/include/test/drivers/aead.h
@@ -0,0 +1,121 @@
+/*
+ * Test driver for AEAD driver entry points.
+ */
+/*  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef PSA_CRYPTO_TEST_DRIVERS_AEAD_H
+#define PSA_CRYPTO_TEST_DRIVERS_AEAD_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;
+    /* Count the amount of times AEAD driver functions are called. */
+    unsigned long hits_encrypt;
+    unsigned long hits_decrypt;
+    unsigned long hits_encrypt_setup;
+    unsigned long hits_decrypt_setup;
+    unsigned long hits_set_nonce;
+    unsigned long hits_set_lengths;
+    unsigned long hits_update_ad;
+    unsigned long hits_update;
+    unsigned long hits_finish;
+    unsigned long hits_verify;
+    unsigned long hits_abort;
+
+    /* Status returned by the last AEAD driver function call. */
+    psa_status_t driver_status;
+} mbedtls_test_driver_aead_hooks_t;
+
+#define MBEDTLS_TEST_DRIVER_AEAD_INIT { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+static inline mbedtls_test_driver_aead_hooks_t
+mbedtls_test_driver_aead_hooks_init(void)
+{
+    const mbedtls_test_driver_aead_hooks_t v = MBEDTLS_TEST_DRIVER_AEAD_INIT;
+    return v;
+}
+
+extern mbedtls_test_driver_aead_hooks_t mbedtls_test_driver_aead_hooks;
+
+psa_status_t mbedtls_test_transparent_aead_encrypt(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer, size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *nonce, size_t nonce_length,
+    const uint8_t *additional_data, size_t additional_data_length,
+    const uint8_t *plaintext, size_t plaintext_length,
+    uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length);
+
+psa_status_t mbedtls_test_transparent_aead_decrypt(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer, size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *nonce, size_t nonce_length,
+    const uint8_t *additional_data, size_t additional_data_length,
+    const uint8_t *ciphertext, size_t ciphertext_length,
+    uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length);
+
+psa_status_t mbedtls_test_transparent_aead_encrypt_setup(
+    mbedtls_transparent_test_driver_aead_operation_t *operation,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer, size_t key_buffer_size,
+    psa_algorithm_t alg);
+
+psa_status_t mbedtls_test_transparent_aead_decrypt_setup(
+    mbedtls_transparent_test_driver_aead_operation_t *operation,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer, size_t key_buffer_size,
+    psa_algorithm_t alg);
+
+psa_status_t mbedtls_test_transparent_aead_set_nonce(
+    mbedtls_transparent_test_driver_aead_operation_t *operation,
+    const uint8_t *nonce,
+    size_t nonce_length);
+
+psa_status_t mbedtls_test_transparent_aead_set_lengths(
+    mbedtls_transparent_test_driver_aead_operation_t *operation,
+    size_t ad_length,
+    size_t plaintext_length);
+
+psa_status_t mbedtls_test_transparent_aead_update_ad(
+    mbedtls_transparent_test_driver_aead_operation_t *operation,
+    const uint8_t *input,
+    size_t input_length);
+
+psa_status_t mbedtls_test_transparent_aead_update(
+    mbedtls_transparent_test_driver_aead_operation_t *operation,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length);
+
+psa_status_t mbedtls_test_transparent_aead_finish(
+    mbedtls_transparent_test_driver_aead_operation_t *operation,
+    uint8_t *ciphertext,
+    size_t ciphertext_size,
+    size_t *ciphertext_length,
+    uint8_t *tag,
+    size_t tag_size,
+    size_t *tag_length);
+
+psa_status_t mbedtls_test_transparent_aead_verify(
+    mbedtls_transparent_test_driver_aead_operation_t *operation,
+    uint8_t *plaintext,
+    size_t plaintext_size,
+    size_t *plaintext_length,
+    const uint8_t *tag,
+    size_t tag_length);
+
+psa_status_t mbedtls_test_transparent_aead_abort(
+    mbedtls_transparent_test_driver_aead_operation_t *operation);
+
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_TEST_DRIVERS_AEAD_H */
diff --git a/framework/tests/include/test/drivers/asymmetric_encryption.h b/framework/tests/include/test/drivers/asymmetric_encryption.h
new file mode 100644
index 0000000..0ac7708
--- /dev/null
+++ b/framework/tests/include/test/drivers/asymmetric_encryption.h
@@ -0,0 +1,67 @@
+/*
+ * Test driver for asymmetric encryption.
+ */
+/*  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef PSA_CRYPTO_TEST_DRIVERS_ASYMMETRIC_ENCRYPTION_H
+#define PSA_CRYPTO_TEST_DRIVERS_ASYMMETRIC_ENCRYPTION_H
+
+#include "mbedtls/build_info.h"
+
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+#include <psa/crypto_driver_common.h>
+#include <psa/crypto.h>
+
+typedef struct {
+    /* If non-null, on success, copy this to the output. */
+    void *forced_output;
+    size_t forced_output_length;
+    /* If not PSA_SUCCESS, return this error code instead of processing the
+     * function call. */
+    psa_status_t forced_status;
+    /* Count the amount of times one of the asymmetric_encryption driver
+       functions is called. */
+    unsigned long hits;
+} mbedtls_test_driver_asymmetric_encryption_hooks_t;
+
+#define MBEDTLS_TEST_DRIVER_ASYMMETRIC_ENCRYPTION_INIT { NULL, 0, PSA_SUCCESS, 0 }
+
+static inline mbedtls_test_driver_asymmetric_encryption_hooks_t
+mbedtls_test_driver_asymmetric_encryption_hooks_init(void)
+{
+    const mbedtls_test_driver_asymmetric_encryption_hooks_t v =
+        MBEDTLS_TEST_DRIVER_ASYMMETRIC_ENCRYPTION_INIT;
+    return v;
+}
+
+extern mbedtls_test_driver_asymmetric_encryption_hooks_t
+    mbedtls_test_driver_asymmetric_encryption_hooks;
+
+psa_status_t mbedtls_test_transparent_asymmetric_encrypt(
+    const psa_key_attributes_t *attributes, const uint8_t *key_buffer,
+    size_t key_buffer_size, psa_algorithm_t alg, const uint8_t *input,
+    size_t input_length, const uint8_t *salt, size_t salt_length,
+    uint8_t *output, size_t output_size, size_t *output_length);
+
+psa_status_t mbedtls_test_opaque_asymmetric_encrypt(
+    const psa_key_attributes_t *attributes, const uint8_t *key,
+    size_t key_length, psa_algorithm_t alg, const uint8_t *input,
+    size_t input_length, const uint8_t *salt, size_t salt_length,
+    uint8_t *output, size_t output_size, size_t *output_length);
+
+psa_status_t mbedtls_test_transparent_asymmetric_decrypt(
+    const psa_key_attributes_t *attributes, const uint8_t *key_buffer,
+    size_t key_buffer_size, psa_algorithm_t alg, const uint8_t *input,
+    size_t input_length, const uint8_t *salt, size_t salt_length,
+    uint8_t *output, size_t output_size, size_t *output_length);
+
+psa_status_t mbedtls_test_opaque_asymmetric_decrypt(
+    const psa_key_attributes_t *attributes, const uint8_t *key,
+    size_t key_length, psa_algorithm_t alg, const uint8_t *input,
+    size_t input_length, const uint8_t *salt, size_t salt_length,
+    uint8_t *output, size_t output_size, size_t *output_length);
+
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_TEST_DRIVERS_ASYMMETRIC_ENCRYPTION_H */
diff --git a/framework/tests/include/test/drivers/cipher.h b/framework/tests/include/test/drivers/cipher.h
new file mode 100644
index 0000000..2fe47e4
--- /dev/null
+++ b/framework/tests/include/test/drivers/cipher.h
@@ -0,0 +1,136 @@
+/*
+ * Test driver for cipher functions
+ */
+/*  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef PSA_CRYPTO_TEST_DRIVERS_CIPHER_H
+#define PSA_CRYPTO_TEST_DRIVERS_CIPHER_H
+
+#include "mbedtls/build_info.h"
+
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+#include <psa/crypto_driver_common.h>
+#include <psa/crypto.h>
+
+#include "mbedtls/cipher.h"
+
+typedef struct {
+    /* If non-null, on success, copy this to the output. */
+    void *forced_output;
+    size_t forced_output_length;
+    /* If not PSA_SUCCESS, return this error code instead of processing the
+     * function call. */
+    psa_status_t forced_status;
+    psa_status_t forced_status_encrypt;
+    psa_status_t forced_status_set_iv;
+    /* Count the amount of times one of the cipher driver functions is called. */
+    unsigned long hits;
+    unsigned long hits_encrypt;
+    unsigned long hits_set_iv;
+} mbedtls_test_driver_cipher_hooks_t;
+
+#define MBEDTLS_TEST_DRIVER_CIPHER_INIT { NULL, 0, \
+                                          PSA_SUCCESS, PSA_SUCCESS, PSA_SUCCESS, \
+                                          0, 0, 0 }
+static inline mbedtls_test_driver_cipher_hooks_t
+mbedtls_test_driver_cipher_hooks_init(void)
+{
+    const mbedtls_test_driver_cipher_hooks_t v = MBEDTLS_TEST_DRIVER_CIPHER_INIT;
+    return v;
+}
+
+extern mbedtls_test_driver_cipher_hooks_t mbedtls_test_driver_cipher_hooks;
+
+psa_status_t mbedtls_test_transparent_cipher_encrypt(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key, size_t key_length,
+    psa_algorithm_t alg,
+    const uint8_t *iv, size_t iv_length,
+    const uint8_t *input, size_t input_length,
+    uint8_t *output, size_t output_size, size_t *output_length);
+
+psa_status_t mbedtls_test_transparent_cipher_decrypt(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key, size_t key_length,
+    psa_algorithm_t alg,
+    const uint8_t *input, size_t input_length,
+    uint8_t *output, size_t output_size, size_t *output_length);
+
+psa_status_t mbedtls_test_transparent_cipher_encrypt_setup(
+    mbedtls_transparent_test_driver_cipher_operation_t *operation,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key, size_t key_length,
+    psa_algorithm_t alg);
+
+psa_status_t mbedtls_test_transparent_cipher_decrypt_setup(
+    mbedtls_transparent_test_driver_cipher_operation_t *operation,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key, size_t key_length,
+    psa_algorithm_t alg);
+
+psa_status_t mbedtls_test_transparent_cipher_abort(
+    mbedtls_transparent_test_driver_cipher_operation_t *operation);
+
+psa_status_t mbedtls_test_transparent_cipher_set_iv(
+    mbedtls_transparent_test_driver_cipher_operation_t *operation,
+    const uint8_t *iv, size_t iv_length);
+
+psa_status_t mbedtls_test_transparent_cipher_update(
+    mbedtls_transparent_test_driver_cipher_operation_t *operation,
+    const uint8_t *input, size_t input_length,
+    uint8_t *output, size_t output_size, size_t *output_length);
+
+psa_status_t mbedtls_test_transparent_cipher_finish(
+    mbedtls_transparent_test_driver_cipher_operation_t *operation,
+    uint8_t *output, size_t output_size, size_t *output_length);
+
+/*
+ * opaque versions
+ */
+psa_status_t mbedtls_test_opaque_cipher_encrypt(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key, size_t key_length,
+    psa_algorithm_t alg,
+    const uint8_t *iv, size_t iv_length,
+    const uint8_t *input, size_t input_length,
+    uint8_t *output, size_t output_size, size_t *output_length);
+
+psa_status_t mbedtls_test_opaque_cipher_decrypt(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key, size_t key_length,
+    psa_algorithm_t alg,
+    const uint8_t *input, size_t input_length,
+    uint8_t *output, size_t output_size, size_t *output_length);
+
+psa_status_t mbedtls_test_opaque_cipher_encrypt_setup(
+    mbedtls_opaque_test_driver_cipher_operation_t *operation,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key, size_t key_length,
+    psa_algorithm_t alg);
+
+psa_status_t mbedtls_test_opaque_cipher_decrypt_setup(
+    mbedtls_opaque_test_driver_cipher_operation_t *operation,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key, size_t key_length,
+    psa_algorithm_t alg);
+
+psa_status_t mbedtls_test_opaque_cipher_abort(
+    mbedtls_opaque_test_driver_cipher_operation_t *operation);
+
+psa_status_t mbedtls_test_opaque_cipher_set_iv(
+    mbedtls_opaque_test_driver_cipher_operation_t *operation,
+    const uint8_t *iv, size_t iv_length);
+
+psa_status_t mbedtls_test_opaque_cipher_update(
+    mbedtls_opaque_test_driver_cipher_operation_t *operation,
+    const uint8_t *input, size_t input_length,
+    uint8_t *output, size_t output_size, size_t *output_length);
+
+psa_status_t mbedtls_test_opaque_cipher_finish(
+    mbedtls_opaque_test_driver_cipher_operation_t *operation,
+    uint8_t *output, size_t output_size, size_t *output_length);
+
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_TEST_DRIVERS_CIPHER_H */
diff --git a/framework/tests/include/test/drivers/hash.h b/framework/tests/include/test/drivers/hash.h
new file mode 100644
index 0000000..ad48c45
--- /dev/null
+++ b/framework/tests/include/test/drivers/hash.h
@@ -0,0 +1,64 @@
+/*
+ * Test driver for hash driver entry points.
+ */
+/*  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef PSA_CRYPTO_TEST_DRIVERS_HASH_H
+#define PSA_CRYPTO_TEST_DRIVERS_HASH_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;
+    /* Count the amount of times hash driver entry points are called. */
+    unsigned long hits;
+    /* Status returned by the last hash driver entry point call. */
+    psa_status_t driver_status;
+} mbedtls_test_driver_hash_hooks_t;
+
+#define MBEDTLS_TEST_DRIVER_HASH_INIT { 0, 0, 0 }
+static inline mbedtls_test_driver_hash_hooks_t
+mbedtls_test_driver_hash_hooks_init(void)
+{
+    const mbedtls_test_driver_hash_hooks_t v = MBEDTLS_TEST_DRIVER_HASH_INIT;
+    return v;
+}
+
+extern mbedtls_test_driver_hash_hooks_t mbedtls_test_driver_hash_hooks;
+
+psa_status_t mbedtls_test_transparent_hash_compute(
+    psa_algorithm_t alg,
+    const uint8_t *input, size_t input_length,
+    uint8_t *hash, size_t hash_size, size_t *hash_length);
+
+psa_status_t mbedtls_test_transparent_hash_setup(
+    mbedtls_transparent_test_driver_hash_operation_t *operation,
+    psa_algorithm_t alg);
+
+psa_status_t mbedtls_test_transparent_hash_clone(
+    const mbedtls_transparent_test_driver_hash_operation_t *source_operation,
+    mbedtls_transparent_test_driver_hash_operation_t *target_operation);
+
+psa_status_t mbedtls_test_transparent_hash_update(
+    mbedtls_transparent_test_driver_hash_operation_t *operation,
+    const uint8_t *input,
+    size_t input_length);
+
+psa_status_t mbedtls_test_transparent_hash_finish(
+    mbedtls_transparent_test_driver_hash_operation_t *operation,
+    uint8_t *hash,
+    size_t hash_size,
+    size_t *hash_length);
+
+psa_status_t mbedtls_test_transparent_hash_abort(
+    mbedtls_transparent_test_driver_hash_operation_t *operation);
+
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_TEST_DRIVERS_HASH_H */
diff --git a/framework/tests/include/test/drivers/key_agreement.h b/framework/tests/include/test/drivers/key_agreement.h
new file mode 100644
index 0000000..ca82b3a
--- /dev/null
+++ b/framework/tests/include/test/drivers/key_agreement.h
@@ -0,0 +1,62 @@
+/*
+ * Test driver for key agreement functions.
+ */
+/*  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef PSA_CRYPTO_TEST_DRIVERS_KEY_AGREEMENT_H
+#define PSA_CRYPTO_TEST_DRIVERS_KEY_AGREEMENT_H
+
+#include "mbedtls/build_info.h"
+
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+#include <psa/crypto_driver_common.h>
+
+typedef struct {
+    /* If non-null, on success, copy this to the output. */
+    void *forced_output;
+    size_t forced_output_length;
+    /* If not PSA_SUCCESS, return this error code instead of processing the
+     * function call. */
+    psa_status_t forced_status;
+    /* Count the amount of times one of the signature driver functions is called. */
+    unsigned long hits;
+} mbedtls_test_driver_key_agreement_hooks_t;
+
+#define MBEDTLS_TEST_DRIVER_KEY_AGREEMENT_INIT { NULL, 0, PSA_SUCCESS, 0 }
+static inline mbedtls_test_driver_key_agreement_hooks_t
+mbedtls_test_driver_key_agreement_hooks_init(void)
+{
+    const mbedtls_test_driver_key_agreement_hooks_t
+        v = MBEDTLS_TEST_DRIVER_KEY_AGREEMENT_INIT;
+    return v;
+}
+
+extern mbedtls_test_driver_key_agreement_hooks_t
+    mbedtls_test_driver_key_agreement_hooks;
+
+psa_status_t mbedtls_test_transparent_key_agreement(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *peer_key,
+    size_t peer_key_length,
+    uint8_t *shared_secret,
+    size_t shared_secret_size,
+    size_t *shared_secret_length);
+
+psa_status_t mbedtls_test_opaque_key_agreement(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *peer_key,
+    size_t peer_key_length,
+    uint8_t *shared_secret,
+    size_t shared_secret_size,
+    size_t *shared_secret_length);
+
+#endif /*PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_TEST_DRIVERS_KEY_AGREEMENT_H */
diff --git a/framework/tests/include/test/drivers/key_management.h b/framework/tests/include/test/drivers/key_management.h
new file mode 100644
index 0000000..1d9bc43
--- /dev/null
+++ b/framework/tests/include/test/drivers/key_management.h
@@ -0,0 +1,131 @@
+/*
+ * Test driver for generating and verifying keys.
+ */
+/*  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef PSA_CRYPTO_TEST_DRIVERS_KEY_MANAGEMENT_H
+#define PSA_CRYPTO_TEST_DRIVERS_KEY_MANAGEMENT_H
+
+#include "mbedtls/build_info.h"
+
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+#include <psa/crypto_driver_common.h>
+
+#define PSA_CRYPTO_TEST_DRIVER_BUILTIN_AES_KEY_SLOT     0
+#define PSA_CRYPTO_TEST_DRIVER_BUILTIN_ECDSA_KEY_SLOT   1
+
+typedef struct {
+    /* If non-null, on success, copy this to the output. */
+    void *forced_output;
+    size_t forced_output_length;
+    /* If not PSA_SUCCESS, return this error code instead of processing the
+     * function call. */
+    psa_status_t forced_status;
+    /* Count the amount of times one of the key management driver functions
+     * is called. */
+    unsigned long hits;
+    /* Subset of hits which only counts public key export operations */
+    unsigned long hits_export_public_key;
+    /* Subset of hits which only counts key generation operations */
+    unsigned long hits_generate_key;
+    /* Location of the last key management driver called to import a key. */
+    psa_key_location_t location;
+} mbedtls_test_driver_key_management_hooks_t;
+
+/* The location is initialized to the invalid value 0x800000. Invalid in the
+ * sense that no PSA specification will assign a meaning to this location
+ * (stated first in version 1.0.1 of the specification) and that it is not
+ * used as a location of an opaque test drivers. */
+#define MBEDTLS_TEST_DRIVER_KEY_MANAGEMENT_INIT { NULL, 0, PSA_SUCCESS, 0, 0, 0, 0x800000 }
+static inline mbedtls_test_driver_key_management_hooks_t
+mbedtls_test_driver_key_management_hooks_init(void)
+{
+    const mbedtls_test_driver_key_management_hooks_t
+        v = MBEDTLS_TEST_DRIVER_KEY_MANAGEMENT_INIT;
+    return v;
+}
+
+/*
+ * In order to convert the plain text keys to Opaque, the size of the key is
+ * padded up by PSA_CRYPTO_TEST_DRIVER_OPAQUE_PAD_PREFIX_SIZE in addition to
+ * xor mangling the key. The pad prefix needs to be accounted for while
+ * sizing for the key.
+ */
+#define PSA_CRYPTO_TEST_DRIVER_OPAQUE_PAD_PREFIX           0xBEEFED00U
+#define PSA_CRYPTO_TEST_DRIVER_OPAQUE_PAD_PREFIX_SIZE      sizeof( \
+        PSA_CRYPTO_TEST_DRIVER_OPAQUE_PAD_PREFIX)
+
+size_t mbedtls_test_opaque_size_function(
+    const psa_key_type_t key_type,
+    const size_t key_bits);
+
+extern mbedtls_test_driver_key_management_hooks_t
+    mbedtls_test_driver_key_management_hooks;
+
+psa_status_t mbedtls_test_transparent_init(void);
+void mbedtls_test_transparent_free(void);
+psa_status_t mbedtls_test_opaque_init(void);
+void mbedtls_test_opaque_free(void);
+
+psa_status_t mbedtls_test_opaque_unwrap_key(
+    const uint8_t *wrapped_key, size_t wrapped_key_length, uint8_t *key_buffer,
+    size_t key_buffer_size, size_t *key_buffer_length);
+
+psa_status_t mbedtls_test_transparent_generate_key(
+    const psa_key_attributes_t *attributes,
+    uint8_t *key, size_t key_size, size_t *key_length);
+
+psa_status_t mbedtls_test_opaque_generate_key(
+    const psa_key_attributes_t *attributes,
+    uint8_t *key, size_t key_size, size_t *key_length);
+
+psa_status_t mbedtls_test_opaque_export_key(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key, size_t key_length,
+    uint8_t *data, size_t data_size, size_t *data_length);
+
+psa_status_t mbedtls_test_transparent_export_public_key(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key, size_t key_length,
+    uint8_t *data, size_t data_size, size_t *data_length);
+
+psa_status_t mbedtls_test_opaque_export_public_key(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key, size_t key_length,
+    uint8_t *data, size_t data_size, size_t *data_length);
+
+psa_status_t mbedtls_test_transparent_import_key(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *data,
+    size_t data_length,
+    uint8_t *key_buffer,
+    size_t key_buffer_size,
+    size_t *key_buffer_length,
+    size_t *bits);
+
+psa_status_t mbedtls_test_opaque_import_key(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *data,
+    size_t data_length,
+    uint8_t *key_buffer,
+    size_t key_buffer_size,
+    size_t *key_buffer_length,
+    size_t *bits);
+
+psa_status_t mbedtls_test_opaque_get_builtin_key(
+    psa_drv_slot_number_t slot_number,
+    psa_key_attributes_t *attributes,
+    uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length);
+
+psa_status_t mbedtls_test_opaque_copy_key(
+    psa_key_attributes_t *attributes,
+    const uint8_t *source_key,
+    size_t source_key_length,
+    uint8_t *target_key_buffer,
+    size_t target_key_buffer_size,
+    size_t *target_key_buffer_length);
+
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_TEST_DRIVERS_KEY_MANAGEMENT_H */
diff --git a/framework/tests/include/test/drivers/mac.h b/framework/tests/include/test/drivers/mac.h
new file mode 100644
index 0000000..d92eff9
--- /dev/null
+++ b/framework/tests/include/test/drivers/mac.h
@@ -0,0 +1,125 @@
+/*
+ * Test driver for MAC driver entry points.
+ */
+/*  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef PSA_CRYPTO_TEST_DRIVERS_MAC_H
+#define PSA_CRYPTO_TEST_DRIVERS_MAC_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;
+    /* Count the amount of times MAC driver functions are called. */
+    unsigned long hits;
+    /* Status returned by the last MAC driver function call. */
+    psa_status_t driver_status;
+} mbedtls_test_driver_mac_hooks_t;
+
+#define MBEDTLS_TEST_DRIVER_MAC_INIT { 0, 0, 0 }
+static inline mbedtls_test_driver_mac_hooks_t
+mbedtls_test_driver_mac_hooks_init(void)
+{
+    const mbedtls_test_driver_mac_hooks_t v = MBEDTLS_TEST_DRIVER_MAC_INIT;
+    return v;
+}
+
+extern mbedtls_test_driver_mac_hooks_t mbedtls_test_driver_mac_hooks;
+
+psa_status_t mbedtls_test_transparent_mac_compute(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *mac,
+    size_t mac_size,
+    size_t *mac_length);
+
+psa_status_t mbedtls_test_transparent_mac_sign_setup(
+    mbedtls_transparent_test_driver_mac_operation_t *operation,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg);
+
+psa_status_t mbedtls_test_transparent_mac_verify_setup(
+    mbedtls_transparent_test_driver_mac_operation_t *operation,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg);
+
+psa_status_t mbedtls_test_transparent_mac_update(
+    mbedtls_transparent_test_driver_mac_operation_t *operation,
+    const uint8_t *input,
+    size_t input_length);
+
+psa_status_t mbedtls_test_transparent_mac_sign_finish(
+    mbedtls_transparent_test_driver_mac_operation_t *operation,
+    uint8_t *mac,
+    size_t mac_size,
+    size_t *mac_length);
+
+psa_status_t mbedtls_test_transparent_mac_verify_finish(
+    mbedtls_transparent_test_driver_mac_operation_t *operation,
+    const uint8_t *mac,
+    size_t mac_length);
+
+psa_status_t mbedtls_test_transparent_mac_abort(
+    mbedtls_transparent_test_driver_mac_operation_t *operation);
+
+psa_status_t mbedtls_test_opaque_mac_compute(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *mac,
+    size_t mac_size,
+    size_t *mac_length);
+
+psa_status_t mbedtls_test_opaque_mac_sign_setup(
+    mbedtls_opaque_test_driver_mac_operation_t *operation,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg);
+
+psa_status_t mbedtls_test_opaque_mac_verify_setup(
+    mbedtls_opaque_test_driver_mac_operation_t *operation,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg);
+
+psa_status_t mbedtls_test_opaque_mac_update(
+    mbedtls_opaque_test_driver_mac_operation_t *operation,
+    const uint8_t *input,
+    size_t input_length);
+
+psa_status_t mbedtls_test_opaque_mac_sign_finish(
+    mbedtls_opaque_test_driver_mac_operation_t *operation,
+    uint8_t *mac,
+    size_t mac_size,
+    size_t *mac_length);
+
+psa_status_t mbedtls_test_opaque_mac_verify_finish(
+    mbedtls_opaque_test_driver_mac_operation_t *operation,
+    const uint8_t *mac,
+    size_t mac_length);
+
+psa_status_t mbedtls_test_opaque_mac_abort(
+    mbedtls_opaque_test_driver_mac_operation_t *operation);
+
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_TEST_DRIVERS_MAC_H */
diff --git a/framework/tests/include/test/drivers/pake.h b/framework/tests/include/test/drivers/pake.h
new file mode 100644
index 0000000..d292ca0
--- /dev/null
+++ b/framework/tests/include/test/drivers/pake.h
@@ -0,0 +1,75 @@
+/*
+ * Test driver for PAKE driver entry points.
+ */
+/*  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#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/framework/tests/include/test/drivers/signature.h b/framework/tests/include/test/drivers/signature.h
new file mode 100644
index 0000000..8c5703e
--- /dev/null
+++ b/framework/tests/include/test/drivers/signature.h
@@ -0,0 +1,112 @@
+/*
+ * Test driver for signature functions.
+ */
+/*  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef PSA_CRYPTO_TEST_DRIVERS_SIGNATURE_H
+#define PSA_CRYPTO_TEST_DRIVERS_SIGNATURE_H
+
+#include "mbedtls/build_info.h"
+
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+#include <psa/crypto_driver_common.h>
+
+typedef struct {
+    /* If non-null, on success, copy this to the output. */
+    void *forced_output;
+    size_t forced_output_length;
+    /* If not PSA_SUCCESS, return this error code instead of processing the
+     * function call. */
+    psa_status_t forced_status;
+    /* Count the amount of times one of the signature driver functions is called. */
+    unsigned long hits;
+} mbedtls_test_driver_signature_hooks_t;
+
+#define MBEDTLS_TEST_DRIVER_SIGNATURE_INIT { NULL, 0, PSA_SUCCESS, 0 }
+static inline mbedtls_test_driver_signature_hooks_t
+mbedtls_test_driver_signature_hooks_init(void)
+{
+    const mbedtls_test_driver_signature_hooks_t
+        v = MBEDTLS_TEST_DRIVER_SIGNATURE_INIT;
+    return v;
+}
+
+extern mbedtls_test_driver_signature_hooks_t
+    mbedtls_test_driver_signature_sign_hooks;
+extern mbedtls_test_driver_signature_hooks_t
+    mbedtls_test_driver_signature_verify_hooks;
+
+psa_status_t mbedtls_test_transparent_signature_sign_message(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key,
+    size_t key_length,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *signature,
+    size_t signature_size,
+    size_t *signature_length);
+
+psa_status_t mbedtls_test_opaque_signature_sign_message(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key,
+    size_t key_length,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *signature,
+    size_t signature_size,
+    size_t *signature_length);
+
+psa_status_t mbedtls_test_transparent_signature_verify_message(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key,
+    size_t key_length,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    const uint8_t *signature,
+    size_t signature_length);
+
+psa_status_t mbedtls_test_opaque_signature_verify_message(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key,
+    size_t key_length,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    const uint8_t *signature,
+    size_t signature_length);
+
+psa_status_t mbedtls_test_transparent_signature_sign_hash(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key, size_t key_length,
+    psa_algorithm_t alg,
+    const uint8_t *hash, size_t hash_length,
+    uint8_t *signature, size_t signature_size, size_t *signature_length);
+
+psa_status_t mbedtls_test_opaque_signature_sign_hash(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key, size_t key_length,
+    psa_algorithm_t alg,
+    const uint8_t *hash, size_t hash_length,
+    uint8_t *signature, size_t signature_size, size_t *signature_length);
+
+psa_status_t mbedtls_test_transparent_signature_verify_hash(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key, size_t key_length,
+    psa_algorithm_t alg,
+    const uint8_t *hash, size_t hash_length,
+    const uint8_t *signature, size_t signature_length);
+
+psa_status_t mbedtls_test_opaque_signature_verify_hash(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key, size_t key_length,
+    psa_algorithm_t alg,
+    const uint8_t *hash, size_t hash_length,
+    const uint8_t *signature, size_t signature_length);
+
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_TEST_DRIVERS_SIGNATURE_H */
diff --git a/framework/tests/include/test/drivers/test_driver.h b/framework/tests/include/test/drivers/test_driver.h
new file mode 100644
index 0000000..74605d6
--- /dev/null
+++ b/framework/tests/include/test/drivers/test_driver.h
@@ -0,0 +1,32 @@
+/*
+ * Umbrella include for all of the test driver functionality
+ */
+/*  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef PSA_CRYPTO_TEST_DRIVER_H
+#define PSA_CRYPTO_TEST_DRIVER_H
+
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+#ifndef PSA_CRYPTO_DRIVER_PRESENT
+#define PSA_CRYPTO_DRIVER_PRESENT
+#endif
+#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
+#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
+#endif
+
+#define PSA_CRYPTO_TEST_DRIVER_LOCATION 0x7fffff
+
+#include "test/drivers/aead.h"
+#include "test/drivers/cipher.h"
+#include "test/drivers/hash.h"
+#include "test/drivers/mac.h"
+#include "test/drivers/key_management.h"
+#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/framework/tests/include/test/fake_external_rng_for_test.h b/framework/tests/include/test/fake_external_rng_for_test.h
new file mode 100644
index 0000000..e3e331d
--- /dev/null
+++ b/framework/tests/include/test/fake_external_rng_for_test.h
@@ -0,0 +1,40 @@
+/*
+ * Insecure but standalone implementation of mbedtls_psa_external_get_random().
+ * Only for use in tests!
+ */
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef FAKE_EXTERNAL_RNG_FOR_TEST_H
+#define FAKE_EXTERNAL_RNG_FOR_TEST_H
+
+#include "mbedtls/build_info.h"
+
+#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+/** Enable the insecure implementation of mbedtls_psa_external_get_random().
+ *
+ * The insecure implementation of mbedtls_psa_external_get_random() is
+ * disabled by default.
+ *
+ * When MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled and the test
+ * helpers are linked into a program, you must enable this before running any
+ * code that uses the PSA subsystem to generate random data (including internal
+ * random generation for purposes such as blinding when the random generation
+ * is routed through PSA).
+ *
+ * You can enable and disable it at any time, regardless of the state
+ * of the PSA subsystem. You may disable it temporarily to simulate a
+ * depleted entropy source.
+ */
+void mbedtls_test_enable_insecure_external_rng(void);
+
+/** Disable the insecure implementation of mbedtls_psa_external_get_random().
+ *
+ * See mbedtls_test_enable_insecure_external_rng().
+ */
+void mbedtls_test_disable_insecure_external_rng(void);
+#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+
+#endif /* FAKE_EXTERNAL_RNG_FOR_TEST_H */
diff --git a/framework/tests/include/test/helpers.h b/framework/tests/include/test/helpers.h
new file mode 100644
index 0000000..d08100f
--- /dev/null
+++ b/framework/tests/include/test/helpers.h
@@ -0,0 +1,404 @@
+/**
+ * \file helpers.h
+ *
+ * \brief   This file contains the prototypes of helper functions for the
+ *          purpose of testing.
+ */
+
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef TEST_HELPERS_H
+#define TEST_HELPERS_H
+
+/* Most fields of publicly available structs are private and are wrapped with
+ * MBEDTLS_PRIVATE macro. This define allows tests to access the private fields
+ * directly (without using the MBEDTLS_PRIVATE wrapper). */
+#define MBEDTLS_ALLOW_PRIVATE_ACCESS
+
+#include "mbedtls/build_info.h"
+
+#if defined(__SANITIZE_ADDRESS__) /* gcc -fsanitize=address */
+#  define MBEDTLS_TEST_HAVE_ASAN
+#endif
+#if defined(__SANITIZE_THREAD__) /* gcc -fsanitize-thread */
+#  define MBEDTLS_TEST_HAVE_TSAN
+#endif
+
+#if defined(__has_feature)
+#  if __has_feature(address_sanitizer) /* clang -fsanitize=address */
+#    define MBEDTLS_TEST_HAVE_ASAN
+#  endif
+#  if __has_feature(memory_sanitizer) /* clang -fsanitize=memory */
+#    define MBEDTLS_TEST_HAVE_MSAN
+#  endif
+#  if __has_feature(thread_sanitizer) /* clang -fsanitize=thread */
+#    define MBEDTLS_TEST_HAVE_TSAN
+#  endif
+#endif
+
+#include "test/threading_helpers.h"
+
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+#include "mbedtls/threading.h"
+#endif
+
+#include "mbedtls/platform.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#if defined(MBEDTLS_BIGNUM_C)
+#include "mbedtls/bignum.h"
+#endif
+
+/** The type of test case arguments that contain binary data. */
+typedef struct data_tag {
+    uint8_t *x;
+    uint32_t    len;
+} data_t;
+
+typedef enum {
+    MBEDTLS_TEST_RESULT_SUCCESS = 0,
+    MBEDTLS_TEST_RESULT_FAILED,
+    MBEDTLS_TEST_RESULT_SKIPPED
+} mbedtls_test_result_t;
+
+#define MBEDTLS_TEST_LINE_LENGTH 76
+
+typedef struct {
+    mbedtls_test_result_t result;
+    const char *test;
+    const char *filename;
+    int line_no;
+    unsigned long step;
+    char line1[MBEDTLS_TEST_LINE_LENGTH];
+    char line2[MBEDTLS_TEST_LINE_LENGTH];
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+    const char *mutex_usage_error;
+#endif
+#if defined(MBEDTLS_BIGNUM_C)
+    unsigned case_uses_negative_0;
+#endif
+}
+mbedtls_test_info_t;
+
+/**
+ * \brief           Get the current test result status
+ *
+ * \return          The current test result status
+ */
+mbedtls_test_result_t mbedtls_test_get_result(void);
+
+/**
+ * \brief           Get the current test name/description
+ *
+ * \return          The current test name/description
+ */
+const char *mbedtls_test_get_test(void);
+
+/**
+ * \brief           Get the current test filename
+ *
+ * \return          The current test filename
+ */
+const char *mbedtls_get_test_filename(void);
+
+/**
+ * \brief           Get the current test file line number (for failure / skip)
+ *
+ * \return          The current test file line number (for failure / skip)
+ */
+int mbedtls_test_get_line_no(void);
+
+/**
+ * \brief           Increment the current test step.
+ *
+ * \note            It is not recommended for multiple threads to call this
+ *                  function concurrently - whilst it is entirely thread safe,
+ *                  the order of calls to this function can obviously not be
+ *                  ensured, so unexpected results may occur.
+ */
+void mbedtls_test_increment_step(void);
+
+/**
+ * \brief           Get the current test step
+ *
+ * \return          The current test step
+ */
+unsigned long mbedtls_test_get_step(void);
+
+/**
+ * \brief           Get the current test line buffer 1
+ *
+ * \param line      Buffer of minimum size \c MBEDTLS_TEST_LINE_LENGTH,
+ *                  which will have line buffer 1 copied to it.
+ */
+void mbedtls_test_get_line1(char *line);
+
+/**
+ * \brief           Get the current test line buffer 2
+ *
+ * \param line      Buffer of minimum size \c MBEDTLS_TEST_LINE_LENGTH,
+ *                  which will have line buffer 1 copied to it.
+ */
+void mbedtls_test_get_line2(char *line);
+
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+/**
+ * \brief           Get the current mutex usage error message
+ *
+ * \return          The current mutex error message (may be NULL if no error)
+ */
+const char *mbedtls_test_get_mutex_usage_error(void);
+
+/**
+ * \brief           Set the current mutex usage error message
+ *
+ * \note            This will only set the mutex error message if one has not
+ *                  already been set, or if we are clearing the message (msg is
+ *                  NULL)
+ *
+ * \param msg       Error message to set (can be NULL to clear)
+ */
+void mbedtls_test_set_mutex_usage_error(const char *msg);
+#endif
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+/**
+ * \brief           Get whether the current test is a bignum test that uses
+ *                  negative zero.
+ *
+ * \return          non zero if the current test uses bignum negative zero.
+ */
+unsigned mbedtls_test_get_case_uses_negative_0(void);
+
+/**
+ * \brief           Indicate that the current test uses bignum negative zero.
+ *
+ * \note            This function is called if the current test case had an
+ *                  input parsed with mbedtls_test_read_mpi() that is a negative
+ *                  0 (`"-"`, `"-0"`, `"-00"`, etc., constructing a result with
+ *                  the sign bit set to -1 and the value being all-limbs-0,
+ *                  which is not a valid representation in #mbedtls_mpi but is
+ *                  tested for robustness). *
+ */
+void  mbedtls_test_increment_case_uses_negative_0(void);
+#endif
+
+int mbedtls_test_platform_setup(void);
+void mbedtls_test_platform_teardown(void);
+
+/**
+ * \brief           Record the current test case as a failure.
+ *
+ *                  This function can be called directly however it is usually
+ *                  called via macros such as TEST_ASSERT, TEST_EQUAL,
+ *                  PSA_ASSERT, etc...
+ *
+ * \note            If the test case was already marked as failed, calling
+ *                  `mbedtls_test_fail( )` again will not overwrite any
+ *                  previous information about the failure.
+ *
+ * \param test      Description of the failure or assertion that failed. This
+ *                  MUST be a string literal.
+ * \param line_no   Line number where the failure originated.
+ * \param filename  Filename where the failure originated.
+ */
+void mbedtls_test_fail(const char *test, int line_no, const char *filename);
+
+/**
+ * \brief           Record the current test case as skipped.
+ *
+ *                  This function can be called directly however it is usually
+ *                  called via the TEST_ASSUME macro.
+ *
+ * \param test      Description of the assumption that caused the test case to
+ *                  be skipped. This MUST be a string literal.
+ * \param line_no   Line number where the test case was skipped.
+ * \param filename  Filename where the test case was skipped.
+ */
+void mbedtls_test_skip(const char *test, int line_no, const char *filename);
+
+/**
+ * \brief           Set the test step number for failure reports.
+ *
+ *                  Call this function to display "step NNN" in addition to the
+ *                  line number and file name if a test fails. Typically the
+ *                  "step number" is the index of a for loop but it can be
+ *                  whatever you want.
+ *
+ * \note            It is not recommended for multiple threads to call this
+ *                  function concurrently - whilst it is entirely thread safe,
+ *                  the order of calls to this function can obviously not be
+ *                  ensured, so unexpected results may occur.
+ *
+ * \param step  The step number to report.
+ */
+void mbedtls_test_set_step(unsigned long step);
+
+/**
+ * \brief           Reset mbedtls_test_info to a ready/starting state.
+ */
+void mbedtls_test_info_reset(void);
+
+#ifdef MBEDTLS_TEST_MUTEX_USAGE
+/**
+ * \brief           Get the test info data mutex.
+ *
+ * \note            This is designed only to be used by threading_helpers to
+ *                  avoid a deadlock, not for general access to this mutex.
+ *
+ * \return          The test info data mutex.
+ */
+mbedtls_threading_mutex_t *mbedtls_test_get_info_mutex(void);
+
+#endif /* MBEDTLS_TEST_MUTEX_USAGE */
+
+/**
+ * \brief Record the current test case as a failure if two integers
+ *                  have a different value.
+ *
+ *                  This function is usually called via the macro
+ *                  #TEST_EQUAL.
+ *
+ * \param test      Description of the failure or assertion that failed. This
+ *                  MUST be a string literal. This normally has the form
+ *                  "EXPR1 == EXPR2" where EXPR1 has the value \p value1
+ *                  and EXPR2 has the value \p value2.
+ * \param line_no   Line number where the failure originated.
+ * \param filename  Filename where the failure originated.
+ * \param value1    The first value to compare.
+ * \param value2    The second value to compare.
+ *
+ * \return          \c 1 if the values are equal, otherwise \c 0.
+ */
+int mbedtls_test_equal(const char *test, int line_no, const char *filename,
+                       unsigned long long value1, unsigned long long value2);
+
+/**
+ * \brief           Record the current test case as a failure based
+ *                  on comparing two unsigned integers.
+ *
+ *                  This function is usually called via the macro
+ *                  #TEST_LE_U.
+ *
+ * \param test      Description of the failure or assertion that failed. This
+ *                  MUST be a string literal. This normally has the form
+ *                  "EXPR1 <= EXPR2" where EXPR1 has the value \p value1
+ *                  and EXPR2 has the value \p value2.
+ * \param line_no   Line number where the failure originated.
+ * \param filename  Filename where the failure originated.
+ * \param value1    The first value to compare.
+ * \param value2    The second value to compare.
+ *
+ * \return          \c 1 if \p value1 <= \p value2, otherwise \c 0.
+ */
+int mbedtls_test_le_u(const char *test, int line_no, const char *filename,
+                      unsigned long long value1, unsigned long long value2);
+
+/**
+ * \brief           Record the current test case as a failure based
+ *                  on comparing two signed integers.
+ *
+ *                  This function is usually called via the macro
+ *                  #TEST_LE_S.
+ *
+ * \param test      Description of the failure or assertion that failed. This
+ *                  MUST be a string literal. This normally has the form
+ *                  "EXPR1 <= EXPR2" where EXPR1 has the value \p value1
+ *                  and EXPR2 has the value \p value2.
+ * \param line_no   Line number where the failure originated.
+ * \param filename  Filename where the failure originated.
+ * \param value1    The first value to compare.
+ * \param value2    The second value to compare.
+ *
+ * \return          \c 1 if \p value1 <= \p value2, otherwise \c 0.
+ */
+int mbedtls_test_le_s(const char *test, int line_no, const char *filename,
+                      long long value1, long long value2);
+
+/**
+ * \brief          This function decodes the hexadecimal representation of
+ *                 data.
+ *
+ * \note           The output buffer can be the same as the input buffer. For
+ *                 any other overlapping of the input and output buffers, the
+ *                 behavior is undefined.
+ *
+ * \param obuf     Output buffer.
+ * \param obufmax  Size in number of bytes of \p obuf.
+ * \param ibuf     Input buffer.
+ * \param len      The number of unsigned char written in \p obuf. This must
+ *                 not be \c NULL.
+ *
+ * \return         \c 0 on success.
+ * \return         \c -1 if the output buffer is too small or the input string
+ *                 is not a valid hexadecimal representation.
+ */
+int mbedtls_test_unhexify(unsigned char *obuf, size_t obufmax,
+                          const char *ibuf, size_t *len);
+
+void mbedtls_test_hexify(unsigned char *obuf,
+                         const unsigned char *ibuf,
+                         int len);
+
+/**
+ * \brief Convert hexadecimal digit to an integer.
+ *
+ * \param c        The digit to convert (`'0'` to `'9'`, `'A'` to `'F'` or
+ *                 `'a'` to `'f'`).
+ * \param[out] uc  On success, the value of the digit (0 to 15).
+ *
+ * \return         0 on success, -1 if \p c is not a hexadecimal digit.
+ */
+int mbedtls_test_ascii2uc(const char c, unsigned char *uc);
+
+/**
+ * Allocate and zeroize a buffer.
+ *
+ * If the size if zero, a pointer to a zeroized 1-byte buffer is returned.
+ *
+ * For convenience, dies if allocation fails.
+ */
+unsigned char *mbedtls_test_zero_alloc(size_t len);
+
+/**
+ * Allocate and fill a buffer from hex data.
+ *
+ * The buffer is sized exactly as needed. This allows to detect buffer
+ * overruns (including overreads) when running the test suite under valgrind.
+ *
+ * If the size if zero, a pointer to a zeroized 1-byte buffer is returned.
+ *
+ * For convenience, dies if allocation fails.
+ */
+unsigned char *mbedtls_test_unhexify_alloc(const char *ibuf, size_t *olen);
+
+int mbedtls_test_hexcmp(uint8_t *a, uint8_t *b,
+                        uint32_t a_len, uint32_t b_len);
+
+#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+#include "test/fake_external_rng_for_test.h"
+#endif
+
+#if defined(MBEDTLS_TEST_HOOKS)
+/**
+ * \brief   Check that only a pure high-level error code is being combined with
+ *          a pure low-level error code as otherwise the resultant error code
+ *          would be corrupted.
+ *
+ * \note    Both high-level and low-level error codes cannot be greater than
+ *          zero however can be zero. If one error code is zero then the
+ *          other error code is returned even if both codes are zero.
+ *
+ * \note    If the check fails, fail the test currently being run.
+ */
+void mbedtls_test_err_add_check(int high, int low,
+                                const char *file, int line);
+#endif
+
+#endif /* TEST_HELPERS_H */
diff --git a/framework/tests/include/test/macros.h b/framework/tests/include/test/macros.h
new file mode 100644
index 0000000..a73e06f
--- /dev/null
+++ b/framework/tests/include/test/macros.h
@@ -0,0 +1,250 @@
+/**
+ * \file macros.h
+ *
+ * \brief   This file contains generic macros for the purpose of testing.
+ */
+
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef TEST_MACROS_H
+#define TEST_MACROS_H
+
+#include "mbedtls/build_info.h"
+
+#include <stdlib.h>
+
+#include "mbedtls/platform.h"
+
+#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
+#include "mbedtls/memory_buffer_alloc.h"
+#endif
+#include "common.h"
+
+/**
+ * \brief   This macro tests the expression passed to it as a test step or
+ *          individual test in a test case.
+ *
+ *          It allows a library function to return a value and return an error
+ *          code that can be tested.
+ *
+ *          Failing the test means:
+ *          - Mark this test case as failed.
+ *          - Print a message identifying the failure.
+ *          - Jump to the \c exit label.
+ *
+ *          This macro expands to an instruction, not an expression.
+ *          It may jump to the \c exit label.
+ *
+ * \param   TEST    The test expression to be tested.
+ */
+#define TEST_ASSERT(TEST)                                 \
+    do {                                                    \
+        if (!(TEST))                                       \
+        {                                                    \
+            mbedtls_test_fail( #TEST, __LINE__, __FILE__);   \
+            goto exit;                                        \
+        }                                                    \
+    } while (0)
+
+/** This macro asserts fails the test with given output message.
+ *
+ * \param   MESSAGE The message to be outputed on assertion
+ */
+#define TEST_FAIL(MESSAGE)                           \
+    do {                                                  \
+        mbedtls_test_fail(MESSAGE, __LINE__, __FILE__);   \
+        goto exit;                                        \
+    } while (0)
+
+/** Evaluate two integer expressions and fail the test case if they have
+ * different values.
+ *
+ * The two expressions should have the same signedness, otherwise the
+ * comparison is not meaningful if the signed value is negative.
+ *
+ * \param expr1     An integral-typed expression to evaluate.
+ * \param expr2     Another integral-typed expression to evaluate.
+ */
+#define TEST_EQUAL(expr1, expr2)                                      \
+    do {                                                                \
+        if (!mbedtls_test_equal( #expr1 " == " #expr2, __LINE__, __FILE__, \
+                                 (unsigned long long) (expr1), (unsigned long long) (expr2)))                      \
+        goto exit;                                                  \
+    } while (0)
+
+/** Evaluate two unsigned integer expressions and fail the test case
+ * if they are not in increasing order (left <= right).
+ *
+ * \param expr1     An integral-typed expression to evaluate.
+ * \param expr2     Another integral-typed expression to evaluate.
+ */
+#define TEST_LE_U(expr1, expr2)                                       \
+    do {                                                                \
+        if (!mbedtls_test_le_u( #expr1 " <= " #expr2, __LINE__, __FILE__, \
+                                expr1, expr2))                      \
+        goto exit;                                                  \
+    } while (0)
+
+/** Evaluate two signed integer expressions and fail the test case
+ * if they are not in increasing order (left <= right).
+ *
+ * \param expr1     An integral-typed expression to evaluate.
+ * \param expr2     Another integral-typed expression to evaluate.
+ */
+#define TEST_LE_S(expr1, expr2)                                       \
+    do {                                                                \
+        if (!mbedtls_test_le_s( #expr1 " <= " #expr2, __LINE__, __FILE__, \
+                                expr1, expr2))                      \
+        goto exit;                                                  \
+    } while (0)
+
+/** Allocate memory dynamically and fail the test case if this fails.
+ * The allocated memory will be filled with zeros.
+ *
+ * You must set \p pointer to \c NULL before calling this macro and
+ * put `mbedtls_free(pointer)` in the test's cleanup code.
+ *
+ * If \p item_count is zero, the resulting \p pointer will be \c NULL.
+ * This is usually what we want in tests since API functions are
+ * supposed to accept null pointers when a buffer size is zero.
+ *
+ * This macro expands to an instruction, not an expression.
+ * It may jump to the \c exit label.
+ *
+ * \param pointer    An lvalue where the address of the allocated buffer
+ *                   will be stored.
+ *                   This expression may be evaluated multiple times.
+ * \param item_count Number of elements to allocate.
+ *                   This expression may be evaluated multiple times.
+ *
+ */
+#define TEST_CALLOC(pointer, item_count)                    \
+    do {                                                    \
+        TEST_ASSERT((pointer) == NULL);                     \
+        if ((item_count) != 0) {                            \
+            (pointer) = mbedtls_calloc((item_count),        \
+                                       sizeof(*(pointer))); \
+            TEST_ASSERT((pointer) != NULL);                 \
+        }                                                   \
+    } while (0)
+
+/** Allocate memory dynamically and fail the test case if this fails.
+ * The allocated memory will be filled with zeros.
+ *
+ * You must set \p pointer to \c NULL before calling this macro and
+ * put `mbedtls_free(pointer)` in the test's cleanup code.
+ *
+ * If \p item_count is zero, the resulting \p pointer will not be \c NULL.
+ *
+ * This macro expands to an instruction, not an expression.
+ * It may jump to the \c exit label.
+ *
+ * \param pointer    An lvalue where the address of the allocated buffer
+ *                   will be stored.
+ *                   This expression may be evaluated multiple times.
+ * \param item_count Number of elements to allocate.
+ *                   This expression may be evaluated multiple times.
+ *
+ * Note: if passing size 0, mbedtls_calloc may return NULL. In this case,
+ * we reattempt to allocate with the smallest possible buffer to assure a
+ * non-NULL pointer.
+ */
+#define TEST_CALLOC_NONNULL(pointer, item_count)            \
+    do {                                                    \
+        TEST_ASSERT((pointer) == NULL);                     \
+        (pointer) = mbedtls_calloc((item_count),            \
+                                   sizeof(*(pointer)));     \
+        if (((pointer) == NULL) && ((item_count) == 0)) {   \
+            (pointer) = mbedtls_calloc(1, 1);               \
+        }                                                   \
+        TEST_ASSERT((pointer) != NULL);                     \
+    } while (0)
+
+/* For backwards compatibility */
+#define ASSERT_ALLOC(pointer, item_count) TEST_CALLOC(pointer, item_count)
+
+/** Allocate memory dynamically. If the allocation fails, skip the test case.
+ *
+ * This macro behaves like #TEST_CALLOC, except that if the allocation
+ * fails, it marks the test as skipped rather than failed.
+ */
+#define TEST_CALLOC_OR_SKIP(pointer, item_count)            \
+    do {                                                    \
+        TEST_ASSERT((pointer) == NULL);                     \
+        if ((item_count) != 0) {                            \
+            (pointer) = mbedtls_calloc((item_count),        \
+                                       sizeof(*(pointer))); \
+            TEST_ASSUME((pointer) != NULL);                 \
+        }                                                   \
+    } while (0)
+
+/* For backwards compatibility */
+#define ASSERT_ALLOC_WEAK(pointer, item_count) TEST_CALLOC_OR_SKIP(pointer, item_count)
+
+/** Compare two buffers and fail the test case if they differ.
+ *
+ * This macro expands to an instruction, not an expression.
+ * It may jump to the \c exit label.
+ *
+ * \param p1        Pointer to the start of the first buffer.
+ * \param size1     Size of the first buffer in bytes.
+ *                  This expression may be evaluated multiple times.
+ * \param p2        Pointer to the start of the second buffer.
+ * \param size2     Size of the second buffer in bytes.
+ *                  This expression may be evaluated multiple times.
+ */
+#define TEST_MEMORY_COMPARE(p1, size1, p2, size2)              \
+    do {                                                       \
+        TEST_EQUAL((size1), (size2));                          \
+        if ((size1) != 0) {                                    \
+            TEST_ASSERT(memcmp((p1), (p2), (size1)) == 0);     \
+        }                                                      \
+    } while (0)
+
+/* For backwards compatibility */
+#define ASSERT_COMPARE(p1, size1, p2, size2) TEST_MEMORY_COMPARE(p1, size1, p2, size2)
+
+/**
+ * \brief   This macro tests the expression passed to it and skips the
+ *          running test if it doesn't evaluate to 'true'.
+ *
+ * \param   TEST    The test expression to be tested.
+ */
+#define TEST_ASSUME(TEST)                                 \
+    do {                                                    \
+        if (!(TEST))                                      \
+        {                                                   \
+            mbedtls_test_skip( #TEST, __LINE__, __FILE__); \
+            goto exit;                                      \
+        }                                                   \
+    } while (0)
+
+#define TEST_HELPER_ASSERT(a) if (!(a))                          \
+    {                                                                   \
+        mbedtls_fprintf(stderr, "Assertion Failed at %s:%d - %s\n",    \
+                        __FILE__, __LINE__, #a);              \
+        mbedtls_exit(1);                                              \
+    }
+
+/** Return the smaller of two values.
+ *
+ * \param x         An integer-valued expression without side effects.
+ * \param y         An integer-valued expression without side effects.
+ *
+ * \return The smaller of \p x and \p y.
+ */
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+
+/** Return the larger of two values.
+ *
+ * \param x         An integer-valued expression without side effects.
+ * \param y         An integer-valued expression without side effects.
+ *
+ * \return The larger of \p x and \p y.
+ */
+#define MAX(x, y) ((x) > (y) ? (x) : (y))
+
+#endif /* TEST_MACROS_H */
diff --git a/framework/tests/include/test/memory.h b/framework/tests/include/test/memory.h
new file mode 100644
index 0000000..940d9e6
--- /dev/null
+++ b/framework/tests/include/test/memory.h
@@ -0,0 +1,108 @@
+/**
+ * \file memory.h
+ *
+ * \brief   Helper macros and functions related to testing memory management.
+ */
+
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef TEST_MEMORY_H
+#define TEST_MEMORY_H
+
+#include "mbedtls/build_info.h"
+#include "mbedtls/platform.h"
+#include "test/helpers.h"
+
+/** \def MBEDTLS_TEST_MEMORY_CAN_POISON
+ *
+ * This macro is defined if the tests are compiled with a method to mark
+ * memory as poisoned, which can be used to enforce some memory access
+ * policies.
+ *
+ * Support for the C11 thread_local keyword is also required.
+ *
+ * Currently, only Asan (Address Sanitizer) is supported.
+ */
+#if defined(MBEDTLS_TEST_HAVE_ASAN) && \
+    (__STDC_VERSION__ >= 201112L) && \
+    !defined(PSA_CRYPTO_DRIVER_TEST)
+#  define MBEDTLS_TEST_MEMORY_CAN_POISON
+#endif
+
+/** \def MBEDTLS_TEST_MEMORY_POISON(buf, size)
+ *
+ * Poison a memory area so that any attempt to read or write from it will
+ * cause a runtime failure.
+ *
+ * Depending on the implementation, this may poison a few bytes beyond the
+ * indicated region, but will never poison a separate object on the heap
+ * or a separate object with more than the alignment of a long long.
+ *
+ * The behavior is undefined if any part of the memory area is invalid.
+ *
+ * This is a no-op in builds without a poisoning method.
+ * See #MBEDTLS_TEST_MEMORY_CAN_POISON.
+ *
+ * \param buf   Pointer to the beginning of the memory area to poison.
+ * \param size  Size of the memory area in bytes.
+ */
+
+/** \def MBEDTLS_TEST_MEMORY_UNPOISON(buf, size)
+ *
+ * Undo the effect of #MBEDTLS_TEST_MEMORY_POISON.
+ *
+ * The behavior is undefined if any part of the memory area is invalid,
+ * or if the memory area contains a mixture of poisoned and unpoisoned parts.
+ *
+ * This is a no-op in builds without a poisoning method.
+ * See #MBEDTLS_TEST_MEMORY_CAN_POISON.
+ *
+ * \param buf   Pointer to the beginning of the memory area to unpoison.
+ * \param size  Size of the memory area in bytes.
+ */
+
+#if defined(MBEDTLS_TEST_MEMORY_CAN_POISON)
+
+/** Thread-local variable used to enable memory poisoning. This is set and
+ *  unset in the test wrappers so that calls to PSA functions from the library
+ *  do not poison memory.
+ */
+extern _Thread_local unsigned int mbedtls_test_memory_poisoning_count;
+
+/** Poison a memory area so that any attempt to read or write from it will
+ * cause a runtime failure.
+ *
+ * The behavior is undefined if any part of the memory area is invalid.
+ */
+void mbedtls_test_memory_poison(const unsigned char *ptr, size_t size);
+#define MBEDTLS_TEST_MEMORY_POISON(ptr, size)    \
+    do { \
+        mbedtls_test_memory_poisoning_count++; \
+        mbedtls_test_memory_poison(ptr, size); \
+    } while (0)
+
+/** Undo the effect of mbedtls_test_memory_poison().
+ *
+ * This is a no-op if the given area is entirely valid, unpoisoned memory.
+ *
+ * The behavior is undefined if any part of the memory area is invalid,
+ * or if the memory area contains a mixture of poisoned and unpoisoned parts.
+ */
+void mbedtls_test_memory_unpoison(const unsigned char *ptr, size_t size);
+#define MBEDTLS_TEST_MEMORY_UNPOISON(ptr, size)    \
+    do { \
+        mbedtls_test_memory_unpoison(ptr, size); \
+        if (mbedtls_test_memory_poisoning_count != 0) { \
+            mbedtls_test_memory_poisoning_count--; \
+        } \
+    } while (0)
+
+#else /* MBEDTLS_TEST_MEMORY_CAN_POISON */
+#define MBEDTLS_TEST_MEMORY_POISON(ptr, size) ((void) (ptr), (void) (size))
+#define MBEDTLS_TEST_MEMORY_UNPOISON(ptr, size) ((void) (ptr), (void) (size))
+#endif /* MBEDTLS_TEST_MEMORY_CAN_POISON */
+
+#endif /* TEST_MEMORY_H */
diff --git a/framework/tests/include/test/psa_crypto_helpers.h b/framework/tests/include/test/psa_crypto_helpers.h
new file mode 100644
index 0000000..7ae0e30
--- /dev/null
+++ b/framework/tests/include/test/psa_crypto_helpers.h
@@ -0,0 +1,533 @@
+/*
+ * Helper functions for tests that use the PSA Crypto API.
+ */
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef PSA_CRYPTO_HELPERS_H
+#define PSA_CRYPTO_HELPERS_H
+
+#include "test/helpers.h"
+
+#if (MBEDTLS_VERSION_MAJOR < 4 && defined(MBEDTLS_PSA_CRYPTO_C)) || \
+    (MBEDTLS_VERSION_MAJOR >= 4 && defined(MBEDTLS_PSA_CRYPTO_CLIENT))
+#include "test/psa_helpers.h"
+#endif
+
+#include <psa/crypto.h>
+#include <mbedtls/ctr_drbg.h>
+
+#if defined(MBEDTLS_PSA_CRYPTO_C)
+/** Initialize the PSA Crypto subsystem. */
+#define PSA_INIT() PSA_ASSERT(psa_crypto_init())
+
+/** Shut down the PSA Crypto subsystem and destroy persistent keys.
+ * Expect a clean shutdown, with no slots in use.
+ *
+ * If some key slots are still in use, record the test case as failed,
+ * but continue executing. This macro is suitable (and primarily intended)
+ * for use in the cleanup section of test functions.
+ *
+ * \note Persistent keys must be recorded with #TEST_USES_KEY_ID before
+ *       creating them.
+ */
+#define PSA_DONE()                                                      \
+    do                                                                  \
+    {                                                                   \
+        mbedtls_test_fail_if_psa_leaking(__LINE__, __FILE__);           \
+        mbedtls_test_psa_purge_key_storage();                           \
+        mbedtls_psa_crypto_free();                                      \
+    }                                                                   \
+    while (0)
+#elif MBEDTLS_VERSION_MAJOR >= 4 && defined(MBEDTLS_PSA_CRYPTO_CLIENT)
+#define PSA_INIT() PSA_ASSERT(psa_crypto_init())
+#define PSA_DONE() mbedtls_psa_crypto_free();
+#else  /* MBEDTLS_PSA_CRYPTO_CLIENT && !MBEDTLS_PSA_CRYPTO_C */
+#define PSA_INIT() ((void) 0)
+#define PSA_DONE() ((void) 0)
+#endif /* MBEDTLS_PSA_CRYPTO_C */
+
+#if (MBEDTLS_VERSION_MAJOR < 4 && defined(MBEDTLS_PSA_CRYPTO_C)) || \
+    (MBEDTLS_VERSION_MAJOR >= 4 && defined(MBEDTLS_PSA_CRYPTO_CLIENT))
+
+#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
+
+/* Internal function for #TEST_USES_KEY_ID. Return 1 on success, 0 on failure. */
+int mbedtls_test_uses_key_id(mbedtls_svc_key_id_t key_id);
+
+/** Destroy persistent keys recorded with #TEST_USES_KEY_ID.
+ */
+void mbedtls_test_psa_purge_key_storage(void);
+
+/** Purge the in-memory cache of persistent keys recorded with
+ * #TEST_USES_KEY_ID.
+ *
+ * Call this function before calling PSA_DONE() if it's ok for
+ * persistent keys to still exist at this point.
+ */
+void mbedtls_test_psa_purge_key_cache(void);
+
+/** \def TEST_USES_KEY_ID
+ *
+ * Call this macro in a test function before potentially creating a
+ * persistent key. Test functions that use this mechanism must call
+ * mbedtls_test_psa_purge_key_storage() in their cleanup code.
+ *
+ * This macro records a persistent key identifier as potentially used in the
+ * current test case. Recorded key identifiers will be cleaned up at the end
+ * of the test case, even on failure.
+ *
+ * This macro has no effect on volatile keys. Therefore, it is safe to call
+ * this macro in a test function that creates either volatile or persistent
+ * keys depending on the test data.
+ *
+ * This macro currently has no effect on special identifiers
+ * used to store implementation-specific files.
+ *
+ * Calling this macro multiple times on the same key identifier in the same
+ * test case has no effect.
+ *
+ * This macro can fail the test case if there isn't enough memory to
+ * record the key id.
+ *
+ * \param key_id    The PSA key identifier to record.
+ */
+#define TEST_USES_KEY_ID(key_id)                      \
+    TEST_ASSERT(mbedtls_test_uses_key_id(key_id))
+
+#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
+
+#define TEST_USES_KEY_ID(key_id) ((void) (key_id))
+#define mbedtls_test_psa_purge_key_storage() ((void) 0)
+#define mbedtls_test_psa_purge_key_cache() ((void) 0)
+
+#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
+
+/** Check for things that have not been cleaned up properly in the
+ * PSA subsystem.
+ *
+ * \return NULL if nothing has leaked.
+ * \return A string literal explaining what has not been cleaned up
+ *         if applicable.
+ */
+const char *mbedtls_test_helper_is_psa_leaking(void);
+
+/** Check that no PSA Crypto key slots are in use.
+ *
+ * If any slots are in use, mark the current test as failed and jump to
+ * the exit label. This is equivalent to
+ * `TEST_ASSERT( ! mbedtls_test_helper_is_psa_leaking( ) )`
+ * but with a more informative message.
+ */
+#define ASSERT_PSA_PRISTINE()                                           \
+    do                                                                  \
+    {                                                                   \
+        if (mbedtls_test_fail_if_psa_leaking(__LINE__, __FILE__))       \
+        goto exit;                                                      \
+    }                                                                   \
+    while (0)
+
+/** Shut down the PSA Crypto subsystem, allowing persistent keys to survive.
+ * Expect a clean shutdown, with no slots in use.
+ *
+ * If some key slots are still in use, record the test case as failed and
+ * jump to the `exit` label.
+ */
+#define PSA_SESSION_DONE()                                             \
+    do                                                                  \
+    {                                                                   \
+        mbedtls_test_psa_purge_key_cache();                            \
+        ASSERT_PSA_PRISTINE();                                         \
+        mbedtls_psa_crypto_free();                                     \
+    }                                                                   \
+    while (0)
+
+
+
+#if defined(RECORD_PSA_STATUS_COVERAGE_LOG)
+psa_status_t mbedtls_test_record_status(psa_status_t status,
+                                        const char *func,
+                                        const char *file, int line,
+                                        const char *expr);
+
+/** Return value logging wrapper macro.
+ *
+ * Evaluate \p expr. Write a line recording its value to the log file
+ * #STATUS_LOG_FILE_NAME and return the value. The line is a colon-separated
+ * list of fields:
+ * ```
+ * value of expr:string:__FILE__:__LINE__:expr
+ * ```
+ *
+ * The test code does not call this macro explicitly because that would
+ * be very invasive. Instead, we instrument the source code by defining
+ * a bunch of wrapper macros like
+ * ```
+ * #define psa_crypto_init() RECORD_STATUS("psa_crypto_init", psa_crypto_init())
+ * ```
+ * These macro definitions must be present in `instrument_record_status.h`
+ * when building the test suites.
+ *
+ * \param string    A string, normally a function name.
+ * \param expr      An expression to evaluate, normally a call of the function
+ *                  whose name is in \p string. This expression must return
+ *                  a value of type #psa_status_t.
+ * \return          The value of \p expr.
+ */
+#define RECORD_STATUS(string, expr)                                   \
+    mbedtls_test_record_status((expr), string, __FILE__, __LINE__, #expr)
+
+#include "instrument_record_status.h"
+
+#endif /* defined(RECORD_PSA_STATUS_COVERAGE_LOG) */
+
+/** Return extended key usage policies.
+ *
+ * Do a key policy permission extension on key usage policies always involves
+ * permissions of other usage policies
+ * (like PSA_KEY_USAGE_SIGN_HASH involves PSA_KEY_USAGE_SIGN_MESSAGE).
+ */
+psa_key_usage_t mbedtls_test_update_key_usage_flags(psa_key_usage_t usage_flags);
+
+/** Check that no PSA Crypto key slots are in use.
+ *
+ * If any slots are in use, mark the current test as failed.
+ *
+ * \return 0 if the key store is empty, 1 otherwise.
+ */
+int mbedtls_test_fail_if_psa_leaking(int line_no, const char *filename);
+
+
+
+#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
+/* The #MBEDTLS_PSA_INJECT_ENTROPY feature requires two extra platform
+ * functions, which must be configured as #MBEDTLS_PLATFORM_NV_SEED_READ_MACRO
+ * and #MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO. The job of these functions
+ * is to read and write from the entropy seed file, which is located
+ * in the PSA ITS file whose uid is #PSA_CRYPTO_ITS_RANDOM_SEED_UID.
+ * (These could have been provided as library functions, but for historical
+ * reasons, they weren't, and so each integrator has to provide a copy
+ * of these functions.)
+ *
+ * Provide implementations of these functions for testing. */
+int mbedtls_test_inject_entropy_seed_read(unsigned char *buf, size_t len);
+int mbedtls_test_inject_entropy_seed_write(unsigned char *buf, size_t len);
+
+
+/** Make sure that the injected entropy is present.
+ *
+ * When MBEDTLS_PSA_INJECT_ENTROPY is enabled, psa_crypto_init()
+ * will fail if the PSA entropy seed is not present.
+ * This function must be called at least once in a test suite or other
+ * program before any call to psa_crypto_init().
+ * It does not need to be called in each test case.
+ *
+ * The test framework calls this function before running any test case.
+ *
+ * The few tests that might remove the entropy file must call this function
+ * in their cleanup.
+ */
+int mbedtls_test_inject_entropy_restore(void);
+#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
+
+/** Parse binary string and convert it to a long integer
+ */
+uint64_t mbedtls_test_parse_binary_string(data_t *bin_string);
+
+/** Skip a test case if the given key is a 192 bits AES key and the AES
+ *  implementation is at least partially provided by an accelerator or
+ *  alternative implementation.
+ *
+ *  Call this macro in a test case when a cryptographic operation that may
+ *  involve an AES operation returns a #PSA_ERROR_NOT_SUPPORTED error code.
+ *  The macro call will skip and not fail the test case in case the operation
+ *  involves a 192 bits AES key and the AES implementation is at least
+ *  partially provided by an accelerator or alternative implementation.
+ *
+ *  Hardware AES implementations not supporting 192 bits keys commonly exist.
+ *  Consequently, PSA test cases aim at not failing when an AES operation with
+ *  a 192 bits key performed by an alternative AES implementation returns
+ *  with the #PSA_ERROR_NOT_SUPPORTED error code. The purpose of this macro
+ *  is to facilitate this and make the test case code more readable.
+ *
+ *  \param key_type  Key type
+ *  \param key_bits  Key length in number of bits.
+ */
+#if defined(MBEDTLS_AES_ALT) || \
+    defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
+    defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_AES)
+#define MBEDTLS_TEST_HAVE_ACCEL_AES 1
+#else
+#define MBEDTLS_TEST_HAVE_ACCEL_AES 0
+#endif
+
+#define MBEDTLS_TEST_PSA_SKIP_IF_ALT_AES_192(key_type, key_bits)        \
+    do                                                                    \
+    {                                                                     \
+        if ((MBEDTLS_TEST_HAVE_ACCEL_AES) &&                              \
+            ((key_type) == PSA_KEY_TYPE_AES) &&                       \
+            (key_bits == 192))                                         \
+        {                                                                 \
+            mbedtls_test_skip("AES-192 not supported", __LINE__, __FILE__);     \
+            goto exit;                                                    \
+        }                                                                 \
+    }                                                                     \
+    while (0)
+
+/** Skip a test case if a GCM operation with a nonce length different from
+ *  12 bytes fails and was performed by an accelerator or alternative
+ *  implementation.
+ *
+ *  Call this macro in a test case when an AEAD cryptography operation that
+ *  may involve the GCM mode returns with a #PSA_ERROR_NOT_SUPPORTED error
+ *  code. The macro call will skip and not fail the test case in case the
+ *  operation involves the GCM mode, a nonce with a length different from
+ *  12 bytes and the GCM mode implementation is an alternative one.
+ *
+ *  Hardware GCM implementations not supporting nonce lengths different from
+ *  12 bytes commonly exist, as supporting a non-12-byte nonce requires
+ *  additional computations involving the GHASH function.
+ *  Consequently, PSA test cases aim at not failing when an AEAD operation in
+ *  GCM mode with a nonce length different from 12 bytes is performed by an
+ *  alternative GCM implementation and returns with a #PSA_ERROR_NOT_SUPPORTED
+ *  error code. The purpose of this macro is to facilitate this check and make
+ *  the test case code more readable.
+ *
+ *  \param  alg             The AEAD algorithm.
+ *  \param  nonce_length    The nonce length in number of bytes.
+ */
+
+#if defined(MBEDTLS_GCM_ALT) || \
+    defined(MBEDTLS_PSA_ACCEL_ALG_GCM)
+#define MBEDTLS_TEST_HAVE_ACCEL_GCM  1
+#else
+#define MBEDTLS_TEST_HAVE_ACCEL_GCM  0
+#endif
+
+#define MBEDTLS_TEST_PSA_SKIP_IF_ALT_GCM_NOT_12BYTES_NONCE(alg,           \
+                                                           nonce_length) \
+    do                                                                     \
+    {                                                                      \
+        if ((MBEDTLS_TEST_HAVE_ACCEL_GCM) &&                               \
+            (PSA_ALG_AEAD_WITH_SHORTENED_TAG((alg), 0) ==            \
+             PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0)) &&       \
+            ((nonce_length) != 12))                                   \
+        {                                                                  \
+            mbedtls_test_skip("GCM with non-12-byte IV is not supported", __LINE__, __FILE__); \
+            goto exit;                                                     \
+        }                                                                  \
+    }                                                                      \
+    while (0)
+
+#endif /* MBEDTLS_PSA_CRYPTO_CLIENT || MBEDTLS_PSA_CRYPTO_C */
+
+#if MBEDTLS_VERSION_MAJOR >= 4
+/* Legacy PSA_INIT() / PSA_DONE() variants from 3.6 */
+#define USE_PSA_INIT()          PSA_INIT()
+#define USE_PSA_DONE()          PSA_DONE()
+#define MD_PSA_INIT()           PSA_INIT()
+#define MD_PSA_DONE()           PSA_DONE()
+#define BLOCK_CIPHER_PSA_INIT() PSA_INIT()
+#define BLOCK_CIPHER_PSA_DONE() PSA_DONE()
+#define MD_OR_USE_PSA_INIT()    PSA_INIT()
+#define MD_OR_USE_PSA_DONE()    PSA_DONE()
+#define AES_PSA_INIT()          PSA_INIT()
+#define AES_PSA_DONE()          PSA_DONE()
+
+#else /* MBEDTLS_VERSION_MAJOR < 4 */
+
+/** \def USE_PSA_INIT
+ *
+ * Call this macro to initialize the PSA subsystem if #MBEDTLS_USE_PSA_CRYPTO
+ * or #MBEDTLS_SSL_PROTO_TLS1_3 (In contrast to TLS 1.2 implementation, the
+ * TLS 1.3 one uses PSA independently of the definition of
+ * #MBEDTLS_USE_PSA_CRYPTO) is enabled and do nothing otherwise.
+ *
+ * If the initialization fails, mark the test case as failed and jump to the
+ * \p exit label.
+ */
+/** \def USE_PSA_DONE
+ *
+ * Call this macro at the end of a test case if you called #USE_PSA_INIT.
+ *
+ * This is like #PSA_DONE except it does nothing under the same conditions as
+ * #USE_PSA_INIT.
+ */
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#define USE_PSA_INIT() PSA_INIT()
+#define USE_PSA_DONE() PSA_DONE()
+#elif defined(MBEDTLS_SSL_PROTO_TLS1_3)
+/* TLS 1.3 must work without having called psa_crypto_init(), for backward
+ * compatibility with Mbed TLS <= 3.5 when connecting with a peer that
+ * supports both TLS 1.2 and TLS 1.3. See mbedtls_ssl_tls13_crypto_init()
+ * and https://github.com/Mbed-TLS/mbedtls/issues/9072 . */
+#define USE_PSA_INIT() ((void) 0)
+/* TLS 1.3 may have initialized the PSA subsystem. Shut it down cleanly,
+ * otherwise Asan and Valgrind would notice a resource leak. */
+#define USE_PSA_DONE() PSA_DONE()
+#else /* MBEDTLS_USE_PSA_CRYPTO || MBEDTLS_SSL_PROTO_TLS1_3 */
+/* Define empty macros so that we can use them in the preamble and teardown
+ * of every test function that uses PSA conditionally based on
+ * MBEDTLS_USE_PSA_CRYPTO. */
+#define USE_PSA_INIT() ((void) 0)
+#define USE_PSA_DONE() ((void) 0)
+#endif /* !MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_SSL_PROTO_TLS1_3 */
+
+/** \def MD_PSA_INIT
+ *
+ * Call this macro to initialize the PSA subsystem if MD uses a driver,
+ * and do nothing otherwise.
+ *
+ * If the initialization fails, mark the test case as failed and jump to the
+ * \p exit label.
+ */
+/** \def MD_PSA_DONE
+ *
+ * Call this macro at the end of a test case if you called #MD_PSA_INIT.
+ *
+ * This is like #PSA_DONE except it does nothing under the same conditions as
+ * #MD_PSA_INIT.
+ */
+#if defined(MBEDTLS_MD_SOME_PSA)
+#define MD_PSA_INIT()   PSA_INIT()
+#define MD_PSA_DONE()   PSA_DONE()
+#else /* MBEDTLS_MD_SOME_PSA */
+#define MD_PSA_INIT() ((void) 0)
+#define MD_PSA_DONE() ((void) 0)
+#endif /* MBEDTLS_MD_SOME_PSA */
+
+/** \def BLOCK_CIPHER_PSA_INIT
+ *
+ * Call this macro to initialize the PSA subsystem if BLOCK_CIPHER uses a driver,
+ * and do nothing otherwise.
+ *
+ * If the initialization fails, mark the test case as failed and jump to the
+ * \p exit label.
+ */
+/** \def BLOCK_CIPHER_PSA_DONE
+ *
+ * Call this macro at the end of a test case if you called #BLOCK_CIPHER_PSA_INIT.
+ *
+ * This is like #PSA_DONE except it does nothing under the same conditions as
+ * #BLOCK_CIPHER_PSA_INIT.
+ */
+#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
+#define BLOCK_CIPHER_PSA_INIT()   PSA_INIT()
+#define BLOCK_CIPHER_PSA_DONE()   PSA_DONE()
+#else /* MBEDTLS_MD_SOME_PSA */
+#define BLOCK_CIPHER_PSA_INIT() ((void) 0)
+#define BLOCK_CIPHER_PSA_DONE() ((void) 0)
+#endif /* MBEDTLS_MD_SOME_PSA */
+
+
+/** \def MD_OR_USE_PSA_INIT
+ *
+ * Call this macro to initialize the PSA subsystem if MD uses a driver,
+ * or if #MBEDTLS_USE_PSA_CRYPTO or #MBEDTLS_SSL_PROTO_TLS1_3 is enabled,
+ * and do nothing otherwise.
+ *
+ * If the initialization fails, mark the test case as failed and jump to the
+ * \p exit label.
+ */
+/** \def MD_OR_USE_PSA_DONE
+ *
+ * Call this macro at the end of a test case if you called #MD_OR_USE_PSA_INIT.
+ *
+ * This is like #PSA_DONE except it does nothing under the same conditions as
+ * #MD_OR_USE_PSA_INIT.
+ */
+#if defined(MBEDTLS_MD_SOME_PSA)
+#define MD_OR_USE_PSA_INIT()   PSA_INIT()
+#define MD_OR_USE_PSA_DONE()   PSA_DONE()
+#else
+#define MD_OR_USE_PSA_INIT()   USE_PSA_INIT()
+#define MD_OR_USE_PSA_DONE()   USE_PSA_DONE()
+#endif
+
+/** \def AES_PSA_INIT
+ *
+ * Call this macro to initialize the PSA subsystem if AES_C is not defined,
+ * so that CTR_DRBG uses PSA implementation to get AES-ECB.
+ *
+ * If the initialization fails, mark the test case as failed and jump to the
+ * \p exit label.
+ */
+/** \def AES_PSA_DONE
+ *
+ * Call this macro at the end of a test case if you called #AES_PSA_INIT.
+ *
+ * This is like #PSA_DONE except it does nothing under the same conditions as
+ * #AES_PSA_INIT.
+ */
+#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
+#define AES_PSA_INIT()   PSA_INIT()
+#define AES_PSA_DONE()   PSA_DONE()
+#else /* MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO */
+#define AES_PSA_INIT() ((void) 0)
+#define AES_PSA_DONE() ((void) 0)
+#endif /* MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO */
+
+#endif /* MBEDTLS_VERSION_MAJOR >= 4 */
+
+#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) &&                        \
+    defined(MBEDTLS_CTR_DRBG_C) &&                                      \
+    defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
+/* When AES_C is not defined and PSA does not have an external RNG,
+ * then CTR_DRBG uses PSA to perform AES-ECB. In this scenario 1 key
+ * slot is used internally from PSA to hold the AES key and it should
+ * not be taken into account when evaluating remaining open slots. */
+#define MBEDTLS_TEST_PSA_INTERNAL_KEYS_FOR_DRBG 1
+#else
+#define MBEDTLS_TEST_PSA_INTERNAL_KEYS_FOR_DRBG 0
+#endif
+
+/** The number of volatile keys that PSA crypto uses internally.
+ *
+ * We expect that many volatile keys to be in use after a successful
+ * psa_crypto_init().
+ */
+#define MBEDTLS_TEST_PSA_INTERNAL_KEYS          \
+    MBEDTLS_TEST_PSA_INTERNAL_KEYS_FOR_DRBG
+
+/* A couple of helper macros to verify if MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE is
+ * large enough to contain an RSA key pair of the given size. This is meant to be
+ * used in test cases where MBEDTLS_PSA_STATIC_KEY_SLOTS is enabled. */
+#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
+
+#if (MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE >= PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(4096))
+#define MBEDTLS_TEST_STATIC_KEY_SLOTS_SUPPORT_RSA_4096
+#endif
+
+#if (MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE >= PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(2048))
+#define MBEDTLS_TEST_STATIC_KEY_SLOTS_SUPPORT_RSA_2048
+#endif
+
+#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
+
+/* Helper macro to get the size of the each key slot buffer. */
+#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS)
+#define MBEDTLS_PSA_KEY_BUFFER_MAX_SIZE     MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE
+#else
+#define MBEDTLS_PSA_KEY_BUFFER_MAX_SIZE     SIZE_MAX
+#endif
+
+/* Helper macro for the PK module to check whether MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE
+ * is large enough to contain 4096-bit RSA key pairs. Of course this check is only
+ * necessary if PK relies on PSA (i.e. MBEDTLS_USE_PSA_CRYPTO) to store and manage
+ * the key. */
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+
+#if !defined(MBEDTLS_PSA_STATIC_KEY_SLOTS) || \
+    defined(MBEDTLS_TEST_STATIC_KEY_SLOTS_SUPPORT_RSA_4096)
+#define MBEDTLS_TEST_PK_ALLOW_RSA_KEY_PAIR_4096
+#endif
+
+#else /* MBEDTLS_USE_PSA_CRYPTO */
+
+#define MBEDTLS_TEST_PK_ALLOW_RSA_KEY_PAIR_4096
+
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#endif /* PSA_CRYPTO_HELPERS_H */
diff --git a/framework/tests/include/test/psa_exercise_key.h b/framework/tests/include/test/psa_exercise_key.h
new file mode 100644
index 0000000..f44608b
--- /dev/null
+++ b/framework/tests/include/test/psa_exercise_key.h
@@ -0,0 +1,286 @@
+/** Code to exercise a PSA key object, i.e. validate that it seems well-formed
+ * and can do what it is supposed to do.
+ */
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef PSA_EXERCISE_KEY_H
+#define PSA_EXERCISE_KEY_H
+
+#include "test/helpers.h"
+#include "test/psa_crypto_helpers.h"
+
+#include <psa/crypto.h>
+
+#if defined(MBEDTLS_PK_C)
+#include <mbedtls/pk.h>
+#endif
+
+/** \def KNOWN_SUPPORTED_HASH_ALG
+ *
+ * A hash algorithm that is known to be supported.
+ *
+ * This is used in some smoke tests.
+ */
+#if defined(PSA_WANT_ALG_SHA_256)
+#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_256
+#elif defined(PSA_WANT_ALG_SHA_384)
+#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_384
+#elif defined(PSA_WANT_ALG_SHA_512)
+#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_512
+#elif defined(PSA_WANT_ALG_SHA3_256)
+#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA3_256
+#elif defined(PSA_WANT_ALG_SHA_1)
+#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_1
+#elif defined(PSA_WANT_ALG_MD5)
+#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD5
+/* PSA_WANT_ALG_RIPEMD160 omitted. This is necessary for the sake of
+ * exercise_signature_key() because Mbed TLS doesn't support RIPEMD160
+ * in RSA PKCS#1v1.5 signatures. A RIPEMD160-only configuration would be
+ * implausible anyway. */
+#else
+#undef KNOWN_SUPPORTED_HASH_ALG
+#endif
+
+/** \def KNOWN_SUPPORTED_BLOCK_CIPHER
+ *
+ * A block cipher that is known to be supported.
+ *
+ * For simplicity's sake, stick to block ciphers with 16-byte blocks.
+ */
+#if defined(PSA_WANT_KEY_TYPE_AES)
+#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_AES
+#elif defined(PSA_WANT_KEY_TYPE_ARIA)
+#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_ARIA
+#elif defined(PSA_WANT_KEY_TYPE_CAMELLIA)
+#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_CAMELLIA
+#else
+#undef KNOWN_SUPPORTED_BLOCK_CIPHER
+#endif
+
+/** \def KNOWN_SUPPORTED_MAC_ALG
+ *
+ * A MAC mode that is known to be supported.
+ *
+ * It must either be HMAC with #KNOWN_SUPPORTED_HASH_ALG or
+ * a block cipher-based MAC with #KNOWN_SUPPORTED_BLOCK_CIPHER.
+ *
+ * This is used in some smoke tests.
+ */
+#if defined(KNOWN_SUPPORTED_HASH_ALG) && defined(PSA_WANT_ALG_HMAC)
+#define KNOWN_SUPPORTED_MAC_ALG (PSA_ALG_HMAC(KNOWN_SUPPORTED_HASH_ALG))
+#define KNOWN_SUPPORTED_MAC_KEY_TYPE PSA_KEY_TYPE_HMAC
+#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CMAC_C)
+#define KNOWN_SUPPORTED_MAC_ALG PSA_ALG_CMAC
+#define KNOWN_SUPPORTED_MAC_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
+#else
+#undef KNOWN_SUPPORTED_MAC_ALG
+#undef KNOWN_SUPPORTED_MAC_KEY_TYPE
+#endif
+
+/** \def KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
+ *
+ * A cipher algorithm and key type that are known to be supported.
+ *
+ * This is used in some smoke tests.
+ */
+#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(PSA_WANT_ALG_CTR)
+#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CTR
+#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(PSA_WANT_ALG_CBC_NO_PADDING)
+#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CBC_NO_PADDING
+#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(PSA_WANT_ALG_CFB)
+#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CFB
+#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(PSA_WANT_ALG_OFB)
+#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_OFB
+#else
+#undef KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
+#endif
+#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER_ALG)
+#define KNOWN_SUPPORTED_CIPHER_ALG KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
+#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
+#else
+#undef KNOWN_SUPPORTED_CIPHER_ALG
+#undef KNOWN_SUPPORTED_CIPHER_KEY_TYPE
+#endif
+
+/** Convenience function to set up a key derivation.
+ *
+ * In case of failure, mark the current test case as failed.
+ *
+ * The inputs \p input1 and \p input2 are, in order:
+ * - HKDF: salt, info.
+ * - TKS 1.2 PRF, TLS 1.2 PSK-to-MS: seed, label.
+ * - PBKDF2: input cost, salt.
+ *
+ * \param operation         The operation object to use.
+ *                          It must be in the initialized state.
+ * \param key               The key to use.
+ * \param alg               The algorithm to use.
+ * \param input1            The first input to pass.
+ * \param input1_length     The length of \p input1 in bytes.
+ * \param input2            The first input to pass.
+ * \param input2_length     The length of \p input2 in bytes.
+ * \param capacity          The capacity to set.
+ * \param key_destroyable   If set to 1, a failure due to the key not existing
+ *                          or the key being destroyed mid-operation will only
+ *                          be reported if the error code is unexpected.
+ *
+ * \return                  \c 1 on success, \c 0 on failure.
+ */
+int mbedtls_test_psa_setup_key_derivation_wrap(
+    psa_key_derivation_operation_t *operation,
+    mbedtls_svc_key_id_t key,
+    psa_algorithm_t alg,
+    const unsigned char *input1, size_t input1_length,
+    const unsigned char *input2, size_t input2_length,
+    size_t capacity, int key_destroyable);
+
+/** Perform a key agreement using the given key pair against its public key
+ * using psa_raw_key_agreement() and psa_key_agreement().
+ *
+ * The result is discarded. The purpose of this function is to smoke-test a key.
+ *
+ * In case of failure, mark the current test case as failed.
+ *
+ * \param alg               A key agreement algorithm compatible with \p key.
+ * \param key               A key that allows key agreement with \p alg.
+ * \param key_destroyable   If set to 1, a failure due to the key not existing
+ *                          or the key being destroyed mid-operation will only
+ *                          be reported if the error code is unexpected.
+ *
+ * \return                  \c 1 on success, \c 0 on failure.
+ */
+psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
+    psa_algorithm_t alg,
+    mbedtls_svc_key_id_t key, int key_destroyable);
+
+/** Perform a key agreement using the given key pair against its public key
+ * using psa_key_derivation_raw_key().
+ *
+ * The result is discarded. The purpose of this function is to smoke-test a key.
+ *
+ * In case of failure, mark the current test case as failed.
+ *
+ * \param operation         An operation that has been set up for a key
+ *                          agreement algorithm that is compatible with
+ *                          \p key.
+ * \param key               A key pair object that is suitable for a key
+ *                          agreement with \p operation.
+ * \param key_destroyable   If set to 1, a failure due to the key not existing
+ *                          or the key being destroyed mid-operation will only
+ *                          be reported if the error code is unexpected.
+ *
+ * \return                  \c 1 on success, \c 0 on failure.
+ */
+psa_status_t mbedtls_test_psa_key_agreement_with_self(
+    psa_key_derivation_operation_t *operation,
+    mbedtls_svc_key_id_t key, int key_destroyable);
+
+/** Perform sanity checks on the given key representation.
+ *
+ * If any of the checks fail, mark the current test case as failed.
+ *
+ * The checks depend on the key type.
+ * - All types: check the export size against maximum-size macros.
+ * - DES: parity bits.
+ * - RSA: check the ASN.1 structure and the size and parity of the integers.
+ * - ECC private or public key: exact representation length.
+ * - Montgomery public key: first byte.
+ *
+ * \param type              The key type.
+ * \param bits              The key size in bits.
+ * \param exported          A buffer containing the key representation.
+ * \param exported_length   The length of \p exported in bytes.
+ *
+ * \return                  \c 1 if all checks passed, \c 0 on failure.
+ */
+int mbedtls_test_psa_exported_key_sanity_check(
+    psa_key_type_t type, size_t bits,
+    const uint8_t *exported, size_t exported_length);
+
+/** Do smoke tests on a key.
+ *
+ * Perform one of each operation indicated by \p alg (decrypt/encrypt,
+ * sign/verify, or derivation) that is permitted according to \p usage.
+ * \p usage and \p alg should correspond to the expected policy on the
+ * key.
+ *
+ * Export the key if permitted by \p usage, and check that the output
+ * looks sensible. If \p usage forbids export, check that
+ * \p psa_export_key correctly rejects the attempt. If the key is
+ * asymmetric, also check \p psa_export_public_key.
+ *
+ * If the key fails the tests, this function calls the test framework's
+ * `mbedtls_test_fail` function and returns false. Otherwise this function
+ * returns true. Therefore it should be used as follows:
+ * ```
+ * if( ! exercise_key( ... ) ) goto exit;
+ * ```
+ * To use this function for multi-threaded tests where the key
+ * may be destroyed at any point: call this function with key_destroyable set
+ * to 1, while another thread calls psa_destroy_key on the same key;
+ * this will test whether destroying the key in use leads to any corruption.
+ *
+ * There cannot be a set of concurrent calls:
+ * `mbedtls_test_psa_exercise_key(ki,...)` such that each ki is a unique
+ * persistent key not loaded into any key slot, and i is greater than the
+ * number of free key slots.
+ * This is because such scenarios can lead to unsupported
+ * `PSA_ERROR_INSUFFICIENT_MEMORY` return codes.
+ *
+ *
+ * \param key               The key to exercise. It should be capable of performing
+ *                          \p alg.
+ * \param usage             The usage flags to assume.
+ * \param alg               The algorithm to exercise.
+ * \param key_destroyable   If set to 1, a failure due to the key not existing
+ *                          or the key being destroyed mid-operation will only
+ *                          be reported if the error code is unexpected.
+ *
+ * \retval 0 The key failed the smoke tests.
+ * \retval 1 The key passed the smoke tests.
+ */
+int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
+                                  psa_key_usage_t usage,
+                                  psa_algorithm_t alg,
+                                  int key_destroyable);
+
+psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
+                                                   psa_algorithm_t alg);
+
+/** Whether the specified algorithm can be exercised.
+ *
+ * \note This function is solely based on the algorithm and does not
+ *       consider potential issues with the compatibility of a key.
+ *       The idea is that you already have a key, so you know that the
+ *       key type is supported, and you want to exercise the key but
+ *       only if the algorithm given in its policy is enabled in the
+ *       compile-time configuration.
+ *
+ * \note This function currently only supports signature algorithms
+ *       (including wildcards).
+ *       TODO: a more general mechanism, which should be automatically
+ *       generated and possibly available as a library function?
+ */
+int mbedtls_test_can_exercise_psa_algorithm(psa_algorithm_t alg);
+
+#if defined(MBEDTLS_PK_C)
+/** PK-PSA key consistency test.
+ *
+ * This function tests that the pk context and the PSA key are
+ * consistent. At a minimum:
+ *
+ * - The two objects must contain keys of the same type,
+ *   or a key pair and a public key of the matching type.
+ * - The two objects must have the same public key.
+ *
+ * \retval 0 The key failed the consistency tests.
+ * \retval 1 The key passed the consistency tests.
+ */
+int mbedtls_test_key_consistency_psa_pk(mbedtls_svc_key_id_t psa_key,
+                                        const mbedtls_pk_context *pk);
+#endif /* MBEDTLS_PK_C */
+
+#endif /* PSA_EXERCISE_KEY_H */
diff --git a/framework/tests/include/test/psa_helpers.h b/framework/tests/include/test/psa_helpers.h
new file mode 100644
index 0000000..b617189
--- /dev/null
+++ b/framework/tests/include/test/psa_helpers.h
@@ -0,0 +1,24 @@
+/*
+ * Helper functions for tests that use any PSA API.
+ */
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef PSA_HELPERS_H
+#define PSA_HELPERS_H
+
+#if defined(MBEDTLS_PSA_CRYPTO_SPM)
+#include "spm/psa_defs.h"
+#endif
+
+/** Evaluate an expression and fail the test case if it returns an error.
+ *
+ * \param expr      The expression to evaluate. This is typically a call
+ *                  to a \c psa_xxx function that returns a value of type
+ *                  #psa_status_t.
+ */
+#define PSA_ASSERT(expr) TEST_EQUAL((expr), PSA_SUCCESS)
+
+#endif /* PSA_HELPERS_H */
diff --git a/framework/tests/include/test/psa_memory_poisoning_wrappers.h b/framework/tests/include/test/psa_memory_poisoning_wrappers.h
new file mode 100644
index 0000000..3f30b65
--- /dev/null
+++ b/framework/tests/include/test/psa_memory_poisoning_wrappers.h
@@ -0,0 +1,40 @@
+/** Support for memory poisoning wrappers for PSA functions.
+ *
+ *  The wrappers poison the input and output buffers of each function
+ *  before calling it, to ensure that it does not access the buffers
+ *  except by calling the approved buffer-copying functions.
+ *
+ * This header declares support functions. The wrappers themselves are
+ * decalred in the automatically generated file `test/psa_test_wrappers.h`.
+ */
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef PSA_MEMORY_POISONING_WRAPPERS_H
+#define PSA_MEMORY_POISONING_WRAPPERS_H
+
+#include "psa/crypto.h"
+
+#include "test/memory.h"
+
+#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_TEST_MEMORY_CAN_POISON)
+
+/**
+ * \brief         Setup the memory poisoning test hooks used by
+ *                psa_crypto_copy_input() and psa_crypto_copy_output() for
+ *                memory poisoning.
+ */
+void mbedtls_poison_test_hooks_setup(void);
+
+/**
+ * \brief         Teardown the memory poisoning test hooks used by
+ *                psa_crypto_copy_input() and psa_crypto_copy_output() for
+ *                memory poisoning.
+ */
+void mbedtls_poison_test_hooks_teardown(void);
+
+#endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_TEST_MEMORY_CAN_POISON */
+
+#endif /* PSA_MEMORY_POISONING_WRAPPERS_H */
diff --git a/framework/tests/include/test/random.h b/framework/tests/include/test/random.h
new file mode 100644
index 0000000..6304e05
--- /dev/null
+++ b/framework/tests/include/test/random.h
@@ -0,0 +1,91 @@
+/**
+ * \file random.h
+ *
+ * \brief   This file contains the prototypes of helper functions to generate
+ *          random numbers for the purpose of testing.
+ */
+
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef TEST_RANDOM_H
+#define TEST_RANDOM_H
+
+#include "mbedtls/build_info.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+typedef struct {
+    unsigned char *buf; /* Pointer to a buffer of length bytes. */
+    size_t length;
+    /* If fallback_f_rng is NULL, fail after delivering length bytes. */
+    int (*fallback_f_rng)(void *, unsigned char *, size_t);
+    void *fallback_p_rng;
+} mbedtls_test_rnd_buf_info;
+
+/**
+ * Info structure for the pseudo random function
+ *
+ * Key should be set at the start to a test-unique value.
+ * Do not forget endianness!
+ * State( v0, v1 ) should be set to zero.
+ */
+typedef struct {
+    uint32_t key[16];
+    uint32_t v0, v1;
+} mbedtls_test_rnd_pseudo_info;
+
+/**
+ * This function just returns data from rand().
+ * Although predictable and often similar on multiple
+ * runs, this does not result in identical random on
+ * each run. So do not use this if the results of a
+ * test depend on the random data that is generated.
+ *
+ * rng_state shall be NULL.
+ */
+int mbedtls_test_rnd_std_rand(void *rng_state,
+                              unsigned char *output,
+                              size_t len);
+
+/**
+ * This function only returns zeros.
+ *
+ * \p rng_state shall be \c NULL.
+ */
+int mbedtls_test_rnd_zero_rand(void *rng_state,
+                               unsigned char *output,
+                               size_t len);
+
+/**
+ * This function returns random data based on a buffer it receives.
+ *
+ * \p rng_state shall be a pointer to a #mbedtls_test_rnd_buf_info structure.
+ *
+ * The number of bytes released from the buffer on each call to
+ * the random function is specified by \p len.
+ *
+ * After the buffer is empty, this function will call the fallback RNG in the
+ * #mbedtls_test_rnd_buf_info structure if there is one, and
+ * will return #MBEDTLS_ERR_ENTROPY_SOURCE_FAILED otherwise.
+ */
+int mbedtls_test_rnd_buffer_rand(void *rng_state,
+                                 unsigned char *output,
+                                 size_t len);
+
+/**
+ * This function returns random based on a pseudo random function.
+ * This means the results should be identical on all systems.
+ * Pseudo random is based on the XTEA encryption algorithm to
+ * generate pseudorandom.
+ *
+ * \p rng_state shall be a pointer to a #mbedtls_test_rnd_pseudo_info structure.
+ */
+int mbedtls_test_rnd_pseudo_rand(void *rng_state,
+                                 unsigned char *output,
+                                 size_t len);
+
+#endif /* TEST_RANDOM_H */
diff --git a/framework/tests/include/test/threading_helpers.h b/framework/tests/include/test/threading_helpers.h
new file mode 100644
index 0000000..79bc6c0
--- /dev/null
+++ b/framework/tests/include/test/threading_helpers.h
@@ -0,0 +1,112 @@
+/**
+ * \file threading_helpers.h
+ *
+ * \brief This file contains the prototypes of helper functions for the purpose
+ *        of testing threading.
+ */
+
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef THREADING_HELPERS_H
+#define THREADING_HELPERS_H
+
+#if defined MBEDTLS_THREADING_C
+
+#include "mbedtls/private_access.h"
+#include "mbedtls/build_info.h"
+
+/* Most fields of publicly available structs are private and are wrapped with
+ * MBEDTLS_PRIVATE macro. This define allows tests to access the private fields
+ * directly (without using the MBEDTLS_PRIVATE wrapper). */
+#define MBEDTLS_ALLOW_PRIVATE_ACCESS
+
+#define MBEDTLS_ERR_THREADING_THREAD_ERROR                 -0x001F
+
+#if defined(MBEDTLS_THREADING_PTHREAD)
+#include <pthread.h>
+#endif /* MBEDTLS_THREADING_PTHREAD */
+
+#if defined(MBEDTLS_THREADING_ALT)
+/* You should define the mbedtls_test_thread_t type in your header */
+#include "threading_alt.h"
+
+/**
+ * \brief                   Set your alternate threading implementation
+ *                          function pointers for test threads. If used, this
+ *                          function must be called once in the main thread
+ *                          before any other MbedTLS function is called.
+ *
+ * \note                    These functions are part of the testing API only and
+ *                          thus not considered part of the public API of
+ *                          MbedTLS and thus may change without notice.
+ *
+ * \param thread_create     The thread create function implementation.
+ * \param thread_join       The thread join function implementation.
+
+ */
+void mbedtls_test_thread_set_alt(int (*thread_create)(mbedtls_test_thread_t *thread,
+                                                      void *(*thread_func)(
+                                                          void *),
+                                                      void *thread_data),
+                                 int (*thread_join)(mbedtls_test_thread_t *thread));
+
+#else /* MBEDTLS_THREADING_ALT*/
+
+typedef struct mbedtls_test_thread_t {
+
+#if defined(MBEDTLS_THREADING_PTHREAD)
+    pthread_t MBEDTLS_PRIVATE(thread);
+#else /* MBEDTLS_THREADING_PTHREAD */
+    /* Make sure this struct is always non-empty */
+    unsigned dummy;
+#endif
+
+} mbedtls_test_thread_t;
+
+#endif /* MBEDTLS_THREADING_ALT*/
+
+/**
+ * \brief                   The function pointers for thread create and thread
+ *                          join.
+ *
+ * \note                    These functions are part of the testing API only
+ *                          and thus not considered part of the public API of
+ *                          MbedTLS and thus may change without notice.
+ *
+ * \note                    All these functions are expected to work or
+ *                          the result will be undefined.
+ */
+extern int (*mbedtls_test_thread_create)(mbedtls_test_thread_t *thread,
+                                         void *(*thread_func)(void *), void *thread_data);
+extern int (*mbedtls_test_thread_join)(mbedtls_test_thread_t *thread);
+
+#if defined(MBEDTLS_THREADING_PTHREAD) && defined(MBEDTLS_TEST_HOOKS)
+#define MBEDTLS_TEST_MUTEX_USAGE
+#endif
+
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+/**
+ *  Activate the mutex usage verification framework. See threading_helpers.c for
+ *  information.
+ */
+void mbedtls_test_mutex_usage_init(void);
+
+/**
+ *  Deactivate the mutex usage verification framework. See threading_helpers.c
+ *  for information.
+ */
+void mbedtls_test_mutex_usage_end(void);
+
+/**
+ *  Call this function after executing a test case to check for mutex usage
+ * errors.
+ */
+void mbedtls_test_mutex_usage_check(void);
+#endif /* MBEDTLS_TEST_MUTEX_USAGE */
+
+#endif /* MBEDTLS_THREADING_C */
+
+#endif /* THREADING_HELPERS_H */