Merge pull request #9437 from tom-daubney-arm/bp_3-6_standardise_proj_detection

[3.6 Backport] Standardise Project Detection
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 10f4f53..d02b84e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -281,6 +281,15 @@
     endif(CMAKE_COMPILER_IS_IAR)
 endif(MBEDTLS_FATAL_WARNINGS)
 
+if(CMAKE_BUILD_TYPE STREQUAL "Check" AND TEST_CPP)
+    set(CMAKE_CXX_STANDARD 11)
+    set(CMAKE_CXX_STANDARD_REQUIRED ON)
+    set(CMAKE_CXX_EXTENSIONS OFF)
+    if(CMAKE_COMPILER_IS_CLANG OR CMAKE_COMPILER_IS_GNU)
+        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
+    endif()
+endif()
+
 if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
     if(CMAKE_COMPILER_IS_GNU OR CMAKE_COMPILER_IS_CLANG)
         set(CMAKE_SHARED_LINKER_FLAGS "--coverage")
diff --git a/ChangeLog.d/psa_generate_key_custom.txt b/ChangeLog.d/psa_generate_key_custom.txt
new file mode 100644
index 0000000..1695be1
--- /dev/null
+++ b/ChangeLog.d/psa_generate_key_custom.txt
@@ -0,0 +1,14 @@
+API changes
+   * The experimental functions psa_generate_key_ext() and
+     psa_key_derivation_output_key_ext() are no longer declared when compiling
+     in C++. This resolves a build failure under C++ compilers that do not
+     support flexible array members (a C99 feature not adopted by C++).
+     Fixes #9020.
+
+New deprecations
+   * The experimental functions psa_generate_key_ext() and
+     psa_key_derivation_output_key_ext() are deprecated in favor of
+     psa_generate_key_custom() and psa_key_derivation_output_key_custom().
+     They have almost exactly the same interface, but the variable-length
+     data is passed in a separate parameter instead of a flexible array
+     member.
diff --git a/docs/architecture/psa-keystore-design.md b/docs/architecture/psa-keystore-design.md
new file mode 100644
index 0000000..54ba8ac
--- /dev/null
+++ b/docs/architecture/psa-keystore-design.md
@@ -0,0 +1,212 @@
+PSA key store design
+====================
+
+## Introduction
+
+This document describes the architecture of the key storage in memory in the Mbed TLS and TF-PSA-Crypto implementation of the PSA Cryptography API.
+
+In the PSA Cryptography API, cryptographic operations access key materials via a key identifier (key ID for short). Applications must first create a key object, which allocates storage in memory for the key material and metadata. This storage is under the control of the library and may be located in a different memory space such as a trusted execution environment or a secure element.
+
+The storage of persistent keys is out of scope of this document. See the [Mbed Crypto storage specification](mbed-crypto-storage-specification.md).
+
+## Key slot management interface
+
+### Key store and key slots
+
+The **key store** consists of a collection of **key slots**. Each key slot contains the metadata for one key, as well as the key material or a reference to the key material.
+
+A key slot has the type `psa_key_slot_t`. The key store is a global object which is private inside `psa_crypto_slot_management.c`.
+
+### Key slot entry points
+
+The following operations allocate a key slot by calling `psa_reserve_free_key_slot()`:
+
+* **Creating** a key object, through means such as import, random generation, deterministic derivation, copy, or registration of an existing key that is stored in protected hardware (secure element, hardware unique key (HUK)).
+* **Loading** a persistent key from storage, or loading a built-in key. This is done through `psa_get_and_lock_key_slot()`, which calls `psa_reserve_free_key_slot()` and loads the key if applicable.
+
+The following operations free a key slot by calling `psa_wipe_key_slot()` and, if applicable, `psa_free_key_slot()`:
+
+* **Destroying** a key.
+* **Purging** a persistent key from memory, either explicitly at the application's request or to free memory.
+
+Deinitializing the PSA Crypto subsystem with `mbedtls_psa_crypto_free()` destroys all volatile keys and purges all persistent keys.
+
+The library accesses key slots in the following scenarios:
+
+* while the key is being created or loaded;
+* while the key is being destroyed or purged;
+* while the key metadata or key material is being accessed.
+
+### Key slot states
+
+The state of a key slot is indicated by its `state` field of type `psa_key_slot_state_t`, which can be:
+
+* `PSA_SLOT_EMPTY`: a slot that occupies memory but does not currently contain a key.
+* `PSA_SLOT_FILLING`: a slot that is being filled to create or load a key.
+* `PSA_SLOT_FULL`: a slot containing a key.
+* `PSA_SLOT_PENDING_DELETION`: a slot whose key is being destroy or purged.
+
+These states are mostly useful for concurrency. See [Concurrency](#concurrency) below and [key slot states in the PSA thread safety specification](psa-thread-safety/psa-thread-safety.md#key-slot-states).
+
+#### Concurrency
+
+In a multithreaded environment, since Mbed TLS 3.6.0, each key slot is protected by a reader-writer lock. (In earlier versions, the key store was not thread-safe.) The lock is controlled by a single global mutex `mbedtls_threading_psa_globaldata_mutex`. The concurrency state of the slot is indicated by the state and the `registered_readers` field:
+
+* `EMPTY` or `FULL` state, `registered_readers == 0`: the slot is not in use by any thread.
+* `FULL` state, `registered_readers != 0`: the slot is being read.
+* `FILLING` or `PENDING_DELETION` state: the slot is being written.
+
+For more information, see [PSA thread safety](psa-thread-safety/psa-thread-safety.md).
+
+Note that a slot must not be moved in memory while it is being read or written.
+
+## Key slot management implementations
+
+### Key store implementation variants
+
+There are three variants of the key store implementation, responding to different needs.
+
+* Hybrid key store ([static key slots](#static-key-store) with dynamic key data): the key store is a statically allocated array of slots, of size `MBEDTLS_PSA_KEY_SLOT_COUNT`. Key material is allocated on the heap. This is the historical implementation. It remains the default in the Mbed TLS 3.6 long-time support (LTS) branch when using a handwritten `mbedtls_config.h`, as is common on resource-constrained platforms, because the alternatives have tradeoffs (key size limit and larger RAM usage at rest for the static key store, larger code size and more risk due to code complexity for the dynamic key store).
+* Fully [static key store](#static-key-store) (since Mbed TLS 3.6.1): the key store is a statically allocated array of slots, of size `MBEDTLS_PSA_KEY_SLOT_COUNT`. Each key slot contains the key representation directly, and the key representation must be no more than `MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE` bytes. This is intended for very constrained devices that do not have a heap.
+* [Dynamic key store](#dynamic-key-store) (since Mbed TLS 3.6.1): the key store is dynamically allocated as multiple slices on the heap, with a size that adjusts to the application's usage. Key material is allocated on the heap. Compared to the hybrid key store, the code size and RAM consumption are larger. This is intended for higher-end devices where applications are not expected to have a highly predicatable resource usage. This is the default implementation when using the default `mbedtls_config.h` file, as is common on platforms such as Linux, starting with Mbed TLS 3.6.1.
+
+#### Future improvement: merging the key store variants
+
+In the future, we may reduce the number of key store variants to just two, perhaps even one.
+
+We introduced the variants other than the hybrid key store in a patch release of a long-time support version. As a consequence, we wanted to minimize making changes to the default build (when not using the supplied `mbedtls_config.h`, as explained above), to minimize the risk of bugs and the increase in code size. These considerations will not apply in future major or minor releases, so the default key store can change later.
+
+The static key store could become a runtime decision, where only keys larger than some threshold require the use of heap memory. The reasons not to do this in Mbed TLS 3.6.x are that this increases complexity somewhat (slightly more code size, and more risk), and this changes the RAM usage profile somewhat.
+
+A major constraint on the design of the dynamic key store is the need to preserve slot pointers while a slot may be accessed by another thread (see [“Concurrency”](#concurrency)). With the concurrency primitives available in Mbed TLS 3.x, it is very hard to move a key slot in memory, because there could be an indefinite wait until some other thread has finished accessing the slot. This pushed towards the slice-based organisation described below, where each slice is allocated for the long term. In particular, slices cannot be compacted (compacting would be moving slots out of a sparsely-used slice to free it). Better concurrency primitives (e.g. condition variables or semaphores), together with a `realloc()` primitive, could allow freeing unused memory more aggressively, which could make the dynamic key store not detrimental in RAM usage compared to the historical hybrid key store.
+
+#### Slice abstraction
+
+Some parts of the key slot management code use **key slices** as an abstraction. A key slice is an array of key slots. Key slices are identified by an index which is a small non-negative integer.
+
+* With a [static key store](#static-key-store), there is a single, statically allocated slice, with the index 0.
+* With a [dynamic key store](#dynamic-key-store), there is statically allocated array of pointers to key slices. The index of a slice is the index in that array. The slices are allocated on the heap as needed.
+
+#### Key identifiers and slot location
+
+When creating a volatile key, the slice containing the slot and index of the slot in its slice determine the key identifier. When accessing a volatile key, the slice and the slot index in the slice are calculated from the key identifier. The encoding of the slot location in the volatile key identifier is different for a [static](#volatile-key-identifiers-in-the-static-key-store) or [dynamic](#volatile-key-identifiers-in-the-dynamic-key-store) key store.
+
+### Static key store
+
+The static key store is the historical implementation. The key store is a statically allocated array of slots, of size `MBEDTLS_PSA_KEY_SLOT_COUNT`. This value is an upper bound for the total number of volatile keys plus loaded keys.
+
+Since Mbed TLS 3.6.1, there are two variants for the static key store: a hybrid variant (default), and a fully-static variant enabled by the configuration option `MBEDTLS_PSA_STATIC_KEY_SLOTS`. The two variants have the same key store management: the only difference is in how the memory for key data is managed. With fully static key slots, the key data is directly inside the slot, and limited to `MBEDTLS_PSA_KEY_SLOT_BUFFER_SIZE` bytes. With the hybrid key store, the slot contains a pointer to the key data, which is allocated on the heap.
+
+#### Volatile key identifiers in the static key store
+
+For easy lookup, a volatile key whose index is `id` is stored at the index `id - PSA_KEY_ID_VOLATILE_MIN`.
+
+#### Key creation with a static key store
+
+To create a key, `psa_reserve_free_key_slot()` searches the key slot array until it finds one that is empty. If there are none, the code looks for a persistent key that can be purged (see [“Persistent key cache”](#persistent-key-cache)), and purges it. If no slot is free and no slot contains a purgeable key, the key creation fails.
+
+#### Freeing a key slot with a static key store
+
+With a static key store, `psa_wipe_key_slot()` destroys or purges a key by freeing any associated resources, then setting the key slot to the empty state. The slot is then ready for reuse.
+
+### Dynamic key store
+
+The dynamic key store allows a large number of keys, at the expense of more complex memory management.
+
+#### Dynamic key slot performance characteristics
+
+Key management and key access have $O(1)$ amortized performance, and mostly $O(1)$ performance for actions involving keys. More precisely:
+
+* Access to an existing volatile key takes $O(1)$ time.
+* Access to a persistent key (including creation and destruction) takes time that is linear in `MBEDTLS_PSA_KEY_SLOT_COUNT`.
+* Allocating a key takes amortized $O(1)$ time. Usually the time is $O(s)$ where $s$ is the number of slices (which is a hard-coded value less than $30$), but when creating $k$ volatile keys, at most $\log(k)$ creations will involve calls to `calloc()`, totalling $O(k)$ memory.
+* Destroying a volatile key takes $O(1)$ time as of Mbed TLS 3.6.1. Later improvements to memory consumption are likely to involve calls to `free()` which may total $O(k)$ memory where $k$ is the maximum number of volatile keys.
+
+#### Key slices in the dynamic key store
+
+The key slot is organized in slices, which are dynamically arrays of key slot. The number of slices is determined at compile time. The key store contains a static array of pointers to slices.
+
+Volatile keys and loaded keys (persistent or built-in) are stored in separate slices.
+Key slices number 0 to `KEY_SLOT_VOLATILE_SLICE_COUNT - 1` contain only volatile keys.
+One key slice contains only loaded keys: that key slice is thus the cache slice. See [“Persistent key cache”](persistent-key-cache) for how the cache is managed.
+
+#### Volatile key identifiers in the dynamic key store
+
+A volatile key identifier encodes the slice index and the slot index at separate bit positions. That is, `key_id = BASE | slice_index | slot_index` where the bits set in `BASE`, `slice_index` and `slot_index` do not overlap.
+
+#### From key slot to key slice
+
+Some parts of the slot management code need to determine which key slice contains a key slot when given a pointer to the key slot. In principle, the key slice is uniquely determined from the key identifier which is located in the slot:
+
+* for a volatile key identifier, the [slice index is encoded in the key identifier](#volatile-key-identifiers-in-the-dynamic-key-store);
+* for a persistent key identifier or built-in key identifier, [the slot is in the sole cache slice](#key-slices-in-the-dynamic-key-store).
+
+Nonetheless, we store the slice index as a field in the slot, for two reasons:
+
+* It is more robust in case the slice assignment becomes more complex in the future or is somehow buggy.
+* It allows the slot to slice correspondence to work even if the key identifier field has not been filled yet or has been wiped. The implementation in Mbed TLS 3.6.1 requires this because `psa_wipe_key_slot()` wipes the slot, then calls `psa_free_key_slot()`, which needs to determine the slice. Keeping the slice index as a separate field allows us to better separate the concerns of key liveness and slot liveness. A redesign of the internal interfaces could improve this, but would be too disruptive in the 3.6 LTS branch.
+
+#### Length of the volatile key slices
+
+The volatile key slices have exponentially increasing length: each slice is twice as long as the previous one. Thus if the length of slice 0 is `B` and there are `N` slices, then there are `B * (2^N - 1)` slots.
+
+As of Mbed TLS 3.6.1, the maximum number of volatile key slots is less than the theoretical maximum of 2^30 - 2^16 (0x10000000..0x7ffeffff, the largest range of key identifiers reserved for the PSA Crypto implementation that does not overlap the range for built-in keys). The reason is that we limit the slot index to 2^25-1 so that the [encoding of volatile key identifiers](#volatile-key-identifiers-in-the-dynamic-key-store) has 25 bits for the slot index.
+
+When `MBEDTLS_TEST_HOOKS` is enabled, the length of key slices can be overridden. We use this in tests that need to fill the key store.
+
+#### Free list
+
+Each volatile key slice has a **free list**. This is a linked list of all the slots in the slice that are free. The global data contains a static array of free list heads, i.e. the index of a free slot in the slice. Each free slot contains the index of the next free slot in that slice's free list. The end of the list is indicated by an index that is larger than the length of the slice. If the list is empty, the head contains an index that is larger than the length.
+
+As a small optimization, a free slot does not actually contain the index of the next slot, but the index of the next free slot on the list _relative to the next slot in the array_. For example, 0 indicates that the next free slot is the slot immediately after the current slot. This fact is the reason for the encoding: a slice freshly obtained from `calloc` has all of its slots in the free list in order. The value 1 indicates that there is one element between this slot and the next free slot. The next element of the free list can come before the current slot: -2 indicates that it's the slot immediately before, -3 is two slots before, and so on (-1 is impossible). In general, the absolute index of the next slot after slot `i` in the free list is `i + 1 slice[i].next_free_relative_to_next`.
+
+#### Dynamic key slot allocation
+
+To create a volatile key, `psa_reserve_free_key_slot()` searches the free lists of each allocated slice until it finds a slice that is not full. If all allocated slices are full, the code allocates a new slice at the lowest possible slice index. If all possible slices are already allocated and full, the key creation fails.
+
+The newly allocated slot is removed from the slice's free list.
+
+We only allocate a slice of size `B * 2^k` if there are already `B * (2^k - 1)` occupied slots. Thus the memory overhead is at most `B` slots plus the number of occupied slots, i.e. the memory consumption for slots is at most twice the required memory plus a small constant overhead.
+
+#### Dynamic key slot deallocation
+
+When destroying a volatile key, `psa_wipe_key_slot()` calls `psa_free_key_slot()`. This function adds the newly freed slot to the head of the free list.
+
+##### Future improvement: slice deallocation
+
+As of Mbed TLS 3.6.1, `psa_free_key_slot()` does not deallocate slices. Thus the memory consumption for slots never decreases (except when the PSA crypto subsystem is deinitialized). Freeing key slices intelligently would be a desirable improvement.
+
+We should not free a key slice as soon as it becomes empty, because that would cause large allocations and deallocations if there are slices full of long-lived keys, and then one slice keeps being allocate and deallocated for the occasional short-lived keys. Rather, there should be some hysteresis, e.g. only deallocate a slice if there are at least T free slots in the previous slice. [#9435](https://github.com/Mbed-TLS/mbedtls/issues/9435)
+
+Note that currently, the slice array contains one sequence of allocated slices followed by one sequence of unallocated slices. Mixing allocated and unallocated slices may make some parts of the code a little more complex, and should be tested thoroughly.
+
+### Persistent key cache
+
+Persistent keys and built-in keys need to be loaded into the in-memory key store each time they are accessed:
+
+* while creating them;
+* to access their metadata;
+* to start performing an operation with the key;
+* when destroying the key.
+
+To avoid frequent storage access, we cache persistent keys in memory. This cache also applies to built-in keys.
+
+With the [static key store](#static-key-store), a non-empty slot can contain either a volatile key or a cache entry for a persistent or built-in key. With the [dynamic key store](#dynamic-key-store), volatile keys and cached keys are placed in separate [slices](#key-slices-in-the-dynamic-key-store).
+
+The persistent key cache is a fixed-size array of `MBEDTLS_PSA_KEY_SLOT_COUNT` slots. In the static key store, this array is shared with volatile keys. In the dynamic key store, the cache is a separate array that does not contain volatile keys.
+
+#### Accessing a persistent key
+
+`psa_get_and_lock_key_slot()` automatically loads persistent and built-in keys if the specified key identifier is in the corresponding range. To that effect, it traverses the key cache to see if a key with the given identifier is already loaded. If not, it loads the key. This cache walk takes time that is proportional to the cache size.
+
+#### Cache eviction
+
+A key slot must be allocated in the cache slice:
+
+* to create a volatile key (static key store only);
+* to create a persistent key;
+* to load a persistent or built-in key.
+
+If the cache slice is full, the code will try to evict an entry. Only slots that do not have readers can be evicted (see [“Concurrency”](#concurrency)). In the static key store, slots containing volatile keys cannot be evicted.
+
+As of Mbed TLS 3.6.1, there is no tracking of a key's usage frequency or age. The slot eviction code picks the first evictable slot it finds in its traversal order. We have not reasoned about or experimented with different strategies.
diff --git a/docs/psa-transition.md b/docs/psa-transition.md
index bbb7da2..dea14fe 100644
--- a/docs/psa-transition.md
+++ b/docs/psa-transition.md
@@ -779,7 +779,7 @@
 
 The easiest way to create a key pair object is by randomly generating it with [`psa_generate_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5). Compared with the low-level functions from the legacy API (`mbedtls_rsa_gen_key`, `mbedtls_ecp_gen_privkey`, `mbedtls_ecp_gen_keypair`, `mbedtls_ecp_gen_keypair_base`, `mbedtls_ecdsa_genkey`), this directly creates an object that can be used with high-level APIs, but removes some of the flexibility. Note that if you want to export the generated private key, you must pass the flag [`PSA_KEY_USAGE_EXPORT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1ga7dddccdd1303176e87a4d20c87b589ed) to [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de); exporting the public key with [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) is always permitted.
 
-For RSA keys, `psa_generate_key` uses 65537 as the public exponent. You can use [`psa_generate_key_ext`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga6776360ae8046a4456a5f990f997da58) to select a different public exponent. As of Mbed TLS 3.6.0, selecting a different public exponent is only supported with the built-in RSA implementation, not with PSA drivers.
+For RSA keys, `psa_generate_key` uses 65537 as the public exponent. You can use [`psa_generate_key_custom`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#ga0415617443afe42a712027bbb8ad89f0) to select a different public exponent. As of Mbed TLS 3.6.1, selecting a different public exponent is only supported with the built-in RSA implementation, not with PSA drivers.
 
 To create a key object from existing material, use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b). This function has the same basic goal as the PK parse functions (`mbedtls_pk_parse_key`, `mbedtls_pk_parse_public_key`, `mbedtls_pk_parse_subpubkey`), but only supports a single format that just contains the number(s) that make up the key, with very little metadata. The table below summarizes the PSA import/export format for key pairs and public keys; see the documentation of [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) and [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) for more details.
 
diff --git a/framework b/framework
index e8b4ae9..331565b 160000
--- a/framework
+++ b/framework
@@ -1 +1 @@
-Subproject commit e8b4ae9bc4bf7e643ee46bf8ff4ef613be2de86f
+Subproject commit 331565b041f794df2da76394b3b0039abce30355
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 3525da2..16dd038 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -119,8 +119,8 @@
  * value in the structure.
  * The persistent key will be written to storage when the attribute
  * structure is passed to a key creation function such as
- * psa_import_key(), psa_generate_key(), psa_generate_key_ext(),
- * psa_key_derivation_output_key(), psa_key_derivation_output_key_ext()
+ * psa_import_key(), psa_generate_key(), psa_generate_key_custom(),
+ * psa_key_derivation_output_key(), psa_key_derivation_output_key_custom()
  * or psa_copy_key().
  *
  * This function may be declared as `static` (i.e. without external
@@ -164,8 +164,8 @@
  * value in the structure.
  * The persistent key will be written to storage when the attribute
  * structure is passed to a key creation function such as
- * psa_import_key(), psa_generate_key(), psa_generate_key_ext(),
- * psa_key_derivation_output_key(), psa_key_derivation_output_key_ext()
+ * psa_import_key(), psa_generate_key(), psa_generate_key_custom(),
+ * psa_key_derivation_output_key(), psa_key_derivation_output_key_custom()
  * or psa_copy_key().
  *
  * This function may be declared as `static` (i.e. without external
@@ -3234,7 +3234,7 @@
  *    of or after providing inputs. For some algorithms, this step is mandatory
  *    because the output depends on the maximum capacity.
  * -# To derive a key, call psa_key_derivation_output_key() or
- *    psa_key_derivation_output_key_ext().
+ *    psa_key_derivation_output_key_custom().
  *    To derive a byte string for a different purpose, call
  *    psa_key_derivation_output_bytes().
  *    Successive calls to these functions use successive output bytes
@@ -3457,7 +3457,7 @@
  * \note Once all inputs steps are completed, the operations will allow:
  * - psa_key_derivation_output_bytes() if each input was either a direct input
  *   or  a key with #PSA_KEY_USAGE_DERIVE set;
- * - psa_key_derivation_output_key() or psa_key_derivation_output_key_ext()
+ * - psa_key_derivation_output_key() or psa_key_derivation_output_key_custom()
  *   if the input for step
  *   #PSA_KEY_DERIVATION_INPUT_SECRET or #PSA_KEY_DERIVATION_INPUT_PASSWORD
  *   was from a key slot with #PSA_KEY_USAGE_DERIVE and each other input was
@@ -3707,9 +3707,9 @@
  * on the derived key based on the attributes and strength of the secret key.
  *
  * \note This function is equivalent to calling
- *       psa_key_derivation_output_key_ext()
- *       with the production parameters #PSA_KEY_PRODUCTION_PARAMETERS_INIT
- *       and `params_data_length == 0` (i.e. `params->data` is empty).
+ *       psa_key_derivation_output_key_custom()
+ *       with the custom production parameters #PSA_CUSTOM_KEY_PARAMETERS_INIT
+ *       and `custom_data_length == 0` (i.e. `custom_data` is empty).
  *
  * \param[in] attributes    The attributes for the new key.
  *                          If the key type to be created is
@@ -3781,6 +3781,85 @@
  *                          the policy must be the same as in the current
  *                          operation.
  * \param[in,out] operation The key derivation operation object to read from.
+ * \param[in] custom        Customization parameters for the key generation.
+ *                          When this is #PSA_CUSTOM_KEY_PARAMETERS_INIT
+ *                          with \p custom_data_length = 0,
+ *                          this function is equivalent to
+ *                          psa_key_derivation_output_key().
+ * \param[in] custom_data   Variable-length data associated with \c custom.
+ * \param custom_data_length
+ *                          Length of `custom_data` in bytes.
+ * \param[out] key          On success, an identifier for the newly created
+ *                          key. For persistent keys, this is the key
+ *                          identifier defined in \p attributes.
+ *                          \c 0 on failure.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ *         If the key is persistent, the key material and the key's metadata
+ *         have been saved to persistent storage.
+ * \retval #PSA_ERROR_ALREADY_EXISTS
+ *         This is an attempt to create a persistent key, and there is
+ *         already a persistent key with the given identifier.
+ * \retval #PSA_ERROR_INSUFFICIENT_DATA
+ *         There was not enough data to create the desired key.
+ *         Note that in this case, no output is written to the output buffer.
+ *         The operation's capacity is set to 0, thus subsequent calls to
+ *         this function will not succeed, even with a smaller output buffer.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         The key type or key size is not supported, either by the
+ *         implementation in general or in this particular location.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         The provided key attributes are not valid for the operation.
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ *         The #PSA_KEY_DERIVATION_INPUT_SECRET or
+ *         #PSA_KEY_DERIVATION_INPUT_PASSWORD input was not provided through a
+ *         key; or one of the inputs was a key whose policy didn't allow
+ *         #PSA_KEY_USAGE_DERIVE.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_DATA_INVALID \emptydescription
+ * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ *         The operation state is not valid (it must be active and completed
+ *         all required input steps), or the library has not been previously
+ *         initialized by psa_crypto_init().
+ *         It is implementation-dependent whether a failure to initialize
+ *         results in this error code.
+ */
+psa_status_t psa_key_derivation_output_key_custom(
+    const psa_key_attributes_t *attributes,
+    psa_key_derivation_operation_t *operation,
+    const psa_custom_key_parameters_t *custom,
+    const uint8_t *custom_data,
+    size_t custom_data_length,
+    mbedtls_svc_key_id_t *key);
+
+#ifndef __cplusplus
+/* Omitted when compiling in C++, because one of the parameters is a
+ * pointer to a struct with a flexible array member, and that is not
+ * standard C++.
+ * https://github.com/Mbed-TLS/mbedtls/issues/9020
+ */
+/** Derive a key from an ongoing key derivation operation with custom
+ *  production parameters.
+ *
+ * \note
+ * This is a deprecated variant of psa_key_derivation_output_key_custom().
+ * It is equivalent except that the associated variable-length data
+ * is passed in `params->data` instead of a separate parameter.
+ * This function will be removed in a future version of Mbed TLS.
+ *
+ * \param[in] attributes    The attributes for the new key.
+ *                          If the key type to be created is
+ *                          #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in
+ *                          the policy must be the same as in the current
+ *                          operation.
+ * \param[in,out] operation The key derivation operation object to read from.
  * \param[in] params        Customization parameters for the key derivation.
  *                          When this is #PSA_KEY_PRODUCTION_PARAMETERS_INIT
  *                          with \p params_data_length = 0,
@@ -3840,6 +3919,7 @@
     const psa_key_production_parameters_t *params,
     size_t params_data_length,
     mbedtls_svc_key_id_t *key);
+#endif /* !__cplusplus */
 
 /** Compare output data from a key derivation operation to an expected value.
  *
@@ -3927,7 +4007,7 @@
  *                          operation. The value of this key was likely
  *                          computed by a previous call to
  *                          psa_key_derivation_output_key() or
- *                          psa_key_derivation_output_key_ext().
+ *                          psa_key_derivation_output_key_custom().
  *
  * \retval #PSA_SUCCESS \emptydescription
  * \retval #PSA_ERROR_INVALID_SIGNATURE
@@ -4095,9 +4175,9 @@
  *   between 2^{n-1} and 2^n where n is the bit size specified in the
  *   attributes.
  *
- * \note This function is equivalent to calling psa_generate_key_ext()
- *       with the production parameters #PSA_KEY_PRODUCTION_PARAMETERS_INIT
- *       and `params_data_length == 0` (i.e. `params->data` is empty).
+ * \note This function is equivalent to calling psa_generate_key_custom()
+ *       with the custom production parameters #PSA_CUSTOM_KEY_PARAMETERS_INIT
+ *       and `custom_data_length == 0` (i.e. `custom_data` is empty).
  *
  * \param[in] attributes    The attributes for the new key.
  * \param[out] key          On success, an identifier for the newly created
@@ -4137,7 +4217,7 @@
  * See the description of psa_generate_key() for the operation of this
  * function with the default production parameters. In addition, this function
  * supports the following production customizations, described in more detail
- * in the documentation of ::psa_key_production_parameters_t:
+ * in the documentation of ::psa_custom_key_parameters_t:
  *
  * - RSA keys: generation with a custom public exponent.
  *
@@ -4145,6 +4225,64 @@
  *       versions of Mbed TLS.
  *
  * \param[in] attributes    The attributes for the new key.
+ * \param[in] custom        Customization parameters for the key generation.
+ *                          When this is #PSA_CUSTOM_KEY_PARAMETERS_INIT
+ *                          with \p custom_data_length = 0,
+ *                          this function is equivalent to
+ *                          psa_generate_key().
+ * \param[in] custom_data   Variable-length data associated with \c custom.
+ * \param custom_data_length
+ *                          Length of `custom_data` in bytes.
+ * \param[out] key          On success, an identifier for the newly created
+ *                          key. For persistent keys, this is the key
+ *                          identifier defined in \p attributes.
+ *                          \c 0 on failure.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ *         If the key is persistent, the key material and the key's metadata
+ *         have been saved to persistent storage.
+ * \retval #PSA_ERROR_ALREADY_EXISTS
+ *         This is an attempt to create a persistent key, and there is
+ *         already a persistent key with the given identifier.
+ * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
+ * \retval #PSA_ERROR_DATA_INVALID \emptydescription
+ * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ *         The library has not been previously initialized by psa_crypto_init().
+ *         It is implementation-dependent whether a failure to initialize
+ *         results in this error code.
+ */
+psa_status_t psa_generate_key_custom(const psa_key_attributes_t *attributes,
+                                     const psa_custom_key_parameters_t *custom,
+                                     const uint8_t *custom_data,
+                                     size_t custom_data_length,
+                                     mbedtls_svc_key_id_t *key);
+
+#ifndef __cplusplus
+/* Omitted when compiling in C++, because one of the parameters is a
+ * pointer to a struct with a flexible array member, and that is not
+ * standard C++.
+ * https://github.com/Mbed-TLS/mbedtls/issues/9020
+ */
+/**
+ * \brief Generate a key or key pair using custom production parameters.
+ *
+ * \note
+ * This is a deprecated variant of psa_key_derivation_output_key_custom().
+ * It is equivalent except that the associated variable-length data
+ * is passed in `params->data` instead of a separate parameter.
+ * This function will be removed in a future version of Mbed TLS.
+ *
+ * \param[in] attributes    The attributes for the new key.
  * \param[in] params        Customization parameters for the key generation.
  *                          When this is #PSA_KEY_PRODUCTION_PARAMETERS_INIT
  *                          with \p params_data_length = 0,
@@ -4184,6 +4322,7 @@
                                   const psa_key_production_parameters_t *params,
                                   size_t params_data_length,
                                   mbedtls_svc_key_id_t *key);
+#endif /* !__cplusplus */
 
 /**@}*/
 
diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h
index 3913551..362e921 100644
--- a/include/psa/crypto_struct.h
+++ b/include/psa/crypto_struct.h
@@ -223,9 +223,34 @@
     return v;
 }
 
-struct psa_key_production_parameters_s {
+struct psa_custom_key_parameters_s {
     /* Future versions may add other fields in this structure. */
     uint32_t flags;
+};
+
+/** The default production parameters for key generation or key derivation.
+ *
+ * Calling psa_generate_key_custom() or psa_key_derivation_output_key_custom()
+ * with `custom=PSA_CUSTOM_KEY_PARAMETERS_INIT` and `custom_data_length=0` is
+ * equivalent to calling psa_generate_key() or psa_key_derivation_output_key()
+ * respectively.
+ */
+#define PSA_CUSTOM_KEY_PARAMETERS_INIT { 0 }
+
+#ifndef __cplusplus
+/* Omitted when compiling in C++, because one of the parameters is a
+ * pointer to a struct with a flexible array member, and that is not
+ * standard C++.
+ * https://github.com/Mbed-TLS/mbedtls/issues/9020
+ */
+/* This is a deprecated variant of `struct psa_custom_key_parameters_s`.
+ * It has exactly the same layout, plus an extra field which is a flexible
+ * array member. Thus a `const struct psa_key_production_parameters_s *`
+ * can be passed to any function that reads a
+ * `const struct psa_custom_key_parameters_s *`.
+ */
+struct psa_key_production_parameters_s {
+    uint32_t flags;
     uint8_t data[];
 };
 
@@ -238,6 +263,7 @@
  * respectively.
  */
 #define PSA_KEY_PRODUCTION_PARAMETERS_INIT { 0 }
+#endif /* !__cplusplus */
 
 struct psa_key_policy_s {
     psa_key_usage_t MBEDTLS_PRIVATE(usage);
diff --git a/include/psa/crypto_types.h b/include/psa/crypto_types.h
index c21bad8..f831486 100644
--- a/include/psa/crypto_types.h
+++ b/include/psa/crypto_types.h
@@ -457,6 +457,30 @@
 
 /** \brief Custom parameters for key generation or key derivation.
  *
+ * This is a structure type with at least the following field:
+ *
+ * - \c flags: an unsigned integer type. 0 for the default production parameters.
+ *
+ * Functions that take such a structure as input also take an associated
+ * input buffer \c custom_data of length \c custom_data_length.
+ *
+ * The interpretation of this structure and the associated \c custom_data
+ * parameter depend on the type of the created key.
+ *
+ * - #PSA_KEY_TYPE_RSA_KEY_PAIR:
+ *     - \c flags: must be 0.
+ *     - \c custom_data: the public exponent, in little-endian order.
+ *       This must be an odd integer and must not be 1.
+ *       Implementations must support 65537, should support 3 and may
+ *       support other values.
+ *       When not using a driver, Mbed TLS supports values up to \c INT_MAX.
+ *       If this is empty, the default value 65537 is used.
+ * - Other key types: reserved for future use. \c flags must be 0.
+ */
+typedef struct psa_custom_key_parameters_s psa_custom_key_parameters_t;
+
+/** \brief Custom parameters for key generation or key derivation.
+ *
  * This is a structure type with at least the following fields:
  *
  * - \c flags: an unsigned integer type. 0 for the default production parameters.
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 8100afc..1a5658d 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -6412,27 +6412,28 @@
     return status;
 }
 
-static const psa_key_production_parameters_t default_production_parameters =
-    PSA_KEY_PRODUCTION_PARAMETERS_INIT;
+static const psa_custom_key_parameters_t default_custom_production =
+    PSA_CUSTOM_KEY_PARAMETERS_INIT;
 
-int psa_key_production_parameters_are_default(
-    const psa_key_production_parameters_t *params,
-    size_t params_data_length)
+int psa_custom_key_parameters_are_default(
+    const psa_custom_key_parameters_t *custom,
+    size_t custom_data_length)
 {
-    if (params->flags != 0) {
+    if (custom->flags != 0) {
         return 0;
     }
-    if (params_data_length != 0) {
+    if (custom_data_length != 0) {
         return 0;
     }
     return 1;
 }
 
-psa_status_t psa_key_derivation_output_key_ext(
+psa_status_t psa_key_derivation_output_key_custom(
     const psa_key_attributes_t *attributes,
     psa_key_derivation_operation_t *operation,
-    const psa_key_production_parameters_t *params,
-    size_t params_data_length,
+    const psa_custom_key_parameters_t *custom,
+    const uint8_t *custom_data,
+    size_t custom_data_length,
     mbedtls_svc_key_id_t *key)
 {
     psa_status_t status;
@@ -6447,7 +6448,8 @@
         return PSA_ERROR_INVALID_ARGUMENT;
     }
 
-    if (!psa_key_production_parameters_are_default(params, params_data_length)) {
+    (void) custom_data;         /* We only accept 0-length data */
+    if (!psa_custom_key_parameters_are_default(custom, custom_data_length)) {
         return PSA_ERROR_INVALID_ARGUMENT;
     }
 
@@ -6482,14 +6484,29 @@
     return status;
 }
 
+psa_status_t psa_key_derivation_output_key_ext(
+    const psa_key_attributes_t *attributes,
+    psa_key_derivation_operation_t *operation,
+    const psa_key_production_parameters_t *params,
+    size_t params_data_length,
+    mbedtls_svc_key_id_t *key)
+{
+    return psa_key_derivation_output_key_custom(
+        attributes, operation,
+        (const psa_custom_key_parameters_t *) params,
+        params->data, params_data_length,
+        key);
+}
+
 psa_status_t psa_key_derivation_output_key(
     const psa_key_attributes_t *attributes,
     psa_key_derivation_operation_t *operation,
     mbedtls_svc_key_id_t *key)
 {
-    return psa_key_derivation_output_key_ext(attributes, operation,
-                                             &default_production_parameters, 0,
-                                             key);
+    return psa_key_derivation_output_key_custom(attributes, operation,
+                                                &default_custom_production,
+                                                NULL, 0,
+                                                key);
 }
 
 
@@ -7863,15 +7880,18 @@
 
 psa_status_t psa_generate_key_internal(
     const psa_key_attributes_t *attributes,
-    const psa_key_production_parameters_t *params, size_t params_data_length,
+    const psa_custom_key_parameters_t *custom,
+    const uint8_t *custom_data,
+    size_t custom_data_length,
     uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     psa_key_type_t type = attributes->type;
 
     /* Only used for RSA */
-    (void) params;
-    (void) params_data_length;
+    (void) custom;
+    (void) custom_data;
+    (void) custom_data_length;
 
     if (key_type_is_raw_bytes(type)) {
         status = psa_generate_random_internal(key_buffer, key_buffer_size);
@@ -7889,7 +7909,7 @@
 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
     if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
         return mbedtls_psa_rsa_generate_key(attributes,
-                                            params, params_data_length,
+                                            custom_data, custom_data_length,
                                             key_buffer,
                                             key_buffer_size,
                                             key_buffer_length);
@@ -7921,10 +7941,11 @@
     return PSA_SUCCESS;
 }
 
-psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes,
-                                  const psa_key_production_parameters_t *params,
-                                  size_t params_data_length,
-                                  mbedtls_svc_key_id_t *key)
+psa_status_t psa_generate_key_custom(const psa_key_attributes_t *attributes,
+                                     const psa_custom_key_parameters_t *custom,
+                                     const uint8_t *custom_data,
+                                     size_t custom_data_length,
+                                     mbedtls_svc_key_id_t *key)
 {
     psa_status_t status;
     psa_key_slot_t *slot = NULL;
@@ -7946,12 +7967,12 @@
 
 #if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
     if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
-        if (params->flags != 0) {
+        if (custom->flags != 0) {
             return PSA_ERROR_INVALID_ARGUMENT;
         }
     } else
 #endif
-    if (!psa_key_production_parameters_are_default(params, params_data_length)) {
+    if (!psa_custom_key_parameters_are_default(custom, custom_data_length)) {
         return PSA_ERROR_INVALID_ARGUMENT;
     }
 
@@ -7992,7 +8013,8 @@
     }
 
     status = psa_driver_wrapper_generate_key(attributes,
-                                             params, params_data_length,
+                                             custom,
+                                             custom_data, custom_data_length,
                                              slot->key.data, slot->key.bytes,
                                              &slot->key.bytes);
     if (status != PSA_SUCCESS) {
@@ -8010,12 +8032,25 @@
     return status;
 }
 
+psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes,
+                                  const psa_key_production_parameters_t *params,
+                                  size_t params_data_length,
+                                  mbedtls_svc_key_id_t *key)
+{
+    return psa_generate_key_custom(
+        attributes,
+        (const psa_custom_key_parameters_t *) params,
+        params->data, params_data_length,
+        key);
+}
+
 psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
                               mbedtls_svc_key_id_t *key)
 {
-    return psa_generate_key_ext(attributes,
-                                &default_production_parameters, 0,
-                                key);
+    return psa_generate_key_custom(attributes,
+                                   &default_custom_production,
+                                   NULL, 0,
+                                   key);
 }
 
 /****************************************************************/
diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h
index 9462d2e..e7ff151 100644
--- a/library/psa_crypto_core.h
+++ b/library/psa_crypto_core.h
@@ -343,17 +343,18 @@
     const uint8_t *key_buffer, size_t key_buffer_size,
     uint8_t *data, size_t data_size, size_t *data_length);
 
-/** Whether a key production parameters structure is the default.
+/** Whether a key custom production parameters structure is the default.
  *
- * Calls to a key generation driver with non-default production parameters
+ * Calls to a key generation driver with non-default custom production parameters
  * require a driver supporting custom production parameters.
  *
- * \param[in] params            The key production parameters to check.
- * \param params_data_length    Size of `params->data` in bytes.
+ * \param[in] custom            The key custom production parameters to check.
+ * \param custom_data_length    Size of the associated variable-length data
+ *                              in bytes.
  */
-int psa_key_production_parameters_are_default(
-    const psa_key_production_parameters_t *params,
-    size_t params_data_length);
+int psa_custom_key_parameters_are_default(
+    const psa_custom_key_parameters_t *custom,
+    size_t custom_data_length);
 
 /**
  * \brief Generate a key.
@@ -362,9 +363,9 @@
  *       entry point.
  *
  * \param[in]  attributes         The attributes for the key to generate.
- * \param[in]  params             The production parameters from
- *                                psa_generate_key_ext().
- * \param      params_data_length The size of `params->data` in bytes.
+ * \param[in] custom              Custom parameters for the key generation.
+ * \param[in] custom_data         Variable-length data associated with \c custom.
+ * \param custom_data_length      Length of `custom_data` in bytes.
  * \param[out] key_buffer         Buffer where the key data is to be written.
  * \param[in]  key_buffer_size    Size of \p key_buffer in bytes.
  * \param[out] key_buffer_length  On success, the number of bytes written in
@@ -379,8 +380,9 @@
  *         The size of \p key_buffer is too small.
  */
 psa_status_t psa_generate_key_internal(const psa_key_attributes_t *attributes,
-                                       const psa_key_production_parameters_t *params,
-                                       size_t params_data_length,
+                                       const psa_custom_key_parameters_t *custom,
+                                       const uint8_t *custom_data,
+                                       size_t custom_data_length,
                                        uint8_t *key_buffer,
                                        size_t key_buffer_size,
                                        size_t *key_buffer_length);
diff --git a/library/psa_crypto_rsa.c b/library/psa_crypto_rsa.c
index 2f613b3..f8e36d8 100644
--- a/library/psa_crypto_rsa.c
+++ b/library/psa_crypto_rsa.c
@@ -241,7 +241,7 @@
 
 psa_status_t mbedtls_psa_rsa_generate_key(
     const psa_key_attributes_t *attributes,
-    const psa_key_production_parameters_t *params, size_t params_data_length,
+    const uint8_t *custom_data, size_t custom_data_length,
     uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
 {
     psa_status_t status;
@@ -249,8 +249,8 @@
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     int exponent = 65537;
 
-    if (params_data_length != 0) {
-        status = psa_rsa_read_exponent(params->data, params_data_length,
+    if (custom_data_length != 0) {
+        status = psa_rsa_read_exponent(custom_data, custom_data_length,
                                        &exponent);
         if (status != PSA_SUCCESS) {
             return status;
diff --git a/library/psa_crypto_rsa.h b/library/psa_crypto_rsa.h
index ffeef26..1a78000 100644
--- a/library/psa_crypto_rsa.h
+++ b/library/psa_crypto_rsa.h
@@ -105,17 +105,11 @@
 /**
  * \brief Generate an RSA key.
  *
- * \note The signature of the function is that of a PSA driver generate_key
- *       entry point.
- *
  * \param[in]  attributes         The attributes for the RSA key to generate.
- * \param[in]  params             Production parameters for the key
- *                                generation. This function only uses
- *                                `params->data`,
- *                                which contains the public exponent.
+ * \param[in]  custom_data        The public exponent to use.
  *                                This can be a null pointer if
  *                                \c params_data_length is 0.
- * \param params_data_length      Length of `params->data` in bytes.
+ * \param custom_data_length      Length of \p custom_data in bytes.
  *                                This can be 0, in which case the
  *                                public exponent will be 65537.
  * \param[out] key_buffer         Buffer where the key data is to be written.
@@ -132,7 +126,7 @@
  */
 psa_status_t mbedtls_psa_rsa_generate_key(
     const psa_key_attributes_t *attributes,
-    const psa_key_production_parameters_t *params, size_t params_data_length,
+    const uint8_t *custom_data, size_t custom_data_length,
     uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length);
 
 /** Sign an already-calculated hash with an RSA private key.
diff --git a/scripts/common.make b/scripts/common.make
index 9908a3c..439f13d 100644
--- a/scripts/common.make
+++ b/scripts/common.make
@@ -18,7 +18,7 @@
 
 CFLAGS	?= -O2
 WARNING_CFLAGS ?= -Wall -Wextra -Wformat=2 -Wno-format-nonliteral
-WARNING_CXXFLAGS ?= -Wall -Wextra -Wformat=2 -Wno-format-nonliteral
+WARNING_CXXFLAGS ?= -Wall -Wextra -Wformat=2 -Wno-format-nonliteral -std=c++11 -pedantic
 LDFLAGS ?=
 
 LOCAL_CFLAGS = $(WARNING_CFLAGS) -I$(MBEDTLS_TEST_PATH)/include -I$(MBEDTLS_PATH)/include -D_FILE_OFFSET_BITS=64
diff --git a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja
index 8b91f0b..d3b7d6f 100644
--- a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja
+++ b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja
@@ -731,7 +731,8 @@
 
 static inline psa_status_t psa_driver_wrapper_generate_key(
     const psa_key_attributes_t *attributes,
-    const psa_key_production_parameters_t *params, size_t params_data_length,
+    const psa_custom_key_parameters_t *custom,
+    const uint8_t *custom_data, size_t custom_data_length,
     uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length )
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
@@ -740,7 +741,7 @@
 
 #if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
     int is_default_production =
-        psa_key_production_parameters_are_default(params, params_data_length);
+        psa_custom_key_parameters_are_default(custom, custom_data_length);
     if( location != PSA_KEY_LOCATION_LOCAL_STORAGE && !is_default_production )
     {
         /* We don't support passing custom production parameters
@@ -811,7 +812,7 @@
 
             /* Software fallback */
             status = psa_generate_key_internal(
-                attributes, params, params_data_length,
+                attributes, custom, custom_data, custom_data_length,
                 key_buffer, key_buffer_size, key_buffer_length );
             break;
 
diff --git a/tests/include/test/psa_test_wrappers.h b/tests/include/test/psa_test_wrappers.h
index 9551855..134a547 100644
--- a/tests/include/test/psa_test_wrappers.h
+++ b/tests/include/test/psa_test_wrappers.h
@@ -354,6 +354,15 @@
 #define psa_generate_key(arg0_attributes, arg1_key) \
     mbedtls_test_wrap_psa_generate_key(arg0_attributes, arg1_key)
 
+psa_status_t mbedtls_test_wrap_psa_generate_key_custom(
+    const psa_key_attributes_t *arg0_attributes,
+    const psa_custom_key_parameters_t *arg1_custom,
+    const uint8_t *arg2_custom_data,
+    size_t arg3_custom_data_length,
+    mbedtls_svc_key_id_t *arg4_key);
+#define psa_generate_key_custom(arg0_attributes, arg1_custom, arg2_custom_data, arg3_custom_data_length, arg4_key) \
+    mbedtls_test_wrap_psa_generate_key_custom(arg0_attributes, arg1_custom, arg2_custom_data, arg3_custom_data_length, arg4_key)
+
 psa_status_t mbedtls_test_wrap_psa_generate_key_ext(
     const psa_key_attributes_t *arg0_attributes,
     const psa_key_production_parameters_t *arg1_params,
@@ -496,6 +505,16 @@
 #define psa_key_derivation_output_key(arg0_attributes, arg1_operation, arg2_key) \
     mbedtls_test_wrap_psa_key_derivation_output_key(arg0_attributes, arg1_operation, arg2_key)
 
+psa_status_t mbedtls_test_wrap_psa_key_derivation_output_key_custom(
+    const psa_key_attributes_t *arg0_attributes,
+    psa_key_derivation_operation_t *arg1_operation,
+    const psa_custom_key_parameters_t *arg2_custom,
+    const uint8_t *arg3_custom_data,
+    size_t arg4_custom_data_length,
+    mbedtls_svc_key_id_t *arg5_key);
+#define psa_key_derivation_output_key_custom(arg0_attributes, arg1_operation, arg2_custom, arg3_custom_data, arg4_custom_data_length, arg5_key) \
+    mbedtls_test_wrap_psa_key_derivation_output_key_custom(arg0_attributes, arg1_operation, arg2_custom, arg3_custom_data, arg4_custom_data_length, arg5_key)
+
 psa_status_t mbedtls_test_wrap_psa_key_derivation_output_key_ext(
     const psa_key_attributes_t *arg0_attributes,
     psa_key_derivation_operation_t *arg1_operation,
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 10dbe56..1a73020 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -834,7 +834,7 @@
     "$@" scripts/output_env.sh
 }
 
-pre_generate_files() {
+pre_generate_files () {
     # since make doesn't have proper dependencies, remove any possibly outdate
     # file that might be around before generating fresh ones
     make neat
@@ -845,7 +845,7 @@
     fi
 }
 
-clang_version() {
+clang_version () {
     if command -v clang > /dev/null ; then
         clang --version|grep version|sed -E 's#.*version ([0-9]+).*#\1#'
     else
@@ -900,7 +900,7 @@
 
 # Adjust the configuration - for both libtestdriver1 and main library,
 # as they should have the same PSA_WANT macros.
-helper_libtestdriver1_adjust_config() {
+helper_libtestdriver1_adjust_config () {
     base_config=$1
     # Select the base configuration
     if [ "$base_config" != "default" ]; then
@@ -928,7 +928,7 @@
 # When called with no parameter this function disables all builtin curves.
 # The function optionally accepts 1 parameter: a space-separated list of the
 # curves that should be kept enabled.
-helper_disable_builtin_curves() {
+helper_disable_builtin_curves () {
     allowed_list="${1:-}"
     scripts/config.py unset-all "MBEDTLS_ECP_DP_[0-9A-Z_a-z]*_ENABLED"
 
@@ -964,7 +964,7 @@
 # Get the list of uncommented PSA_WANT_KEY_TYPE_xxx_ from CRYPTO_CONFIG_H. This
 # is useful to easily get a list of key type symbols to accelerate.
 # The function accepts a single argument which is the key type: ECC, DH, RSA.
-helper_get_psa_key_type_list() {
+helper_get_psa_key_type_list () {
     key_type="$1"
     loc_list=""
     for item in $(sed -n "s/^#define PSA_WANT_\(KEY_TYPE_${key_type}_[0-9A-Z_a-z]*\).*/\1/p" <"$CRYPTO_CONFIG_H"); do
@@ -984,7 +984,7 @@
 # 1. a space-separated list of things to accelerate;
 # 2. optional: a space-separate list of things to also support.
 # Here "things" are PSA_WANT_ symbols but with PSA_WANT_ removed.
-helper_libtestdriver1_make_drivers() {
+helper_libtestdriver1_make_drivers () {
     loc_accel_flags=$( echo "$1 ${2-}" | sed 's/[^ ]* */-DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_&/g' )
     make CC=$ASAN_CC -C tests libtestdriver1.a CFLAGS=" $ASAN_CFLAGS $loc_accel_flags" LDFLAGS="$ASAN_CFLAGS"
 }
@@ -997,7 +997,7 @@
 # *. remaining arguments if any are passed directly to make
 #    (examples: lib, -C tests test_suite_xxx, etc.)
 # Here "things" are PSA_WANT_ symbols but with PSA_WANT_ removed.
-helper_libtestdriver1_make_main() {
+helper_libtestdriver1_make_main () {
     loc_accel_list=$1
     shift
 
@@ -1007,5448 +1007,11 @@
     make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -I../tests/include -I../tests -I../../tests -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_TEST_LIBTESTDRIVER1 $loc_accel_flags" LDFLAGS="-ltestdriver1 $ASAN_CFLAGS" "$@"
 }
 
-################################################################
-#### Basic checks
-################################################################
-
-#
-# Test Suites to be executed
-#
-# The test ordering tries to optimize for the following criteria:
-# 1. Catch possible problems early, by running first tests that run quickly
-#    and/or are more likely to fail than others (eg I use Clang most of the
-#    time, so start with a GCC build).
-# 2. Minimize total running time, by avoiding useless rebuilds
-#
-# Indicative running times are given for reference.
-
-component_check_recursion () {
-    msg "Check: recursion.pl" # < 1s
-    tests/scripts/recursion.pl library/*.c
-}
-
-component_check_generated_files () {
-    msg "Check: check-generated-files, files generated with make" # 2s
-    make generated_files
-    tests/scripts/check-generated-files.sh
-
-    msg "Check: check-generated-files -u, files present" # 2s
-    tests/scripts/check-generated-files.sh -u
-    # Check that the generated files are considered up to date.
-    tests/scripts/check-generated-files.sh
-
-    msg "Check: check-generated-files -u, files absent" # 2s
-    command make neat
-    tests/scripts/check-generated-files.sh -u
-    # Check that the generated files are considered up to date.
-    tests/scripts/check-generated-files.sh
-
-    # This component ends with the generated files present in the source tree.
-    # This is necessary for subsequent components!
-}
-
-component_check_doxy_blocks () {
-    msg "Check: doxygen markup outside doxygen blocks" # < 1s
-    tests/scripts/check-doxy-blocks.pl
-}
-
-component_check_files () {
-    msg "Check: file sanity checks (permissions, encodings)" # < 1s
-    tests/scripts/check_files.py
-}
-
-component_check_changelog () {
-    msg "Check: changelog entries" # < 1s
-    rm -f ChangeLog.new
-    scripts/assemble_changelog.py -o ChangeLog.new
-    if [ -e ChangeLog.new ]; then
-        # Show the diff for information. It isn't an error if the diff is
-        # non-empty.
-        diff -u ChangeLog ChangeLog.new || true
-        rm ChangeLog.new
-    fi
-}
-
-component_check_names () {
-    msg "Check: declared and exported names (builds the library)" # < 3s
-    tests/scripts/check_names.py -v
-}
-
-component_check_test_cases () {
-    msg "Check: test case descriptions" # < 1s
-    if [ $QUIET -eq 1 ]; then
-        opt='--quiet'
-    else
-        opt=''
-    fi
-    tests/scripts/check_test_cases.py -q $opt
-    unset opt
-}
-
-component_check_test_dependencies () {
-    msg "Check: test case dependencies: legacy vs PSA" # < 1s
-    # The purpose of this component is to catch unjustified dependencies on
-    # legacy feature macros (MBEDTLS_xxx) in PSA tests. Generally speaking,
-    # PSA test should use PSA feature macros (PSA_WANT_xxx, more rarely
-    # MBEDTLS_PSA_xxx).
-    #
-    # Most of the time, use of legacy MBEDTLS_xxx macros are mistakes, which
-    # this component is meant to catch. However a few of them are justified,
-    # mostly by the absence of a PSA equivalent, so this component includes a
-    # list of expected exceptions.
-
-    found="check-test-deps-found-$$"
-    expected="check-test-deps-expected-$$"
-
-    # Find legacy dependencies in PSA tests
-    grep 'depends_on' \
-        tests/suites/test_suite_psa*.data tests/suites/test_suite_psa*.function |
-        grep -Eo '!?MBEDTLS_[^: ]*' |
-        grep -v -e MBEDTLS_PSA_ -e MBEDTLS_TEST_ |
-        sort -u > $found
-
-    # Expected ones with justification - keep in sorted order by ASCII table!
-    rm -f $expected
-    # No PSA equivalent - WANT_KEY_TYPE_AES means all sizes
-    echo "!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH" >> $expected
-    # No PSA equivalent - used to skip decryption tests in PSA-ECB, CBC/XTS/NIST_KW/DES
-    echo "!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT" >> $expected
-    # MBEDTLS_ASN1_WRITE_C is used by import_rsa_made_up() in test_suite_psa_crypto
-    # in order to build a fake RSA key of the wanted size based on
-    # PSA_VENDOR_RSA_MAX_KEY_BITS. The legacy module is only used by
-    # the test code and that's probably the most convenient way of achieving
-    # the test's goal.
-    echo "MBEDTLS_ASN1_WRITE_C" >> $expected
-    # No PSA equivalent - we should probably have one in the future.
-    echo "MBEDTLS_ECP_RESTARTABLE" >> $expected
-    # No PSA equivalent - needed by some init tests
-    echo "MBEDTLS_ENTROPY_NV_SEED" >> $expected
-    # No PSA equivalent - required to run threaded tests.
-    echo "MBEDTLS_THREADING_PTHREAD" >> $expected
-
-    # Compare reality with expectation.
-    # We want an exact match, to ensure the above list remains up-to-date.
-    #
-    # The output should be empty. When it's not:
-    # - Each '+' line is a macro that was found but not expected. You want to
-    # find where that macro occurs, and either replace it with PSA macros, or
-    # add it to the exceptions list above with a justification.
-    # - Each '-' line is a macro that was expected but not found; it means the
-    # exceptions list above should be updated by removing that macro.
-    diff -U0 $expected $found
-
-    rm $found $expected
-}
-
-component_check_doxygen_warnings () {
-    msg "Check: doxygen warnings (builds the documentation)" # ~ 3s
-    tests/scripts/doxygen.sh
-}
-
-
-
-################################################################
-#### Build and test many configurations and targets
-################################################################
-
-component_test_default_out_of_box () {
-    msg "build: make, default config (out-of-box)" # ~1min
-    make
-    # Disable fancy stuff
-    unset MBEDTLS_TEST_OUTCOME_FILE
-
-    msg "test: main suites make, default config (out-of-box)" # ~10s
-    make test
-
-    msg "selftest: make, default config (out-of-box)" # ~10s
-    programs/test/selftest
-
-    msg "program demos: make, default config (out-of-box)" # ~10s
-    tests/scripts/run_demos.py
-}
-
-component_test_default_cmake_gcc_asan () {
-    msg "build: cmake, gcc, ASan" # ~ 1 min 50s
-    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: main suites (inc. selftests) (ASan build)" # ~ 50s
-    make test
-
-    msg "program demos (ASan build)" # ~10s
-    tests/scripts/run_demos.py
-
-    msg "test: selftest (ASan build)" # ~ 10s
-    programs/test/selftest
-
-    msg "test: metatests (GCC, ASan build)"
-    tests/scripts/run-metatests.sh any asan poison
-
-    msg "test: ssl-opt.sh (ASan build)" # ~ 1 min
-    tests/ssl-opt.sh
-
-    msg "test: compat.sh (ASan build)" # ~ 6 min
-    tests/compat.sh
-
-    msg "test: context-info.sh (ASan build)" # ~ 15 sec
-    tests/context-info.sh
-}
-
-component_test_default_cmake_gcc_asan_new_bignum () {
-    msg "build: cmake, gcc, ASan" # ~ 1 min 50s
-    scripts/config.py set MBEDTLS_ECP_WITH_MPI_UINT
-    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: main suites (inc. selftests) (ASan build)" # ~ 50s
-    make test
-
-    msg "test: selftest (ASan build)" # ~ 10s
-    programs/test/selftest
-
-    msg "test: ssl-opt.sh (ASan build)" # ~ 1 min
-    tests/ssl-opt.sh
-
-    msg "test: compat.sh (ASan build)" # ~ 6 min
-    tests/compat.sh
-
-    msg "test: context-info.sh (ASan build)" # ~ 15 sec
-    tests/context-info.sh
-}
-
-component_test_full_cmake_gcc_asan () {
-    msg "build: full config, cmake, gcc, ASan"
-    scripts/config.py full
-    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: main suites (inc. selftests) (full config, ASan build)"
-    make test
-
-    msg "test: selftest (full config, ASan build)" # ~ 10s
-    programs/test/selftest
-
-    msg "test: ssl-opt.sh (full config, ASan build)"
-    tests/ssl-opt.sh
-
-    # Note: the next two invocations cover all compat.sh test cases.
-    # We should use the same here and in basic-build-test.sh.
-    msg "test: compat.sh: default version (full config, ASan build)"
-    tests/compat.sh -e 'ARIA\|CHACHA'
-
-    msg "test: compat.sh: next: ARIA, Chacha (full config, ASan build)"
-    env OPENSSL="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA'
-
-    msg "test: context-info.sh (full config, ASan build)" # ~ 15 sec
-    tests/context-info.sh
-}
-
-
-component_test_full_cmake_gcc_asan_new_bignum () {
-    msg "build: full config, cmake, gcc, ASan"
-    scripts/config.py full
-    scripts/config.py set MBEDTLS_ECP_WITH_MPI_UINT
-    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: main suites (inc. selftests) (full config, new bignum, ASan)"
-    make test
-
-    msg "test: selftest (full config, new bignum, ASan)" # ~ 10s
-    programs/test/selftest
-
-    msg "test: ssl-opt.sh (full config, new bignum, ASan)"
-    tests/ssl-opt.sh
-
-    # Note: the next two invocations cover all compat.sh test cases.
-    # We should use the same here and in basic-build-test.sh.
-    msg "test: compat.sh: default version (full config, new bignum, ASan)"
-    tests/compat.sh -e 'ARIA\|CHACHA'
-
-    msg "test: compat.sh: next: ARIA, Chacha (full config, new bignum, ASan)"
-    env OPENSSL="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA'
-
-    msg "test: context-info.sh (full config, new bignum, ASan)" # ~ 15 sec
-    tests/context-info.sh
-}
-
-component_test_psa_crypto_key_id_encodes_owner () {
-    msg "build: full config + PSA_CRYPTO_KEY_ID_ENCODES_OWNER, cmake, gcc, ASan"
-    scripts/config.py full
-    scripts/config.py set MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
-    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: full config - USE_PSA_CRYPTO + PSA_CRYPTO_KEY_ID_ENCODES_OWNER, cmake, gcc, ASan"
-    make test
-}
-
-component_test_psa_assume_exclusive_buffers () {
-    msg "build: full config + MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS, cmake, gcc, ASan"
-    scripts/config.py full
-    scripts/config.py set MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS
-    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: full config + MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS, cmake, gcc, ASan"
-    make test
-}
-
-# check_renamed_symbols HEADER LIB
-# Check that if HEADER contains '#define MACRO ...' then MACRO is not a symbol
-# name is LIB.
-check_renamed_symbols () {
-    ! nm "$2" | sed 's/.* //' |
-      grep -x -F "$(sed -n 's/^ *# *define  *\([A-Z_a-z][0-9A-Z_a-z]*\)..*/\1/p' "$1")"
-}
-
-component_build_psa_crypto_spm () {
-    msg "build: full config + PSA_CRYPTO_KEY_ID_ENCODES_OWNER + PSA_CRYPTO_SPM, make, gcc"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS
-    scripts/config.py set MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
-    scripts/config.py set MBEDTLS_PSA_CRYPTO_SPM
-    # We can only compile, not link, since our test and sample programs
-    # aren't equipped for the modified names used when MBEDTLS_PSA_CRYPTO_SPM
-    # is active.
-    make CC=gcc CFLAGS='-Werror -Wall -Wextra -I../tests/include/spe' lib
-
-    # Check that if a symbol is renamed by crypto_spe.h, the non-renamed
-    # version is not present.
-    echo "Checking for renamed symbols in the library"
-    check_renamed_symbols tests/include/spe/crypto_spe.h library/libmbedcrypto.a
-}
-
-# Get a list of library-wise undefined symbols and ensure that they only
-# belong to psa_xxx() functions and not to mbedtls_yyy() ones.
-# This function is a common helper used by both:
-# - component_test_default_psa_crypto_client_without_crypto_provider
-# - component_build_full_psa_crypto_client_without_crypto_provider.
-common_check_mbedtls_missing_symbols() {
-    nm library/libmbedcrypto.a | grep ' [TRrDC] ' | grep -Eo '(mbedtls_|psa_).*' | sort -u > sym_def.txt
-    nm library/libmbedcrypto.a | grep ' U ' | grep -Eo '(mbedtls_|psa_).*' | sort -u > sym_undef.txt
-    comm sym_def.txt sym_undef.txt -13 > linking_errors.txt
-    not grep mbedtls_ linking_errors.txt
-
-    rm sym_def.txt sym_undef.txt linking_errors.txt
-}
-
-component_test_default_psa_crypto_client_without_crypto_provider () {
-    msg "build: default config - PSA_CRYPTO_C + PSA_CRYPTO_CLIENT"
-
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_C
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C
-    scripts/config.py unset MBEDTLS_PSA_ITS_FILE_C
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    scripts/config.py set MBEDTLS_PSA_CRYPTO_CLIENT
-    scripts/config.py unset MBEDTLS_LMS_C
-
-    make
-
-    msg "check missing symbols: default config - PSA_CRYPTO_C + PSA_CRYPTO_CLIENT"
-    common_check_mbedtls_missing_symbols
-
-    msg "test: default config - PSA_CRYPTO_C + PSA_CRYPTO_CLIENT"
-    make test
-}
-
-component_build_full_psa_crypto_client_without_crypto_provider () {
-    msg "build: full config - PSA_CRYPTO_C"
-
-    # Use full config which includes USE_PSA and CRYPTO_CLIENT.
-    scripts/config.py full
-
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_C
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C
-    # Dynamic secure element support is a deprecated feature and it is not
-    # available when CRYPTO_C and PSA_CRYPTO_STORAGE_C are disabled.
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
-
-    # Since there is no crypto provider in this build it is not possible to
-    # build all the test executables and progrems due to missing PSA functions
-    # at link time. Therefore we will just build libraries and we'll check
-    # that symbols of interest are there.
-    make lib
-
-    msg "check missing symbols: full config - PSA_CRYPTO_C"
-
-    common_check_mbedtls_missing_symbols
-
-    # Ensure that desired functions are included into the build (extend the
-    # following list as required).
-    grep mbedtls_pk_get_psa_attributes library/libmbedcrypto.a
-    grep mbedtls_pk_import_into_psa library/libmbedcrypto.a
-    grep mbedtls_pk_copy_from_psa library/libmbedcrypto.a
-}
-
-component_test_psa_crypto_rsa_no_genprime() {
-    msg "build: default config minus MBEDTLS_GENPRIME"
-    scripts/config.py unset MBEDTLS_GENPRIME
-    make
-
-    msg "test: default config minus MBEDTLS_GENPRIME"
-    make test
-}
-
-component_test_ref_configs () {
-    msg "test/build: ref-configs (ASan build)" # ~ 6 min 20s
-    # test-ref-configs works by overwriting mbedtls_config.h; this makes cmake
-    # want to re-generate generated files that depend on it, quite correctly.
-    # However this doesn't work as the generation script expects a specific
-    # format for mbedtls_config.h, which the other files don't follow. Also,
-    # cmake can't know this, but re-generation is actually not necessary as
-    # the generated files only depend on the list of available options, not
-    # whether they're on or off. So, disable cmake's (over-sensitive here)
-    # dependency resolution for generated files and just rely on them being
-    # present (thanks to pre_generate_files) by turning GEN_FILES off.
-    CC=$ASAN_CC cmake -D GEN_FILES=Off -D CMAKE_BUILD_TYPE:String=Asan .
-    tests/scripts/test-ref-configs.pl
-}
-
-component_test_no_renegotiation () {
-    msg "build: Default + !MBEDTLS_SSL_RENEGOTIATION (ASan build)" # ~ 6 min
-    scripts/config.py unset MBEDTLS_SSL_RENEGOTIATION
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: !MBEDTLS_SSL_RENEGOTIATION - main suites (inc. selftests) (ASan build)" # ~ 50s
-    make test
-
-    msg "test: !MBEDTLS_SSL_RENEGOTIATION - ssl-opt.sh (ASan build)" # ~ 6 min
-    tests/ssl-opt.sh
-}
-
-component_test_no_pem_no_fs () {
-    msg "build: Default + !MBEDTLS_PEM_PARSE_C + !MBEDTLS_FS_IO (ASan build)"
-    scripts/config.py unset MBEDTLS_PEM_PARSE_C
-    scripts/config.py unset MBEDTLS_FS_IO
-    scripts/config.py unset MBEDTLS_PSA_ITS_FILE_C # requires a filesystem
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C # requires PSA ITS
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: !MBEDTLS_PEM_PARSE_C !MBEDTLS_FS_IO - main suites (inc. selftests) (ASan build)" # ~ 50s
-    make test
-
-    msg "test: !MBEDTLS_PEM_PARSE_C !MBEDTLS_FS_IO - ssl-opt.sh (ASan build)" # ~ 6 min
-    tests/ssl-opt.sh
-}
-
-component_test_rsa_no_crt () {
-    msg "build: Default + RSA_NO_CRT (ASan build)" # ~ 6 min
-    scripts/config.py set MBEDTLS_RSA_NO_CRT
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: RSA_NO_CRT - main suites (inc. selftests) (ASan build)" # ~ 50s
-    make test
-
-    msg "test: RSA_NO_CRT - RSA-related part of ssl-opt.sh (ASan build)" # ~ 5s
-    tests/ssl-opt.sh -f RSA
-
-    msg "test: RSA_NO_CRT - RSA-related part of compat.sh (ASan build)" # ~ 3 min
-    tests/compat.sh -t RSA
-
-    msg "test: RSA_NO_CRT - RSA-related part of context-info.sh (ASan build)" # ~ 15 sec
-    tests/context-info.sh
-}
-
-component_test_no_ctr_drbg_classic () {
-    msg "build: Full minus CTR_DRBG, classic crypto in TLS"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_CTR_DRBG_C
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: Full minus CTR_DRBG, classic crypto - main suites"
-    make test
-
-    # In this configuration, the TLS test programs use HMAC_DRBG.
-    # The SSL tests are slow, so run a small subset, just enough to get
-    # confidence that the SSL code copes with HMAC_DRBG.
-    msg "test: Full minus CTR_DRBG, classic crypto - ssl-opt.sh (subset)"
-    tests/ssl-opt.sh -f 'Default\|SSL async private.*delay=\|tickets enabled on server'
-
-    msg "test: Full minus CTR_DRBG, classic crypto - compat.sh (subset)"
-    tests/compat.sh -m tls12 -t 'ECDSA PSK' -V NO -p OpenSSL
-}
-
-component_test_no_ctr_drbg_use_psa () {
-    msg "build: Full minus CTR_DRBG, PSA crypto in TLS"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_CTR_DRBG_C
-    scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
-
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: Full minus CTR_DRBG, USE_PSA_CRYPTO - main suites"
-    make test
-
-    # In this configuration, the TLS test programs use HMAC_DRBG.
-    # The SSL tests are slow, so run a small subset, just enough to get
-    # confidence that the SSL code copes with HMAC_DRBG.
-    msg "test: Full minus CTR_DRBG, USE_PSA_CRYPTO - ssl-opt.sh (subset)"
-    tests/ssl-opt.sh -f 'Default\|SSL async private.*delay=\|tickets enabled on server'
-
-    msg "test: Full minus CTR_DRBG, USE_PSA_CRYPTO - compat.sh (subset)"
-    tests/compat.sh -m tls12 -t 'ECDSA PSK' -V NO -p OpenSSL
-}
-
-component_test_no_hmac_drbg_classic () {
-    msg "build: Full minus HMAC_DRBG, classic crypto in TLS"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_HMAC_DRBG_C
-    scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC # requires HMAC_DRBG
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: Full minus HMAC_DRBG, classic crypto - main suites"
-    make test
-
-    # Normally our ECDSA implementation uses deterministic ECDSA. But since
-    # HMAC_DRBG is disabled in this configuration, randomized ECDSA is used
-    # instead.
-    # Test SSL with non-deterministic ECDSA. Only test features that
-    # might be affected by how ECDSA signature is performed.
-    msg "test: Full minus HMAC_DRBG, classic crypto - ssl-opt.sh (subset)"
-    tests/ssl-opt.sh -f 'Default\|SSL async private: sign'
-
-    # To save time, only test one protocol version, since this part of
-    # the protocol is identical in (D)TLS up to 1.2.
-    msg "test: Full minus HMAC_DRBG, classic crypto - compat.sh (ECDSA)"
-    tests/compat.sh -m tls12 -t 'ECDSA'
-}
-
-component_test_no_hmac_drbg_use_psa () {
-    msg "build: Full minus HMAC_DRBG, PSA crypto in TLS"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_HMAC_DRBG_C
-    scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC # requires HMAC_DRBG
-    scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
-
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: Full minus HMAC_DRBG, USE_PSA_CRYPTO - main suites"
-    make test
-
-    # Normally our ECDSA implementation uses deterministic ECDSA. But since
-    # HMAC_DRBG is disabled in this configuration, randomized ECDSA is used
-    # instead.
-    # Test SSL with non-deterministic ECDSA. Only test features that
-    # might be affected by how ECDSA signature is performed.
-    msg "test: Full minus HMAC_DRBG, USE_PSA_CRYPTO - ssl-opt.sh (subset)"
-    tests/ssl-opt.sh -f 'Default\|SSL async private: sign'
-
-    # To save time, only test one protocol version, since this part of
-    # the protocol is identical in (D)TLS up to 1.2.
-    msg "test: Full minus HMAC_DRBG, USE_PSA_CRYPTO - compat.sh (ECDSA)"
-    tests/compat.sh -m tls12 -t 'ECDSA'
-}
-
-component_test_psa_external_rng_no_drbg_classic () {
-    msg "build: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG, classic crypto in TLS"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    scripts/config.py set MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
-    scripts/config.py unset MBEDTLS_ENTROPY_C
-    scripts/config.py unset MBEDTLS_ENTROPY_NV_SEED
-    scripts/config.py unset MBEDTLS_PLATFORM_NV_SEED_ALT
-    scripts/config.py unset MBEDTLS_CTR_DRBG_C
-    scripts/config.py unset MBEDTLS_HMAC_DRBG_C
-    scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC # requires HMAC_DRBG
-    # When MBEDTLS_USE_PSA_CRYPTO is disabled and there is no DRBG,
-    # the SSL test programs don't have an RNG and can't work. Explicitly
-    # make them use the PSA RNG with -DMBEDTLS_TEST_USE_PSA_CRYPTO_RNG.
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DMBEDTLS_TEST_USE_PSA_CRYPTO_RNG" LDFLAGS="$ASAN_CFLAGS"
-
-    msg "test: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG, classic crypto - main suites"
-    make test
-
-    msg "test: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG, classic crypto - ssl-opt.sh (subset)"
-    tests/ssl-opt.sh -f 'Default'
-}
-
-component_test_psa_external_rng_no_drbg_use_psa () {
-    msg "build: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG, PSA crypto in TLS"
-    scripts/config.py full
-    scripts/config.py set MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
-    scripts/config.py unset MBEDTLS_ENTROPY_C
-    scripts/config.py unset MBEDTLS_ENTROPY_NV_SEED
-    scripts/config.py unset MBEDTLS_PLATFORM_NV_SEED_ALT
-    scripts/config.py unset MBEDTLS_CTR_DRBG_C
-    scripts/config.py unset MBEDTLS_HMAC_DRBG_C
-    scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC # requires HMAC_DRBG
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
-
-    msg "test: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG, PSA crypto - main suites"
-    make test
-
-    msg "test: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG, PSA crypto - ssl-opt.sh (subset)"
-    tests/ssl-opt.sh -f 'Default\|opaque'
-}
-
-component_test_psa_external_rng_use_psa_crypto () {
-    msg "build: full + PSA_CRYPTO_EXTERNAL_RNG + USE_PSA_CRYPTO minus CTR_DRBG"
-    scripts/config.py full
-    scripts/config.py set MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
-    scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_CTR_DRBG_C
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
-
-    msg "test: full + PSA_CRYPTO_EXTERNAL_RNG + USE_PSA_CRYPTO minus CTR_DRBG"
-    make test
-
-    msg "test: full + PSA_CRYPTO_EXTERNAL_RNG + USE_PSA_CRYPTO minus CTR_DRBG"
-    tests/ssl-opt.sh -f 'Default\|opaque'
-}
-
-component_test_psa_inject_entropy () {
-    msg "build: full + MBEDTLS_PSA_INJECT_ENTROPY"
-    scripts/config.py full
-    scripts/config.py set MBEDTLS_PSA_INJECT_ENTROPY
-    scripts/config.py set MBEDTLS_ENTROPY_NV_SEED
-    scripts/config.py set MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
-    scripts/config.py unset MBEDTLS_PLATFORM_NV_SEED_ALT
-    scripts/config.py unset MBEDTLS_PLATFORM_STD_NV_SEED_READ
-    scripts/config.py unset MBEDTLS_PLATFORM_STD_NV_SEED_WRITE
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS '-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/user-config-for-test.h\"'" LDFLAGS="$ASAN_CFLAGS"
-
-    msg "test: full + MBEDTLS_PSA_INJECT_ENTROPY"
-    make test
-}
-
-component_test_sw_inet_pton () {
-    msg "build: default plus MBEDTLS_TEST_SW_INET_PTON"
-
-    # MBEDTLS_TEST_HOOKS required for x509_crt_parse_cn_inet_pton
-    scripts/config.py set MBEDTLS_TEST_HOOKS
-    make CFLAGS="-DMBEDTLS_TEST_SW_INET_PTON"
-
-    msg "test: default plus MBEDTLS_TEST_SW_INET_PTON"
-    make test
-}
-
-component_full_no_pkparse_pkwrite() {
-    msg "build: full without pkparse and pkwrite"
-
-    scripts/config.py crypto_full
-    scripts/config.py unset MBEDTLS_PK_PARSE_C
-    scripts/config.py unset MBEDTLS_PK_WRITE_C
-
-    make CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
-
-    # Ensure that PK_[PARSE|WRITE]_C were not re-enabled accidentally (additive config).
-    not grep mbedtls_pk_parse_key library/pkparse.o
-    not grep mbedtls_pk_write_key_der library/pkwrite.o
-
-    msg "test: full without pkparse and pkwrite"
-    make test
-}
-
-component_test_crypto_full_md_light_only () {
-    msg "build: crypto_full with only the light subset of MD"
-    scripts/config.py crypto_full
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_CONFIG
-    # Disable MD
-    scripts/config.py unset MBEDTLS_MD_C
-    # Disable direct dependencies of MD_C
-    scripts/config.py unset MBEDTLS_HKDF_C
-    scripts/config.py unset MBEDTLS_HMAC_DRBG_C
-    scripts/config.py unset MBEDTLS_PKCS7_C
-    # Disable indirect dependencies of MD_C
-    scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC # needs HMAC_DRBG
-    # Disable things that would auto-enable MD_C
-    scripts/config.py unset MBEDTLS_PKCS5_C
-
-    # Note: MD-light is auto-enabled in build_info.h by modules that need it,
-    # which we haven't disabled, so no need to explicitly enable it.
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
-
-    # Make sure we don't have the HMAC functions, but the hashing functions
-    not grep mbedtls_md_hmac library/md.o
-    grep mbedtls_md library/md.o
-
-    msg "test: crypto_full with only the light subset of MD"
-    make test
-}
-
-component_test_full_no_cipher_no_psa_crypto () {
-    msg "build: full no CIPHER no PSA_CRYPTO_C"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_CIPHER_C
-    # Don't pull in cipher via PSA mechanisms
-    # (currently ignored anyway because we completely disable PSA)
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_CONFIG
-    # Disable features that depend on CIPHER_C
-    scripts/config.py unset MBEDTLS_CMAC_C
-    scripts/config.py unset MBEDTLS_NIST_KW_C
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_C
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_CLIENT
-    scripts/config.py unset MBEDTLS_SSL_TLS_C
-    scripts/config.py unset MBEDTLS_SSL_TICKET_C
-    # Disable features that depend on PSA_CRYPTO_C
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_LMS_C
-    scripts/config.py unset MBEDTLS_LMS_PRIVATE
-
-    msg "test: full no CIPHER no PSA_CRYPTO_C"
-    make test
-}
-
-# This is a common configurator and test function that is used in:
-# - component_test_full_no_cipher_with_psa_crypto
-# - component_test_full_no_cipher_with_psa_crypto_config
-# It accepts 2 input parameters:
-# - $1: boolean value which basically reflects status of MBEDTLS_PSA_CRYPTO_CONFIG
-# - $2: a text string which describes the test component
-common_test_full_no_cipher_with_psa_crypto () {
-    USE_CRYPTO_CONFIG="$1"
-    COMPONENT_DESCRIPTION="$2"
-
-    msg "build: $COMPONENT_DESCRIPTION"
-
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_CIPHER_C
-
-    if [ "$USE_CRYPTO_CONFIG" -eq 1 ]; then
-        # The built-in implementation of the following algs/key-types depends
-        # on CIPHER_C so we disable them.
-        # This does not hold for KEY_TYPE_CHACHA20 and ALG_CHACHA20_POLY1305
-        # so we keep them enabled.
-        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_CCM_STAR_NO_TAG
-        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_CMAC
-        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_CBC_NO_PADDING
-        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_CBC_PKCS7
-        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_CFB
-        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_CTR
-        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_ECB_NO_PADDING
-        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_OFB
-        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128
-        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_STREAM_CIPHER
-        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_KEY_TYPE_DES
-    else
-        # Don't pull in cipher via PSA mechanisms
-        scripts/config.py unset MBEDTLS_PSA_CRYPTO_CONFIG
-        # Disable cipher modes/keys that make PSA depend on CIPHER_C.
-        # Keep CHACHA20 and CHACHAPOLY enabled since they do not depend on CIPHER_C.
-        scripts/config.py unset-all MBEDTLS_CIPHER_MODE
-    fi
-    # The following modules directly depends on CIPHER_C
-    scripts/config.py unset MBEDTLS_CMAC_C
-    scripts/config.py unset MBEDTLS_NIST_KW_C
-
-    make
-
-    # Ensure that CIPHER_C was not re-enabled
-    not grep mbedtls_cipher_init library/cipher.o
-
-    msg "test: $COMPONENT_DESCRIPTION"
-    make test
-}
-
-component_test_full_no_cipher_with_psa_crypto() {
-    common_test_full_no_cipher_with_psa_crypto 0 "full no CIPHER no CRYPTO_CONFIG"
-}
-
-component_test_full_no_cipher_with_psa_crypto_config() {
-    common_test_full_no_cipher_with_psa_crypto 1 "full no CIPHER"
-}
-
-component_test_full_no_ccm() {
-    msg "build: full no PSA_WANT_ALG_CCM"
-
-    # Full config enables:
-    # - USE_PSA_CRYPTO so that TLS code dispatches cipher/AEAD to PSA
-    # - CRYPTO_CONFIG so that PSA_WANT config symbols are evaluated
-    scripts/config.py full
-
-    # Disable PSA_WANT_ALG_CCM so that CCM is not supported in PSA. CCM_C is still
-    # enabled, but not used from TLS since USE_PSA is set.
-    # This is helpful to ensure that TLS tests below have proper dependencies.
-    #
-    # Note: also PSA_WANT_ALG_CCM_STAR_NO_TAG is enabled, but it does not cause
-    # PSA_WANT_ALG_CCM to be re-enabled.
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CCM
-
-    make
-
-    msg "test: full no PSA_WANT_ALG_CCM"
-    make test
-}
-
-component_test_full_no_ccm_star_no_tag() {
-    msg "build: full no PSA_WANT_ALG_CCM_STAR_NO_TAG"
-
-    # Full config enables CRYPTO_CONFIG so that PSA_WANT config symbols are evaluated
-    scripts/config.py full
-
-    # Disable CCM_STAR_NO_TAG, which is the target of this test, as well as all
-    # other components that enable MBEDTLS_PSA_BUILTIN_CIPHER internal symbol.
-    # This basically disables all unauthenticated ciphers on the PSA side, while
-    # keeping AEADs enabled.
-    #
-    # Note: PSA_WANT_ALG_CCM is enabled, but it does not cause
-    # PSA_WANT_ALG_CCM_STAR_NO_TAG to be re-enabled.
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CCM_STAR_NO_TAG
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_STREAM_CIPHER
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CTR
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CFB
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_OFB
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_ECB_NO_PADDING
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_NO_PADDING
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_PKCS7
-
-    make
-
-    # Ensure MBEDTLS_PSA_BUILTIN_CIPHER was not enabled
-    not grep mbedtls_psa_cipher library/psa_crypto_cipher.o
-
-    msg "test: full no PSA_WANT_ALG_CCM_STAR_NO_TAG"
-    make test
-}
-
-component_test_full_no_bignum () {
-    msg "build: full minus bignum"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_BIGNUM_C
-    # Direct dependencies of bignum
-    scripts/config.py unset MBEDTLS_ECP_C
-    scripts/config.py unset MBEDTLS_RSA_C
-    scripts/config.py unset MBEDTLS_DHM_C
-    # Direct dependencies of ECP
-    scripts/config.py unset MBEDTLS_ECDH_C
-    scripts/config.py unset MBEDTLS_ECDSA_C
-    scripts/config.py unset MBEDTLS_ECJPAKE_C
-    scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
-    # Disable what auto-enables ECP_LIGHT
-    scripts/config.py unset MBEDTLS_PK_PARSE_EC_EXTENDED
-    scripts/config.py unset MBEDTLS_PK_PARSE_EC_COMPRESSED
-    # Indirect dependencies of ECP
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
-    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
-    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-    # Direct dependencies of DHM
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
-    # Direct dependencies of RSA
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
-    scripts/config.py unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
-    # PK and its dependencies
-    scripts/config.py unset MBEDTLS_PK_C
-    scripts/config.py unset MBEDTLS_PK_PARSE_C
-    scripts/config.py unset MBEDTLS_PK_WRITE_C
-    scripts/config.py unset MBEDTLS_X509_USE_C
-    scripts/config.py unset MBEDTLS_X509_CRT_PARSE_C
-    scripts/config.py unset MBEDTLS_X509_CRL_PARSE_C
-    scripts/config.py unset MBEDTLS_X509_CSR_PARSE_C
-    scripts/config.py unset MBEDTLS_X509_CREATE_C
-    scripts/config.py unset MBEDTLS_X509_CRT_WRITE_C
-    scripts/config.py unset MBEDTLS_X509_CSR_WRITE_C
-    scripts/config.py unset MBEDTLS_PKCS7_C
-    scripts/config.py unset MBEDTLS_SSL_SERVER_NAME_INDICATION
-    scripts/config.py unset MBEDTLS_SSL_ASYNC_PRIVATE
-    scripts/config.py unset MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
-
-    make
-
-    msg "test: full minus bignum"
-    make test
-}
-
-component_test_tls1_2_default_stream_cipher_only () {
-    msg "build: default with only stream cipher"
-
-    # Disable AEAD (controlled by the presence of one of GCM_C, CCM_C, CHACHAPOLY_C
-    scripts/config.py unset MBEDTLS_GCM_C
-    scripts/config.py unset MBEDTLS_CCM_C
-    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
-    #Disable TLS 1.3 (as no AEAD)
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    # Disable CBC-legacy (controlled by MBEDTLS_CIPHER_MODE_CBC plus at least one block cipher (AES, ARIA, Camellia, DES))
-    scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
-    # Disable CBC-EtM (controlled by the same as CBC-legacy plus MBEDTLS_SSL_ENCRYPT_THEN_MAC)
-    scripts/config.py unset MBEDTLS_SSL_ENCRYPT_THEN_MAC
-    # Enable stream (currently that's just the NULL pseudo-cipher (controlled by MBEDTLS_CIPHER_NULL_CIPHER))
-    scripts/config.py set MBEDTLS_CIPHER_NULL_CIPHER
-    # Modules that depend on AEAD
-    scripts/config.py unset MBEDTLS_SSL_CONTEXT_SERIALIZATION
-    scripts/config.py unset MBEDTLS_SSL_TICKET_C
-
-    make
-
-    msg "test: default with only stream cipher"
-    make test
-
-    # Not running ssl-opt.sh because most tests require a non-NULL ciphersuite.
-}
-
-component_test_tls1_2_default_stream_cipher_only_use_psa () {
-    msg "build: default with only stream cipher use psa"
-
-    scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
-    # Disable AEAD (controlled by the presence of one of GCM_C, CCM_C, CHACHAPOLY_C)
-    scripts/config.py unset MBEDTLS_GCM_C
-    scripts/config.py unset MBEDTLS_CCM_C
-    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
-    #Disable TLS 1.3 (as no AEAD)
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    # Disable CBC-legacy (controlled by MBEDTLS_CIPHER_MODE_CBC plus at least one block cipher (AES, ARIA, Camellia, DES))
-    scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
-    # Disable CBC-EtM (controlled by the same as CBC-legacy plus MBEDTLS_SSL_ENCRYPT_THEN_MAC)
-    scripts/config.py unset MBEDTLS_SSL_ENCRYPT_THEN_MAC
-    # Enable stream (currently that's just the NULL pseudo-cipher (controlled by MBEDTLS_CIPHER_NULL_CIPHER))
-    scripts/config.py set MBEDTLS_CIPHER_NULL_CIPHER
-    # Modules that depend on AEAD
-    scripts/config.py unset MBEDTLS_SSL_CONTEXT_SERIALIZATION
-    scripts/config.py unset MBEDTLS_SSL_TICKET_C
-
-    make
-
-    msg "test: default with only stream cipher use psa"
-    make test
-
-    # Not running ssl-opt.sh because most tests require a non-NULL ciphersuite.
-}
-
-component_test_tls1_2_default_cbc_legacy_cipher_only () {
-    msg "build: default with only CBC-legacy cipher"
-
-    # Disable AEAD (controlled by the presence of one of GCM_C, CCM_C, CHACHAPOLY_C)
-    scripts/config.py unset MBEDTLS_GCM_C
-    scripts/config.py unset MBEDTLS_CCM_C
-    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
-    #Disable TLS 1.3 (as no AEAD)
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    # Enable CBC-legacy (controlled by MBEDTLS_CIPHER_MODE_CBC plus at least one block cipher (AES, ARIA, Camellia, DES))
-    scripts/config.py set MBEDTLS_CIPHER_MODE_CBC
-    # Disable CBC-EtM (controlled by the same as CBC-legacy plus MBEDTLS_SSL_ENCRYPT_THEN_MAC)
-    scripts/config.py unset MBEDTLS_SSL_ENCRYPT_THEN_MAC
-    # Disable stream (currently that's just the NULL pseudo-cipher (controlled by MBEDTLS_CIPHER_NULL_CIPHER))
-    scripts/config.py unset MBEDTLS_CIPHER_NULL_CIPHER
-    # Modules that depend on AEAD
-    scripts/config.py unset MBEDTLS_SSL_CONTEXT_SERIALIZATION
-    scripts/config.py unset MBEDTLS_SSL_TICKET_C
-
-    make
-
-    msg "test: default with only CBC-legacy cipher"
-    make test
-
-    msg "test: default with only CBC-legacy cipher - ssl-opt.sh (subset)"
-    tests/ssl-opt.sh -f "TLS 1.2"
-}
-
-component_test_tls1_2_deafult_cbc_legacy_cipher_only_use_psa () {
-    msg "build: default with only CBC-legacy cipher use psa"
-
-    scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
-    # Disable AEAD (controlled by the presence of one of GCM_C, CCM_C, CHACHAPOLY_C)
-    scripts/config.py unset MBEDTLS_GCM_C
-    scripts/config.py unset MBEDTLS_CCM_C
-    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
-    #Disable TLS 1.3 (as no AEAD)
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    # Enable CBC-legacy (controlled by MBEDTLS_CIPHER_MODE_CBC plus at least one block cipher (AES, ARIA, Camellia, DES))
-    scripts/config.py set MBEDTLS_CIPHER_MODE_CBC
-    # Disable CBC-EtM (controlled by the same as CBC-legacy plus MBEDTLS_SSL_ENCRYPT_THEN_MAC)
-    scripts/config.py unset MBEDTLS_SSL_ENCRYPT_THEN_MAC
-    # Disable stream (currently that's just the NULL pseudo-cipher (controlled by MBEDTLS_CIPHER_NULL_CIPHER))
-    scripts/config.py unset MBEDTLS_CIPHER_NULL_CIPHER
-    # Modules that depend on AEAD
-    scripts/config.py unset MBEDTLS_SSL_CONTEXT_SERIALIZATION
-    scripts/config.py unset MBEDTLS_SSL_TICKET_C
-
-    make
-
-    msg "test: default with only CBC-legacy cipher use psa"
-    make test
-
-    msg "test: default with only CBC-legacy cipher use psa - ssl-opt.sh (subset)"
-    tests/ssl-opt.sh -f "TLS 1.2"
-}
-
-component_test_tls1_2_default_cbc_legacy_cbc_etm_cipher_only () {
-    msg "build: default with only CBC-legacy and CBC-EtM ciphers"
-
-    # Disable AEAD (controlled by the presence of one of GCM_C, CCM_C, CHACHAPOLY_C)
-    scripts/config.py unset MBEDTLS_GCM_C
-    scripts/config.py unset MBEDTLS_CCM_C
-    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
-    #Disable TLS 1.3 (as no AEAD)
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    # Enable CBC-legacy (controlled by MBEDTLS_CIPHER_MODE_CBC plus at least one block cipher (AES, ARIA, Camellia, DES))
-    scripts/config.py set MBEDTLS_CIPHER_MODE_CBC
-    # Enable CBC-EtM (controlled by the same as CBC-legacy plus MBEDTLS_SSL_ENCRYPT_THEN_MAC)
-    scripts/config.py set MBEDTLS_SSL_ENCRYPT_THEN_MAC
-    # Disable stream (currently that's just the NULL pseudo-cipher (controlled by MBEDTLS_CIPHER_NULL_CIPHER))
-    scripts/config.py unset MBEDTLS_CIPHER_NULL_CIPHER
-    # Modules that depend on AEAD
-    scripts/config.py unset MBEDTLS_SSL_CONTEXT_SERIALIZATION
-    scripts/config.py unset MBEDTLS_SSL_TICKET_C
-
-    make
-
-    msg "test: default with only CBC-legacy and CBC-EtM ciphers"
-    make test
-
-    msg "test: default with only CBC-legacy and CBC-EtM ciphers - ssl-opt.sh (subset)"
-    tests/ssl-opt.sh -f "TLS 1.2"
-}
-
-component_test_tls1_2_default_cbc_legacy_cbc_etm_cipher_only_use_psa () {
-    msg "build: default with only CBC-legacy and CBC-EtM ciphers use psa"
-
-    scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
-    # Disable AEAD (controlled by the presence of one of GCM_C, CCM_C, CHACHAPOLY_C)
-    scripts/config.py unset MBEDTLS_GCM_C
-    scripts/config.py unset MBEDTLS_CCM_C
-    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
-    #Disable TLS 1.3 (as no AEAD)
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    # Enable CBC-legacy (controlled by MBEDTLS_CIPHER_MODE_CBC plus at least one block cipher (AES, ARIA, Camellia, DES))
-    scripts/config.py set MBEDTLS_CIPHER_MODE_CBC
-    # Enable CBC-EtM (controlled by the same as CBC-legacy plus MBEDTLS_SSL_ENCRYPT_THEN_MAC)
-    scripts/config.py set MBEDTLS_SSL_ENCRYPT_THEN_MAC
-    # Disable stream (currently that's just the NULL pseudo-cipher (controlled by MBEDTLS_CIPHER_NULL_CIPHER))
-    scripts/config.py unset MBEDTLS_CIPHER_NULL_CIPHER
-    # Modules that depend on AEAD
-    scripts/config.py unset MBEDTLS_SSL_CONTEXT_SERIALIZATION
-    scripts/config.py unset MBEDTLS_SSL_TICKET_C
-
-    make
-
-    msg "test: default with only CBC-legacy and CBC-EtM ciphers use psa"
-    make test
-
-    msg "test: default with only CBC-legacy and CBC-EtM ciphers use psa - ssl-opt.sh (subset)"
-    tests/ssl-opt.sh -f "TLS 1.2"
-}
-
-# We're not aware of any other (open source) implementation of EC J-PAKE in TLS
-# that we could use for interop testing. However, we now have sort of two
-# implementations ourselves: one using PSA, the other not. At least test that
-# these two interoperate with each other.
-component_test_tls1_2_ecjpake_compatibility() {
-    msg "build: TLS1.2 server+client w/ EC-JPAKE w/o USE_PSA"
-    scripts/config.py set MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
-    # Explicitly make lib first to avoid a race condition:
-    # https://github.com/Mbed-TLS/mbedtls/issues/8229
-    make lib
-    make -C programs ssl/ssl_server2 ssl/ssl_client2
-    cp programs/ssl/ssl_server2 s2_no_use_psa
-    cp programs/ssl/ssl_client2 c2_no_use_psa
-
-    msg "build: TLS1.2 server+client w/ EC-JPAKE w/ USE_PSA"
-    scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
-    make clean
-    make lib
-    make -C programs ssl/ssl_server2 ssl/ssl_client2
-    make -C programs test/udp_proxy test/query_compile_time_config
-
-    msg "test: server w/o USE_PSA - client w/ USE_PSA, text password"
-    P_SRV=../s2_no_use_psa tests/ssl-opt.sh -f "ECJPAKE: working, TLS"
-    msg "test: server w/o USE_PSA - client w/ USE_PSA, opaque password"
-    P_SRV=../s2_no_use_psa tests/ssl-opt.sh -f "ECJPAKE: opaque password client only, working, TLS"
-    msg "test: client w/o USE_PSA - server w/ USE_PSA, text password"
-    P_CLI=../c2_no_use_psa tests/ssl-opt.sh -f "ECJPAKE: working, TLS"
-    msg "test: client w/o USE_PSA - server w/ USE_PSA, opaque password"
-    P_CLI=../c2_no_use_psa tests/ssl-opt.sh -f "ECJPAKE: opaque password server only, working, TLS"
-
-    rm s2_no_use_psa c2_no_use_psa
-}
-
-component_test_everest () {
-    msg "build: Everest ECDH context (ASan build)" # ~ 6 min
-    scripts/config.py set MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED
-    CC=clang cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: Everest ECDH context - main suites (inc. selftests) (ASan build)" # ~ 50s
-    make test
-
-    msg "test: metatests (clang, ASan)"
-    tests/scripts/run-metatests.sh any asan poison
-
-    msg "test: Everest ECDH context - ECDH-related part of ssl-opt.sh (ASan build)" # ~ 5s
-    tests/ssl-opt.sh -f ECDH
-
-    msg "test: Everest ECDH context - compat.sh with some ECDH ciphersuites (ASan build)" # ~ 3 min
-    # Exclude some symmetric ciphers that are redundant here to gain time.
-    tests/compat.sh -f ECDH -V NO -e 'ARIA\|CAMELLIA\|CHACHA'
-}
-
-component_test_everest_curve25519_only () {
-    msg "build: Everest ECDH context, only Curve25519" # ~ 6 min
-    scripts/config.py set MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED
-    scripts/config.py unset MBEDTLS_ECDSA_C
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
-    scripts/config.py unset MBEDTLS_ECJPAKE_C
-    # Disable all curves
-    scripts/config.py unset-all "MBEDTLS_ECP_DP_[0-9A-Z_a-z]*_ENABLED"
-    scripts/config.py set MBEDTLS_ECP_DP_CURVE25519_ENABLED
-
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
-
-    msg "test: Everest ECDH context, only Curve25519" # ~ 50s
-    make test
-}
-
-component_test_small_ssl_out_content_len () {
-    msg "build: small SSL_OUT_CONTENT_LEN (ASan build)"
-    scripts/config.py set MBEDTLS_SSL_IN_CONTENT_LEN 16384
-    scripts/config.py set MBEDTLS_SSL_OUT_CONTENT_LEN 4096
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: small SSL_OUT_CONTENT_LEN - ssl-opt.sh MFL and large packet tests"
-    tests/ssl-opt.sh -f "Max fragment\|Large packet"
-}
-
-component_test_small_ssl_in_content_len () {
-    msg "build: small SSL_IN_CONTENT_LEN (ASan build)"
-    scripts/config.py set MBEDTLS_SSL_IN_CONTENT_LEN 4096
-    scripts/config.py set MBEDTLS_SSL_OUT_CONTENT_LEN 16384
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: small SSL_IN_CONTENT_LEN - ssl-opt.sh MFL tests"
-    tests/ssl-opt.sh -f "Max fragment"
-}
-
-component_test_small_ssl_dtls_max_buffering () {
-    msg "build: small MBEDTLS_SSL_DTLS_MAX_BUFFERING #0"
-    scripts/config.py set MBEDTLS_SSL_DTLS_MAX_BUFFERING 1000
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: small MBEDTLS_SSL_DTLS_MAX_BUFFERING #0 - ssl-opt.sh specific reordering test"
-    tests/ssl-opt.sh -f "DTLS reordering: Buffer out-of-order hs msg before reassembling next, free buffered msg"
-}
-
-component_test_small_mbedtls_ssl_dtls_max_buffering () {
-    msg "build: small MBEDTLS_SSL_DTLS_MAX_BUFFERING #1"
-    scripts/config.py set MBEDTLS_SSL_DTLS_MAX_BUFFERING 190
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: small MBEDTLS_SSL_DTLS_MAX_BUFFERING #1 - ssl-opt.sh specific reordering test"
-    tests/ssl-opt.sh -f "DTLS reordering: Buffer encrypted Finished message, drop for fragmented NewSessionTicket"
-}
-
-component_test_psa_collect_statuses () {
-  msg "build+test: psa_collect_statuses" # ~30s
-  scripts/config.py full
-  tests/scripts/psa_collect_statuses.py
-  # Check that psa_crypto_init() succeeded at least once
-  grep -q '^0:psa_crypto_init:' tests/statuses.log
-  rm -f tests/statuses.log
-}
-
-component_test_full_cmake_clang () {
-    msg "build: cmake, full config, clang" # ~ 50s
-    scripts/config.py full
-    CC=clang CXX=clang cmake -D CMAKE_BUILD_TYPE:String=Release -D ENABLE_TESTING=On -D TEST_CPP=1 .
-    make
-
-    msg "test: main suites (full config, clang)" # ~ 5s
-    make test
-
-    msg "test: cpp_dummy_build (full config, clang)" # ~ 1s
-    programs/test/cpp_dummy_build
-
-    msg "test: metatests (clang)"
-    tests/scripts/run-metatests.sh any pthread
-
-    msg "program demos (full config, clang)" # ~10s
-    tests/scripts/run_demos.py
-
-    msg "test: psa_constant_names (full config, clang)" # ~ 1s
-    tests/scripts/test_psa_constant_names.py
-
-    msg "test: ssl-opt.sh default, ECJPAKE, SSL async (full config)" # ~ 1s
-    tests/ssl-opt.sh -f 'Default\|ECJPAKE\|SSL async private'
-}
-
-skip_suites_without_constant_flow () {
-    # Skip the test suites that don't have any constant-flow annotations.
-    # This will need to be adjusted if we ever start declaring things as
-    # secret from macros or functions inside tests/include or tests/src.
-    SKIP_TEST_SUITES=$(
-        git -C tests/suites grep -L TEST_CF_ 'test_suite_*.function' |
-            sed 's/test_suite_//; s/\.function$//' |
-            tr '\n' ,)
-    export SKIP_TEST_SUITES
-}
-
-skip_all_except_given_suite () {
-    # Skip all but the given test suite
-    SKIP_TEST_SUITES=$(
-        ls -1 tests/suites/test_suite_*.function |
-        grep -v $1.function |
-         sed 's/tests.suites.test_suite_//; s/\.function$//' |
-        tr '\n' ,)
-    export SKIP_TEST_SUITES
-}
-
-component_test_memsan_constant_flow () {
-    # This tests both (1) accesses to undefined memory, and (2) branches or
-    # memory access depending on secret values. To distinguish between those:
-    # - unset MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN - does the failure persist?
-    # - or alternatively, change the build type to MemSanDbg, which enables
-    # origin tracking and nicer stack traces (which are useful for debugging
-    # anyway), and check if the origin was TEST_CF_SECRET() or something else.
-    msg "build: cmake MSan (clang), full config minus MBEDTLS_USE_PSA_CRYPTO with constant flow testing"
-    scripts/config.py full
-    scripts/config.py set MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_AESNI_C # memsan doesn't grok asm
-    CC=clang cmake -D CMAKE_BUILD_TYPE:String=MemSan .
-    make
-
-    msg "test: main suites (full minus MBEDTLS_USE_PSA_CRYPTO, Msan + constant flow)"
-    make test
-}
-
-component_test_memsan_constant_flow_psa () {
-    # This tests both (1) accesses to undefined memory, and (2) branches or
-    # memory access depending on secret values. To distinguish between those:
-    # - unset MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN - does the failure persist?
-    # - or alternatively, change the build type to MemSanDbg, which enables
-    # origin tracking and nicer stack traces (which are useful for debugging
-    # anyway), and check if the origin was TEST_CF_SECRET() or something else.
-    msg "build: cmake MSan (clang), full config with constant flow testing"
-    scripts/config.py full
-    scripts/config.py set MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN
-    scripts/config.py unset MBEDTLS_AESNI_C # memsan doesn't grok asm
-    CC=clang cmake -D CMAKE_BUILD_TYPE:String=MemSan .
-    make
-
-    msg "test: main suites (Msan + constant flow)"
-    make test
-}
-
-component_release_test_valgrind_constant_flow () {
-    # This tests both (1) everything that valgrind's memcheck usually checks
-    # (heap buffer overflows, use of uninitialized memory, use-after-free,
-    # etc.) and (2) branches or memory access depending on secret values,
-    # which will be reported as uninitialized memory. To distinguish between
-    # secret and actually uninitialized:
-    # - unset MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND - does the failure persist?
-    # - or alternatively, build with debug info and manually run the offending
-    # test suite with valgrind --track-origins=yes, then check if the origin
-    # was TEST_CF_SECRET() or something else.
-    msg "build: cmake release GCC, full config minus MBEDTLS_USE_PSA_CRYPTO with constant flow testing"
-    scripts/config.py full
-    scripts/config.py set MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    skip_suites_without_constant_flow
-    cmake -D CMAKE_BUILD_TYPE:String=Release .
-    make
-
-    # this only shows a summary of the results (how many of each type)
-    # details are left in Testing/<date>/DynamicAnalysis.xml
-    msg "test: some suites (full minus MBEDTLS_USE_PSA_CRYPTO, valgrind + constant flow)"
-    make memcheck
-
-    # Test asm path in constant time module - by default, it will test the plain C
-    # path under Valgrind or Memsan. Running only the constant_time tests is fast (<1s)
-    msg "test: valgrind asm constant_time"
-    scripts/config.py --force set MBEDTLS_TEST_CONSTANT_FLOW_ASM
-    skip_all_except_given_suite test_suite_constant_time
-    cmake -D CMAKE_BUILD_TYPE:String=Release .
-    make clean
-    make
-    make memcheck
-}
-
-component_release_test_valgrind_constant_flow_psa () {
-    # This tests both (1) everything that valgrind's memcheck usually checks
-    # (heap buffer overflows, use of uninitialized memory, use-after-free,
-    # etc.) and (2) branches or memory access depending on secret values,
-    # which will be reported as uninitialized memory. To distinguish between
-    # secret and actually uninitialized:
-    # - unset MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND - does the failure persist?
-    # - or alternatively, build with debug info and manually run the offending
-    # test suite with valgrind --track-origins=yes, then check if the origin
-    # was TEST_CF_SECRET() or something else.
-    msg "build: cmake release GCC, full config with constant flow testing"
-    scripts/config.py full
-    scripts/config.py set MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND
-    skip_suites_without_constant_flow
-    cmake -D CMAKE_BUILD_TYPE:String=Release .
-    make
-
-    # this only shows a summary of the results (how many of each type)
-    # details are left in Testing/<date>/DynamicAnalysis.xml
-    msg "test: some suites (valgrind + constant flow)"
-    make memcheck
-}
-
-component_test_tsan () {
-    msg "build: TSan (clang)"
-    scripts/config.py full
-    scripts/config.py set MBEDTLS_THREADING_C
-    scripts/config.py set MBEDTLS_THREADING_PTHREAD
-    # Self-tests do not currently use multiple threads.
-    scripts/config.py unset MBEDTLS_SELF_TEST
-
-    # The deprecated MBEDTLS_PSA_CRYPTO_SE_C interface is not thread safe.
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
-
-    CC=clang cmake -D CMAKE_BUILD_TYPE:String=TSan .
-    make
-
-    msg "test: main suites (TSan)"
-    make test
-}
-
-component_test_default_no_deprecated () {
-    # Test that removing the deprecated features from the default
-    # configuration leaves something consistent.
-    msg "build: make, default + MBEDTLS_DEPRECATED_REMOVED" # ~ 30s
-    scripts/config.py set MBEDTLS_DEPRECATED_REMOVED
-    make CFLAGS='-O -Werror -Wall -Wextra'
-
-    msg "test: make, default + MBEDTLS_DEPRECATED_REMOVED" # ~ 5s
-    make test
-}
-
-component_test_full_no_deprecated () {
-    msg "build: make, full_no_deprecated config" # ~ 30s
-    scripts/config.py full_no_deprecated
-    make CFLAGS='-O -Werror -Wall -Wextra'
-
-    msg "test: make, full_no_deprecated config" # ~ 5s
-    make test
-
-    msg "test: ensure that X509 has no direct dependency on BIGNUM_C"
-    not grep mbedtls_mpi library/libmbedx509.a
-}
-
-component_test_full_no_deprecated_deprecated_warning () {
-    # Test that there is nothing deprecated in "full_no_deprecated".
-    # A deprecated feature would trigger a warning (made fatal) from
-    # MBEDTLS_DEPRECATED_WARNING.
-    msg "build: make, full_no_deprecated config, MBEDTLS_DEPRECATED_WARNING" # ~ 30s
-    scripts/config.py full_no_deprecated
-    scripts/config.py unset MBEDTLS_DEPRECATED_REMOVED
-    scripts/config.py set MBEDTLS_DEPRECATED_WARNING
-    make CFLAGS='-O -Werror -Wall -Wextra'
-
-    msg "test: make, full_no_deprecated config, MBEDTLS_DEPRECATED_WARNING" # ~ 5s
-    make test
-}
-
-component_test_full_deprecated_warning () {
-    # Test that when MBEDTLS_DEPRECATED_WARNING is enabled, the build passes
-    # with only certain whitelisted types of warnings.
-    msg "build: make, full config + MBEDTLS_DEPRECATED_WARNING, expect warnings" # ~ 30s
-    scripts/config.py full
-    scripts/config.py set MBEDTLS_DEPRECATED_WARNING
-    # Expect warnings from '#warning' directives in check_config.h.
-    # Note that gcc is required to allow the use of -Wno-error=cpp, which allows us to
-    # display #warning messages without them being treated as errors.
-    make CC=gcc CFLAGS='-O -Werror -Wall -Wextra -Wno-error=cpp' lib programs
-
-    msg "build: make tests, full config + MBEDTLS_DEPRECATED_WARNING, expect warnings" # ~ 30s
-    # Set MBEDTLS_TEST_DEPRECATED to enable tests for deprecated features.
-    # By default those are disabled when MBEDTLS_DEPRECATED_WARNING is set.
-    # Expect warnings from '#warning' directives in check_config.h and
-    # from the use of deprecated functions in test suites.
-    make CC=gcc CFLAGS='-O -Werror -Wall -Wextra -Wno-error=deprecated-declarations -Wno-error=cpp -DMBEDTLS_TEST_DEPRECATED' tests
-
-    msg "test: full config + MBEDTLS_TEST_DEPRECATED" # ~ 30s
-    make test
-
-    msg "program demos: full config + MBEDTLS_TEST_DEPRECATED" # ~10s
-    tests/scripts/run_demos.py
-}
-
-# Check that the specified libraries exist and are empty.
-are_empty_libraries () {
-  nm "$@" >/dev/null 2>/dev/null
-  ! nm "$@" 2>/dev/null | grep -v ':$' | grep .
-}
-
-component_build_crypto_default () {
-  msg "build: make, crypto only"
-  scripts/config.py crypto
-  make CFLAGS='-O1 -Werror'
-  are_empty_libraries library/libmbedx509.* library/libmbedtls.*
-}
-
-component_build_crypto_full () {
-  msg "build: make, crypto only, full config"
-  scripts/config.py crypto_full
-  make CFLAGS='-O1 -Werror'
-  are_empty_libraries library/libmbedx509.* library/libmbedtls.*
-}
-
-component_test_crypto_for_psa_service () {
-  msg "build: make, config for PSA crypto service"
-  scripts/config.py crypto
-  scripts/config.py set MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
-  # Disable things that are not needed for just cryptography, to
-  # reach a configuration that would be typical for a PSA cryptography
-  # service providing all implemented PSA algorithms.
-  # System stuff
-  scripts/config.py unset MBEDTLS_ERROR_C
-  scripts/config.py unset MBEDTLS_TIMING_C
-  scripts/config.py unset MBEDTLS_VERSION_FEATURES
-  # Crypto stuff with no PSA interface
-  scripts/config.py unset MBEDTLS_BASE64_C
-  # Keep MBEDTLS_CIPHER_C because psa_crypto_cipher, CCM and GCM need it.
-  scripts/config.py unset MBEDTLS_HKDF_C # PSA's HKDF is independent
-  # Keep MBEDTLS_MD_C because deterministic ECDSA needs it for HMAC_DRBG.
-  scripts/config.py unset MBEDTLS_NIST_KW_C
-  scripts/config.py unset MBEDTLS_PEM_PARSE_C
-  scripts/config.py unset MBEDTLS_PEM_WRITE_C
-  scripts/config.py unset MBEDTLS_PKCS12_C
-  scripts/config.py unset MBEDTLS_PKCS5_C
-  # MBEDTLS_PK_PARSE_C and MBEDTLS_PK_WRITE_C are actually currently needed
-  # in PSA code to work with RSA keys. We don't require users to set those:
-  # they will be reenabled in build_info.h.
-  scripts/config.py unset MBEDTLS_PK_C
-  scripts/config.py unset MBEDTLS_PK_PARSE_C
-  scripts/config.py unset MBEDTLS_PK_WRITE_C
-  make CFLAGS='-O1 -Werror' all test
-  are_empty_libraries library/libmbedx509.* library/libmbedtls.*
-}
-
-component_build_crypto_baremetal () {
-  msg "build: make, crypto only, baremetal config"
-  scripts/config.py crypto_baremetal
-  make CFLAGS="-O1 -Werror -I$PWD/tests/include/baremetal-override/"
-  are_empty_libraries library/libmbedx509.* library/libmbedtls.*
-}
-support_build_crypto_baremetal () {
-    support_build_baremetal "$@"
-}
-
-component_build_baremetal () {
-  msg "build: make, baremetal config"
-  scripts/config.py baremetal
-  make CFLAGS="-O1 -Werror -I$PWD/tests/include/baremetal-override/"
-}
-support_build_baremetal () {
-    # Older Glibc versions include time.h from other headers such as stdlib.h,
-    # which makes the no-time.h-in-baremetal check fail. Ubuntu 16.04 has this
-    # problem, Ubuntu 18.04 is ok.
-    ! grep -q -F time.h /usr/include/x86_64-linux-gnu/sys/types.h
-}
-
-# depends.py family of tests
-component_test_depends_py_cipher_id () {
-    msg "test/build: depends.py cipher_id (gcc)"
-    tests/scripts/depends.py cipher_id --unset-use-psa
-}
-
-component_test_depends_py_cipher_chaining () {
-    msg "test/build: depends.py cipher_chaining (gcc)"
-    tests/scripts/depends.py cipher_chaining --unset-use-psa
-}
-
-component_test_depends_py_cipher_padding () {
-    msg "test/build: depends.py cipher_padding (gcc)"
-    tests/scripts/depends.py cipher_padding --unset-use-psa
-}
-
-component_test_depends_py_curves () {
-    msg "test/build: depends.py curves (gcc)"
-    tests/scripts/depends.py curves --unset-use-psa
-}
-
-component_test_depends_py_hashes () {
-    msg "test/build: depends.py hashes (gcc)"
-    tests/scripts/depends.py hashes --unset-use-psa
-}
-
-component_test_depends_py_kex () {
-    msg "test/build: depends.py kex (gcc)"
-    tests/scripts/depends.py kex --unset-use-psa
-}
-
-component_test_depends_py_pkalgs () {
-    msg "test/build: depends.py pkalgs (gcc)"
-    tests/scripts/depends.py pkalgs --unset-use-psa
-}
-
-# PSA equivalents of the depends.py tests
-component_test_depends_py_cipher_id_psa () {
-    msg "test/build: depends.py cipher_id (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
-    tests/scripts/depends.py cipher_id
-}
-
-component_test_depends_py_cipher_chaining_psa () {
-    msg "test/build: depends.py cipher_chaining (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
-    tests/scripts/depends.py cipher_chaining
-}
-
-component_test_depends_py_cipher_padding_psa () {
-    msg "test/build: depends.py cipher_padding (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
-    tests/scripts/depends.py cipher_padding
-}
-
-component_test_depends_py_curves_psa () {
-    msg "test/build: depends.py curves (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
-    tests/scripts/depends.py curves
-}
-
-component_test_depends_py_hashes_psa () {
-    msg "test/build: depends.py hashes (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
-    tests/scripts/depends.py hashes
-}
-
-component_test_depends_py_kex_psa () {
-    msg "test/build: depends.py kex (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
-    tests/scripts/depends.py kex
-}
-
-component_test_depends_py_pkalgs_psa () {
-    msg "test/build: depends.py pkalgs (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
-    tests/scripts/depends.py pkalgs
-}
-
-component_test_psa_crypto_config_ffdh_2048_only () {
-    msg "build: full config - only DH 2048"
-
-    scripts/config.py full
-
-    # Disable all DH groups other than 2048.
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_DH_RFC7919_3072
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_DH_RFC7919_4096
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_DH_RFC7919_6144
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_DH_RFC7919_8192
-
-    make CFLAGS="$ASAN_CFLAGS -Werror" LDFLAGS="$ASAN_CFLAGS"
-
-    msg "test: full config - only DH 2048"
-    make test
-
-    msg "ssl-opt: full config - only DH 2048"
-    tests/ssl-opt.sh -f "ffdh"
-}
-
-component_build_no_pk_rsa_alt_support () {
-    msg "build: !MBEDTLS_PK_RSA_ALT_SUPPORT" # ~30s
-
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_PK_RSA_ALT_SUPPORT
-    scripts/config.py set MBEDTLS_RSA_C
-    scripts/config.py set MBEDTLS_X509_CRT_WRITE_C
-
-    # Only compile - this is primarily to test for compile issues
-    make CFLAGS='-Werror -Wall -Wextra -I../tests/include/alt-dummy'
-}
-
-component_build_module_alt () {
-    msg "build: MBEDTLS_XXX_ALT" # ~30s
-    scripts/config.py full
-
-    # Disable options that are incompatible with some ALT implementations:
-    # aesni.c and padlock.c reference mbedtls_aes_context fields directly.
-    scripts/config.py unset MBEDTLS_AESNI_C
-    scripts/config.py unset MBEDTLS_PADLOCK_C
-    scripts/config.py unset MBEDTLS_AESCE_C
-    # MBEDTLS_ECP_RESTARTABLE is documented as incompatible.
-    scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
-    # You can only have one threading implementation: alt or pthread, not both.
-    scripts/config.py unset MBEDTLS_THREADING_PTHREAD
-    # The SpecifiedECDomain parsing code accesses mbedtls_ecp_group fields
-    # directly and assumes the implementation works with partial groups.
-    scripts/config.py unset MBEDTLS_PK_PARSE_EC_EXTENDED
-    # MBEDTLS_SHA256_*ALT can't be used with MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*
-    scripts/config.py unset MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
-    scripts/config.py unset MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
-    # MBEDTLS_SHA512_*ALT can't be used with MBEDTLS_SHA512_USE_A64_CRYPTO_*
-    scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
-    scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
-
-    # Enable all MBEDTLS_XXX_ALT for whole modules. Do not enable
-    # MBEDTLS_XXX_YYY_ALT which are for single functions.
-    scripts/config.py set-all 'MBEDTLS_([A-Z0-9]*|NIST_KW)_ALT'
-    scripts/config.py unset MBEDTLS_DHM_ALT #incompatible with MBEDTLS_DEBUG_C
-
-    # We can only compile, not link, since we don't have any implementations
-    # suitable for testing with the dummy alt headers.
-    make CFLAGS='-Werror -Wall -Wextra -I../tests/include/alt-dummy' lib
-}
-
-component_build_dhm_alt () {
-    msg "build: MBEDTLS_DHM_ALT" # ~30s
-    scripts/config.py full
-    scripts/config.py set MBEDTLS_DHM_ALT
-    # debug.c currently references mbedtls_dhm_context fields directly.
-    scripts/config.py unset MBEDTLS_DEBUG_C
-    # We can only compile, not link, since we don't have any implementations
-    # suitable for testing with the dummy alt headers.
-    make CFLAGS='-Werror -Wall -Wextra -I../tests/include/alt-dummy' lib
-}
-
-component_test_no_psa_crypto_full_cmake_asan() {
-    # full minus MBEDTLS_PSA_CRYPTO_C: run the same set of tests as basic-build-test.sh
-    msg "build: cmake, full config minus PSA crypto, ASan"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_C
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_CLIENT
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    scripts/config.py unset MBEDTLS_PSA_ITS_FILE_C
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C
-    scripts/config.py unset MBEDTLS_LMS_C
-    scripts/config.py unset MBEDTLS_LMS_PRIVATE
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: main suites (full minus PSA crypto)"
-    make test
-
-    # Note: ssl-opt.sh has some test cases that depend on
-    # MBEDTLS_ECP_RESTARTABLE && !MBEDTLS_USE_PSA_CRYPTO
-    # This is the only component where those tests are not skipped.
-    msg "test: ssl-opt.sh (full minus PSA crypto)"
-    tests/ssl-opt.sh
-
-    # Note: the next two invocations cover all compat.sh test cases.
-    # We should use the same here and in basic-build-test.sh.
-    msg "test: compat.sh: default version (full minus PSA crypto)"
-    tests/compat.sh -e 'ARIA\|CHACHA'
-
-    msg "test: compat.sh: next: ARIA, Chacha (full minus PSA crypto)"
-    env OPENSSL="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA'
-}
-
-component_test_psa_crypto_config_accel_ecdsa () {
-    msg "build: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated ECDSA"
-
-    # Algorithms and key types to accelerate
-    loc_accel_list="ALG_ECDSA ALG_DETERMINISTIC_ECDSA \
-                    $(helper_get_psa_key_type_list "ECC") \
-                    $(helper_get_psa_curve_list)"
-
-    # Configure
-    # ---------
-
-    # Start from default config (no USE_PSA) + TLS 1.3
-    helper_libtestdriver1_adjust_config "default"
-
-    # Disable the module that's accelerated
-    scripts/config.py unset MBEDTLS_ECDSA_C
-
-    # Disable things that depend on it
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
-
-    # Build
-    # -----
-
-    # These hashes are needed for some ECDSA signature tests.
-    loc_extra_list="ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
-                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
-
-    helper_libtestdriver1_make_drivers "$loc_accel_list" "$loc_extra_list"
-
-    helper_libtestdriver1_make_main "$loc_accel_list"
-
-    # Make sure this was not re-enabled by accident (additive config)
-    not grep mbedtls_ecdsa_ library/ecdsa.o
-
-    # Run the tests
-    # -------------
-
-    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated ECDSA"
-    make test
-}
-
-component_test_psa_crypto_config_accel_ecdh () {
-    msg "build: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated ECDH"
-
-    # Algorithms and key types to accelerate
-    loc_accel_list="ALG_ECDH \
-                    $(helper_get_psa_key_type_list "ECC") \
-                    $(helper_get_psa_curve_list)"
-
-    # Configure
-    # ---------
-
-    # Start from default config (no USE_PSA)
-    helper_libtestdriver1_adjust_config "default"
-
-    # Disable the module that's accelerated
-    scripts/config.py unset MBEDTLS_ECDH_C
-
-    # Disable things that depend on it
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
-
-    # Build
-    # -----
-
-    helper_libtestdriver1_make_drivers "$loc_accel_list"
-
-    helper_libtestdriver1_make_main "$loc_accel_list"
-
-    # Make sure this was not re-enabled by accident (additive config)
-    not grep mbedtls_ecdh_ library/ecdh.o
-
-    # Run the tests
-    # -------------
-
-    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated ECDH"
-    make test
-}
-
-component_test_psa_crypto_config_accel_ffdh () {
-    msg "build: full with accelerated FFDH"
-
-    # Algorithms and key types to accelerate
-    loc_accel_list="ALG_FFDH \
-                    $(helper_get_psa_key_type_list "DH") \
-                    $(helper_get_psa_dh_group_list)"
-
-    # Configure
-    # ---------
-
-    # start with full (USE_PSA and TLS 1.3)
-    helper_libtestdriver1_adjust_config "full"
-
-    # Disable the module that's accelerated
-    scripts/config.py unset MBEDTLS_DHM_C
-
-    # Disable things that depend on it
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
-
-    # Build
-    # -----
-
-    helper_libtestdriver1_make_drivers "$loc_accel_list"
-
-    helper_libtestdriver1_make_main "$loc_accel_list"
-
-    # Make sure this was not re-enabled by accident (additive config)
-    not grep mbedtls_dhm_ library/dhm.o
-
-    # Run the tests
-    # -------------
-
-    msg "test: full with accelerated FFDH"
-    make test
-
-    msg "ssl-opt: full with accelerated FFDH alg"
-    tests/ssl-opt.sh -f "ffdh"
-}
-
-component_test_psa_crypto_config_reference_ffdh () {
-    msg "build: full with non-accelerated FFDH"
-
-    # Start with full (USE_PSA and TLS 1.3)
-    helper_libtestdriver1_adjust_config "full"
-
-    # Disable things that are not supported
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
-    make
-
-    msg "test suites: full with non-accelerated FFDH alg"
-    make test
-
-    msg "ssl-opt: full with non-accelerated FFDH alg"
-    tests/ssl-opt.sh -f "ffdh"
-}
-
-component_test_psa_crypto_config_accel_pake() {
-    msg "build: full with accelerated PAKE"
-
-    loc_accel_list="ALG_JPAKE \
-                    $(helper_get_psa_key_type_list "ECC") \
-                    $(helper_get_psa_curve_list)"
-
-    # Configure
-    # ---------
-
-    helper_libtestdriver1_adjust_config "full"
-
-    # Make built-in fallback not available
-    scripts/config.py unset MBEDTLS_ECJPAKE_C
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
-
-    # Build
-    # -----
-
-    helper_libtestdriver1_make_drivers "$loc_accel_list"
-
-    helper_libtestdriver1_make_main "$loc_accel_list"
-
-    # Make sure this was not re-enabled by accident (additive config)
-    not grep mbedtls_ecjpake_init library/ecjpake.o
-
-    # Run the tests
-    # -------------
-
-    msg "test: full with accelerated PAKE"
-    make test
-}
-
-component_test_psa_crypto_config_accel_ecc_some_key_types () {
-    msg "build: full with accelerated EC algs and some key types"
-
-    # Algorithms and key types to accelerate
-    # For key types, use an explicitly list to omit GENERATE (and DERIVE)
-    loc_accel_list="ALG_ECDSA ALG_DETERMINISTIC_ECDSA \
-                    ALG_ECDH \
-                    ALG_JPAKE \
-                    KEY_TYPE_ECC_PUBLIC_KEY \
-                    KEY_TYPE_ECC_KEY_PAIR_BASIC \
-                    KEY_TYPE_ECC_KEY_PAIR_IMPORT \
-                    KEY_TYPE_ECC_KEY_PAIR_EXPORT \
-                    $(helper_get_psa_curve_list)"
-
-    # Configure
-    # ---------
-
-    # start with config full for maximum coverage (also enables USE_PSA)
-    helper_libtestdriver1_adjust_config "full"
-
-    # Disable modules that are accelerated - some will be re-enabled
-    scripts/config.py unset MBEDTLS_ECDSA_C
-    scripts/config.py unset MBEDTLS_ECDH_C
-    scripts/config.py unset MBEDTLS_ECJPAKE_C
-    scripts/config.py unset MBEDTLS_ECP_C
-
-    # Disable all curves - those that aren't accelerated should be re-enabled
-    helper_disable_builtin_curves
-
-    # Restartable feature is not yet supported by PSA. Once it will in
-    # the future, the following line could be removed (see issues
-    # 6061, 6332 and following ones)
-    scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
-
-    # this is not supported by the driver API yet
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE
-
-    # Build
-    # -----
-
-    # These hashes are needed for some ECDSA signature tests.
-    loc_extra_list="ALG_SHA_1 ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
-                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
-    helper_libtestdriver1_make_drivers "$loc_accel_list" "$loc_extra_list"
-
-    helper_libtestdriver1_make_main "$loc_accel_list"
-
-    # ECP should be re-enabled but not the others
-    not grep mbedtls_ecdh_ library/ecdh.o
-    not grep mbedtls_ecdsa library/ecdsa.o
-    not grep mbedtls_ecjpake  library/ecjpake.o
-    grep mbedtls_ecp library/ecp.o
-
-    # Run the tests
-    # -------------
-
-    msg "test suites: full with accelerated EC algs and some key types"
-    make test
-}
-
-# Run tests with only (non-)Weierstrass accelerated
-# Common code used in:
-# - component_test_psa_crypto_config_accel_ecc_weierstrass_curves
-# - component_test_psa_crypto_config_accel_ecc_non_weierstrass_curves
-common_test_psa_crypto_config_accel_ecc_some_curves () {
-    weierstrass=$1
-    if [ $weierstrass -eq 1 ]; then
-        desc="Weierstrass"
-    else
-        desc="non-Weierstrass"
-    fi
-
-    msg "build: crypto_full minus PK with accelerated EC algs and $desc curves"
-
-    # Note: Curves are handled in a special way by the libtestdriver machinery,
-    # so we only want to include them in the accel list when building the main
-    # libraries, hence the use of a separate variable.
-    # Note: the following loop is a modified version of
-    # helper_get_psa_curve_list that only keeps Weierstrass families.
-    loc_weierstrass_list=""
-    loc_non_weierstrass_list=""
-    for item in $(sed -n 's/^#define PSA_WANT_\(ECC_[0-9A-Z_a-z]*\).*/\1/p' <"$CRYPTO_CONFIG_H"); do
-        case $item in
-            ECC_BRAINPOOL*|ECC_SECP*)
-                loc_weierstrass_list="$loc_weierstrass_list $item"
-                ;;
-            *)
-                loc_non_weierstrass_list="$loc_non_weierstrass_list $item"
-                ;;
-        esac
-    done
-    if [ $weierstrass -eq 1 ]; then
-        loc_curve_list=$loc_weierstrass_list
-    else
-        loc_curve_list=$loc_non_weierstrass_list
-    fi
-
-    # Algorithms and key types to accelerate
-    loc_accel_list="ALG_ECDSA ALG_DETERMINISTIC_ECDSA \
-                    ALG_ECDH \
-                    ALG_JPAKE \
-                    $(helper_get_psa_key_type_list "ECC") \
-                    $loc_curve_list"
-
-    # Configure
-    # ---------
-
-    # Start with config crypto_full and remove PK_C:
-    # that's what's supported now, see docs/driver-only-builds.md.
-    helper_libtestdriver1_adjust_config "crypto_full"
-    scripts/config.py unset MBEDTLS_PK_C
-    scripts/config.py unset MBEDTLS_PK_PARSE_C
-    scripts/config.py unset MBEDTLS_PK_WRITE_C
-
-    # Disable modules that are accelerated - some will be re-enabled
-    scripts/config.py unset MBEDTLS_ECDSA_C
-    scripts/config.py unset MBEDTLS_ECDH_C
-    scripts/config.py unset MBEDTLS_ECJPAKE_C
-    scripts/config.py unset MBEDTLS_ECP_C
-
-    # Disable all curves - those that aren't accelerated should be re-enabled
-    helper_disable_builtin_curves
-
-    # Restartable feature is not yet supported by PSA. Once it will in
-    # the future, the following line could be removed (see issues
-    # 6061, 6332 and following ones)
-    scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
-
-    # this is not supported by the driver API yet
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE
-
-    # Build
-    # -----
-
-    # These hashes are needed for some ECDSA signature tests.
-    loc_extra_list="ALG_SHA_1 ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
-                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
-    helper_libtestdriver1_make_drivers "$loc_accel_list" "$loc_extra_list"
-
-    helper_libtestdriver1_make_main "$loc_accel_list"
-
-    # We expect ECDH to be re-enabled for the missing curves
-    grep mbedtls_ecdh_ library/ecdh.o
-    # We expect ECP to be re-enabled, however the parts specific to the
-    # families of curves that are accelerated should be ommited.
-    # - functions with mxz in the name are specific to Montgomery curves
-    # - ecp_muladd is specific to Weierstrass curves
-    ##nm library/ecp.o | tee ecp.syms
-    if [ $weierstrass -eq 1 ]; then
-        not grep mbedtls_ecp_muladd library/ecp.o
-        grep mxz library/ecp.o
-    else
-        grep mbedtls_ecp_muladd library/ecp.o
-        not grep mxz library/ecp.o
-    fi
-    # We expect ECDSA and ECJPAKE to be re-enabled only when
-    # Weierstrass curves are not accelerated
-    if [ $weierstrass -eq 1 ]; then
-        not grep mbedtls_ecdsa library/ecdsa.o
-        not grep mbedtls_ecjpake  library/ecjpake.o
-    else
-        grep mbedtls_ecdsa library/ecdsa.o
-        grep mbedtls_ecjpake  library/ecjpake.o
-    fi
-
-    # Run the tests
-    # -------------
-
-    msg "test suites: crypto_full minus PK with accelerated EC algs and $desc curves"
-    make test
-}
-
-component_test_psa_crypto_config_accel_ecc_weierstrass_curves () {
-    common_test_psa_crypto_config_accel_ecc_some_curves 1
-}
-
-component_test_psa_crypto_config_accel_ecc_non_weierstrass_curves () {
-    common_test_psa_crypto_config_accel_ecc_some_curves 0
-}
-
-# Auxiliary function to build config for all EC based algorithms (EC-JPAKE,
-# ECDH, ECDSA) with and without drivers.
-# The input parameter is a boolean value which indicates:
-# - 0 keep built-in EC algs,
-# - 1 exclude built-in EC algs (driver only).
-#
-# This is used by the two following components to ensure they always use the
-# same config, except for the use of driver or built-in EC algorithms:
-# - component_test_psa_crypto_config_accel_ecc_ecp_light_only;
-# - component_test_psa_crypto_config_reference_ecc_ecp_light_only.
-# This supports comparing their test coverage with analyze_outcomes.py.
-config_psa_crypto_config_ecp_light_only () {
-    driver_only="$1"
-    # start with config full for maximum coverage (also enables USE_PSA)
-    helper_libtestdriver1_adjust_config "full"
-    if [ "$driver_only" -eq 1 ]; then
-        # Disable modules that are accelerated
-        scripts/config.py unset MBEDTLS_ECDSA_C
-        scripts/config.py unset MBEDTLS_ECDH_C
-        scripts/config.py unset MBEDTLS_ECJPAKE_C
-        scripts/config.py unset MBEDTLS_ECP_C
-    fi
-
-    # Restartable feature is not yet supported by PSA. Once it will in
-    # the future, the following line could be removed (see issues
-    # 6061, 6332 and following ones)
-    scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
-}
-
-# Keep in sync with component_test_psa_crypto_config_reference_ecc_ecp_light_only
-component_test_psa_crypto_config_accel_ecc_ecp_light_only () {
-    msg "build: full with accelerated EC algs"
-
-    # Algorithms and key types to accelerate
-    loc_accel_list="ALG_ECDSA ALG_DETERMINISTIC_ECDSA \
-                    ALG_ECDH \
-                    ALG_JPAKE \
-                    $(helper_get_psa_key_type_list "ECC") \
-                    $(helper_get_psa_curve_list)"
-
-    # Configure
-    # ---------
-
-    # Use the same config as reference, only without built-in EC algs
-    config_psa_crypto_config_ecp_light_only 1
-
-    # Do not disable builtin curves because that support is required for:
-    # - MBEDTLS_PK_PARSE_EC_EXTENDED
-    # - MBEDTLS_PK_PARSE_EC_COMPRESSED
-
-    # Build
-    # -----
-
-    # These hashes are needed for some ECDSA signature tests.
-    loc_extra_list="ALG_SHA_1 ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
-                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
-    helper_libtestdriver1_make_drivers "$loc_accel_list" "$loc_extra_list"
-
-    helper_libtestdriver1_make_main "$loc_accel_list"
-
-    # Make sure any built-in EC alg was not re-enabled by accident (additive config)
-    not grep mbedtls_ecdsa_ library/ecdsa.o
-    not grep mbedtls_ecdh_ library/ecdh.o
-    not grep mbedtls_ecjpake_ library/ecjpake.o
-    not grep mbedtls_ecp_mul library/ecp.o
-
-    # Run the tests
-    # -------------
-
-    msg "test suites: full with accelerated EC algs"
-    make test
-
-    msg "ssl-opt: full with accelerated EC algs"
-    tests/ssl-opt.sh
-}
-
-# Keep in sync with component_test_psa_crypto_config_accel_ecc_ecp_light_only
-component_test_psa_crypto_config_reference_ecc_ecp_light_only () {
-    msg "build: MBEDTLS_PSA_CRYPTO_CONFIG with non-accelerated EC algs"
-
-    config_psa_crypto_config_ecp_light_only 0
-
-    make
-
-    msg "test suites: full with non-accelerated EC algs"
-    make test
-
-    msg "ssl-opt: full with non-accelerated EC algs"
-    tests/ssl-opt.sh
-}
-
-# This helper function is used by:
-# - component_test_psa_crypto_config_accel_ecc_no_ecp_at_all()
-# - component_test_psa_crypto_config_reference_ecc_no_ecp_at_all()
-# to ensure that both tests use the same underlying configuration when testing
-# driver's coverage with analyze_outcomes.py.
-#
-# This functions accepts 1 boolean parameter as follows:
-# - 1: building with accelerated EC algorithms (ECDSA, ECDH, ECJPAKE), therefore
-#      excluding their built-in implementation as well as ECP_C & ECP_LIGHT
-# - 0: include built-in implementation of EC algorithms.
-#
-# PK_C and RSA_C are always disabled to ensure there is no remaining dependency
-# on the ECP module.
-config_psa_crypto_no_ecp_at_all () {
-    driver_only="$1"
-    # start with full config for maximum coverage (also enables USE_PSA)
-    helper_libtestdriver1_adjust_config "full"
-
-    if [ "$driver_only" -eq 1 ]; then
-        # Disable modules that are accelerated
-        scripts/config.py unset MBEDTLS_ECDSA_C
-        scripts/config.py unset MBEDTLS_ECDH_C
-        scripts/config.py unset MBEDTLS_ECJPAKE_C
-        # Disable ECP module (entirely)
-        scripts/config.py unset MBEDTLS_ECP_C
-    fi
-
-    # Disable all the features that auto-enable ECP_LIGHT (see build_info.h)
-    scripts/config.py unset MBEDTLS_PK_PARSE_EC_EXTENDED
-    scripts/config.py unset MBEDTLS_PK_PARSE_EC_COMPRESSED
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE
-
-    # Restartable feature is not yet supported by PSA. Once it will in
-    # the future, the following line could be removed (see issues
-    # 6061, 6332 and following ones)
-    scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
-}
-
-# Build and test a configuration where driver accelerates all EC algs while
-# all support and dependencies from ECP and ECP_LIGHT are removed on the library
-# side.
-#
-# Keep in sync with component_test_psa_crypto_config_reference_ecc_no_ecp_at_all()
-component_test_psa_crypto_config_accel_ecc_no_ecp_at_all () {
-    msg "build: full + accelerated EC algs - ECP"
-
-    # Algorithms and key types to accelerate
-    loc_accel_list="ALG_ECDSA ALG_DETERMINISTIC_ECDSA \
-                    ALG_ECDH \
-                    ALG_JPAKE \
-                    $(helper_get_psa_key_type_list "ECC") \
-                    $(helper_get_psa_curve_list)"
-
-    # Configure
-    # ---------
-
-    # Set common configurations between library's and driver's builds
-    config_psa_crypto_no_ecp_at_all 1
-    # Disable all the builtin curves. All the required algs are accelerated.
-    helper_disable_builtin_curves
-
-    # Build
-    # -----
-
-    # Things we wanted supported in libtestdriver1, but not accelerated in the main library:
-    # SHA-1 and all SHA-2/3 variants, as they are used by ECDSA deterministic.
-    loc_extra_list="ALG_SHA_1 ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
-                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
-
-    helper_libtestdriver1_make_drivers "$loc_accel_list" "$loc_extra_list"
-
-    helper_libtestdriver1_make_main "$loc_accel_list"
-
-    # Make sure any built-in EC alg was not re-enabled by accident (additive config)
-    not grep mbedtls_ecdsa_ library/ecdsa.o
-    not grep mbedtls_ecdh_ library/ecdh.o
-    not grep mbedtls_ecjpake_ library/ecjpake.o
-    # Also ensure that ECP module was not re-enabled
-    not grep mbedtls_ecp_ library/ecp.o
-
-    # Run the tests
-    # -------------
-
-    msg "test: full + accelerated EC algs - ECP"
-    make test
-
-    msg "ssl-opt: full + accelerated EC algs - ECP"
-    tests/ssl-opt.sh
-}
-
-# Reference function used for driver's coverage analysis in analyze_outcomes.py
-# in conjunction with component_test_psa_crypto_config_accel_ecc_no_ecp_at_all().
-# Keep in sync with its accelerated counterpart.
-component_test_psa_crypto_config_reference_ecc_no_ecp_at_all () {
-    msg "build: full + non accelerated EC algs"
-
-    config_psa_crypto_no_ecp_at_all 0
-
-    make
-
-    msg "test: full + non accelerated EC algs"
-    make test
-
-    msg "ssl-opt: full + non accelerated EC algs"
-    tests/ssl-opt.sh
-}
-
-# This is a common configuration helper used directly from:
-# - common_test_psa_crypto_config_accel_ecc_ffdh_no_bignum
-# - common_test_psa_crypto_config_reference_ecc_ffdh_no_bignum
-# and indirectly from:
-# - component_test_psa_crypto_config_accel_ecc_no_bignum
-#       - accelerate all EC algs, disable RSA and FFDH
-# - component_test_psa_crypto_config_reference_ecc_no_bignum
-#       - this is the reference component of the above
-#       - it still disables RSA and FFDH, but it uses builtin EC algs
-# - component_test_psa_crypto_config_accel_ecc_ffdh_no_bignum
-#       - accelerate all EC and FFDH algs, disable only RSA
-# - component_test_psa_crypto_config_reference_ecc_ffdh_no_bignum
-#       - this is the reference component of the above
-#       - it still disables RSA, but it uses builtin EC and FFDH algs
-#
-# This function accepts 2 parameters:
-# $1: a boolean value which states if we are testing an accelerated scenario
-#     or not.
-# $2: a string value which states which components are tested. Allowed values
-#     are "ECC" or "ECC_DH".
-config_psa_crypto_config_accel_ecc_ffdh_no_bignum() {
-    driver_only="$1"
-    test_target="$2"
-    # start with full config for maximum coverage (also enables USE_PSA)
-    helper_libtestdriver1_adjust_config "full"
-
-    if [ "$driver_only" -eq 1 ]; then
-        # Disable modules that are accelerated
-        scripts/config.py unset MBEDTLS_ECDSA_C
-        scripts/config.py unset MBEDTLS_ECDH_C
-        scripts/config.py unset MBEDTLS_ECJPAKE_C
-        # Disable ECP module (entirely)
-        scripts/config.py unset MBEDTLS_ECP_C
-        # Also disable bignum
-        scripts/config.py unset MBEDTLS_BIGNUM_C
-    fi
-
-    # Disable all the features that auto-enable ECP_LIGHT (see build_info.h)
-    scripts/config.py unset MBEDTLS_PK_PARSE_EC_EXTENDED
-    scripts/config.py unset MBEDTLS_PK_PARSE_EC_COMPRESSED
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE
-
-    # RSA support is intentionally disabled on this test because RSA_C depends
-    # on BIGNUM_C.
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset-all "PSA_WANT_KEY_TYPE_RSA_[0-9A-Z_a-z]*"
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset-all "PSA_WANT_ALG_RSA_[0-9A-Z_a-z]*"
-    scripts/config.py unset MBEDTLS_RSA_C
-    scripts/config.py unset MBEDTLS_PKCS1_V15
-    scripts/config.py unset MBEDTLS_PKCS1_V21
-    scripts/config.py unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
-    # Also disable key exchanges that depend on RSA
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
-
-    if [ "$test_target" = "ECC" ]; then
-        # When testing ECC only, we disable FFDH support, both from builtin and
-        # PSA sides, and also disable the key exchanges that depend on DHM.
-        scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_FFDH
-        scripts/config.py -f "$CRYPTO_CONFIG_H" unset-all "PSA_WANT_KEY_TYPE_DH_[0-9A-Z_a-z]*"
-        scripts/config.py -f "$CRYPTO_CONFIG_H" unset-all "PSA_WANT_DH_RFC7919_[0-9]*"
-        scripts/config.py unset MBEDTLS_DHM_C
-        scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
-        scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
-    else
-        # When testing ECC and DH instead, we disable DHM and depending key
-        # exchanges only in the accelerated build
-        if [ "$driver_only" -eq 1 ]; then
-            scripts/config.py unset MBEDTLS_DHM_C
-            scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
-            scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
-        fi
-    fi
-
-    # Restartable feature is not yet supported by PSA. Once it will in
-    # the future, the following line could be removed (see issues
-    # 6061, 6332 and following ones)
-    scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
-}
-
-# Common helper used by:
-# - component_test_psa_crypto_config_accel_ecc_no_bignum
-# - component_test_psa_crypto_config_accel_ecc_ffdh_no_bignum
-#
-# The goal is to build and test accelerating either:
-# - ECC only or
-# - both ECC and FFDH
-#
-# It is meant to be used in conjunction with
-# common_test_psa_crypto_config_reference_ecc_ffdh_no_bignum() for drivers
-# coverage analysis in the "analyze_outcomes.py" script.
-common_test_psa_crypto_config_accel_ecc_ffdh_no_bignum () {
-    test_target="$1"
-
-    # This is an internal helper to simplify text message handling
-    if [ "$test_target" = "ECC_DH" ]; then
-        accel_text="ECC/FFDH"
-        removed_text="ECP - DH"
-    else
-        accel_text="ECC"
-        removed_text="ECP"
-    fi
-
-    msg "build: full + accelerated $accel_text algs + USE_PSA - $removed_text - BIGNUM"
-
-    # By default we accelerate all EC keys/algs
-    loc_accel_list="ALG_ECDSA ALG_DETERMINISTIC_ECDSA \
-                    ALG_ECDH \
-                    ALG_JPAKE \
-                    $(helper_get_psa_key_type_list "ECC") \
-                    $(helper_get_psa_curve_list)"
-    # Optionally we can also add DH to the list of accelerated items
-    if [ "$test_target" = "ECC_DH" ]; then
-        loc_accel_list="$loc_accel_list \
-                        ALG_FFDH \
-                        $(helper_get_psa_key_type_list "DH") \
-                        $(helper_get_psa_dh_group_list)"
-    fi
-
-    # Configure
-    # ---------
-
-    # Set common configurations between library's and driver's builds
-    config_psa_crypto_config_accel_ecc_ffdh_no_bignum 1 "$test_target"
-    # Disable all the builtin curves. All the required algs are accelerated.
-    helper_disable_builtin_curves
-
-    # Build
-    # -----
-
-    # Things we wanted supported in libtestdriver1, but not accelerated in the main library:
-    # SHA-1 and all SHA-2/3 variants, as they are used by ECDSA deterministic.
-    loc_extra_list="ALG_SHA_1 ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
-                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
-
-    helper_libtestdriver1_make_drivers "$loc_accel_list" "$loc_extra_list"
-
-    helper_libtestdriver1_make_main "$loc_accel_list"
-
-    # Make sure any built-in EC alg was not re-enabled by accident (additive config)
-    not grep mbedtls_ecdsa_ library/ecdsa.o
-    not grep mbedtls_ecdh_ library/ecdh.o
-    not grep mbedtls_ecjpake_ library/ecjpake.o
-    # Also ensure that ECP, RSA, [DHM] or BIGNUM modules were not re-enabled
-    not grep mbedtls_ecp_ library/ecp.o
-    not grep mbedtls_rsa_ library/rsa.o
-    not grep mbedtls_mpi_ library/bignum.o
-    not grep mbedtls_dhm_ library/dhm.o
-
-    # Run the tests
-    # -------------
-
-    msg "test suites: full + accelerated $accel_text algs + USE_PSA - $removed_text - DHM - BIGNUM"
-
-    make test
-
-    msg "ssl-opt: full + accelerated $accel_text algs + USE_PSA - $removed_text - BIGNUM"
-    tests/ssl-opt.sh
-}
-
-# Common helper used by:
-# - component_test_psa_crypto_config_reference_ecc_no_bignum
-# - component_test_psa_crypto_config_reference_ecc_ffdh_no_bignum
-#
-# The goal is to build and test a reference scenario (i.e. with builtin
-# components) compared to the ones used in
-# common_test_psa_crypto_config_accel_ecc_ffdh_no_bignum() above.
-#
-# It is meant to be used in conjunction with
-# common_test_psa_crypto_config_accel_ecc_ffdh_no_bignum() for drivers'
-# coverage analysis in "analyze_outcomes.py" script.
-common_test_psa_crypto_config_reference_ecc_ffdh_no_bignum () {
-    test_target="$1"
-
-    # This is an internal helper to simplify text message handling
-    if [ "$test_target" = "ECC_DH" ]; then
-        accel_text="ECC/FFDH"
-    else
-        accel_text="ECC"
-    fi
-
-    msg "build: full + non accelerated $accel_text algs + USE_PSA"
-
-    config_psa_crypto_config_accel_ecc_ffdh_no_bignum 0 "$test_target"
-
-    make
-
-    msg "test suites: full + non accelerated EC algs + USE_PSA"
-    make test
-
-    msg "ssl-opt: full + non accelerated $accel_text algs + USE_PSA"
-    tests/ssl-opt.sh
-}
-
-component_test_psa_crypto_config_accel_ecc_no_bignum () {
-    common_test_psa_crypto_config_accel_ecc_ffdh_no_bignum "ECC"
-}
-
-component_test_psa_crypto_config_reference_ecc_no_bignum () {
-    common_test_psa_crypto_config_reference_ecc_ffdh_no_bignum "ECC"
-}
-
-component_test_psa_crypto_config_accel_ecc_ffdh_no_bignum () {
-    common_test_psa_crypto_config_accel_ecc_ffdh_no_bignum "ECC_DH"
-}
-
-component_test_psa_crypto_config_reference_ecc_ffdh_no_bignum () {
-    common_test_psa_crypto_config_reference_ecc_ffdh_no_bignum "ECC_DH"
-}
-
-# Helper for setting common configurations between:
-# - component_test_tfm_config_p256m_driver_accel_ec()
-# - component_test_tfm_config()
-common_tfm_config () {
-    # Enable TF-M config
-    cp configs/config-tfm.h "$CONFIG_H"
-    echo "#undef MBEDTLS_PSA_CRYPTO_CONFIG_FILE" >> "$CONFIG_H"
-    cp configs/ext/crypto_config_profile_medium.h "$CRYPTO_CONFIG_H"
-
-    # Other config adjustment to make the tests pass.
-    # This should probably be adopted upstream.
-    #
-    # - USE_PSA_CRYPTO for PK_HAVE_ECC_KEYS
-    echo "#define MBEDTLS_USE_PSA_CRYPTO" >> "$CONFIG_H"
-
-    # Config adjustment for better test coverage in our environment.
-    # This is not needed just to build and pass tests.
-    #
-    # Enable filesystem I/O for the benefit of PK parse/write tests.
-    echo "#define MBEDTLS_FS_IO" >> "$CONFIG_H"
-}
-
-# Keep this in sync with component_test_tfm_config() as they are both meant
-# to be used in analyze_outcomes.py for driver's coverage analysis.
-component_test_tfm_config_p256m_driver_accel_ec () {
-    msg "build: TF-M config + p256m driver + accel ECDH(E)/ECDSA"
-
-    common_tfm_config
-
-    # Build crypto library
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -I../tests/include/spe" LDFLAGS="$ASAN_CFLAGS"
-
-    # Make sure any built-in EC alg was not re-enabled by accident (additive config)
-    not grep mbedtls_ecdsa_ library/ecdsa.o
-    not grep mbedtls_ecdh_ library/ecdh.o
-    not grep mbedtls_ecjpake_ library/ecjpake.o
-    # Also ensure that ECP, RSA, DHM or BIGNUM modules were not re-enabled
-    not grep mbedtls_ecp_ library/ecp.o
-    not grep mbedtls_rsa_ library/rsa.o
-    not grep mbedtls_dhm_ library/dhm.o
-    not grep mbedtls_mpi_ library/bignum.o
-    # Check that p256m was built
-    grep -q p256_ecdsa_ library/libmbedcrypto.a
-
-    # In "config-tfm.h" we disabled CIPHER_C tweaking TF-M's configuration
-    # files, so we want to ensure that it has not be re-enabled accidentally.
-    not grep mbedtls_cipher library/cipher.o
-
-    # Run the tests
-    msg "test: TF-M config + p256m driver + accel ECDH(E)/ECDSA"
-    make test
-}
-
-# Keep this in sync with component_test_tfm_config_p256m_driver_accel_ec() as
-# they are both meant to be used in analyze_outcomes.py for driver's coverage
-# analysis.
-component_test_tfm_config() {
-    common_tfm_config
-
-    # Disable P256M driver, which is on by default, so that analyze_outcomes
-    # can compare this test with test_tfm_config_p256m_driver_accel_ec
-    echo "#undef MBEDTLS_PSA_P256M_DRIVER_ENABLED" >> "$CONFIG_H"
-
-    msg "build: TF-M config"
-    make CFLAGS='-Werror -Wall -Wextra -I../tests/include/spe' tests
-
-    # Check that p256m was not built
-    not grep p256_ecdsa_ library/libmbedcrypto.a
-
-    # In "config-tfm.h" we disabled CIPHER_C tweaking TF-M's configuration
-    # files, so we want to ensure that it has not be re-enabled accidentally.
-    not grep mbedtls_cipher library/cipher.o
-
-    msg "test: TF-M config"
-    make test
-}
-
-# Common helper for component_full_without_ecdhe_ecdsa() and
-# component_full_without_ecdhe_ecdsa_and_tls13() which:
-# - starts from the "full" configuration minus the list of symbols passed in
-#   as 1st parameter
-# - build
-# - test only TLS (i.e. test_suite_tls and ssl-opt)
-build_full_minus_something_and_test_tls () {
-    symbols_to_disable="$1"
-
-    msg "build: full minus something, test TLS"
-
-    scripts/config.py full
-    for sym in $symbols_to_disable; do
-        echo "Disabling $sym"
-        scripts/config.py unset $sym
-    done
-
-    make
-
-    msg "test: full minus something, test TLS"
-    ( cd tests; ./test_suite_ssl )
-
-    msg "ssl-opt: full minus something, test TLS"
-    tests/ssl-opt.sh
-}
-
-component_full_without_ecdhe_ecdsa () {
-    build_full_minus_something_and_test_tls "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED"
-}
-
-component_full_without_ecdhe_ecdsa_and_tls13 () {
-    build_full_minus_something_and_test_tls "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
-                                             MBEDTLS_SSL_PROTO_TLS1_3"
-}
-
-# This is an helper used by:
-# - component_test_psa_ecc_key_pair_no_derive
-# - component_test_psa_ecc_key_pair_no_generate
-# The goal is to test with all PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_yyy symbols
-# enabled, but one. Input arguments are as follows:
-# - $1 is the key type under test, i.e. ECC/RSA/DH
-# - $2 is the key option to be unset (i.e. generate, derive, etc)
-build_and_test_psa_want_key_pair_partial() {
-    key_type=$1
-    unset_option=$2
-    disabled_psa_want="PSA_WANT_KEY_TYPE_${key_type}_KEY_PAIR_${unset_option}"
-
-    msg "build: full - MBEDTLS_USE_PSA_CRYPTO - ${disabled_psa_want}"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-
-    # All the PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_yyy are enabled by default in
-    # crypto_config.h so we just disable the one we don't want.
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset "$disabled_psa_want"
-
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
-
-    msg "test: full - MBEDTLS_USE_PSA_CRYPTO - ${disabled_psa_want}"
-    make test
-}
-
-component_test_psa_ecc_key_pair_no_derive() {
-    build_and_test_psa_want_key_pair_partial "ECC" "DERIVE"
-}
-
-component_test_psa_ecc_key_pair_no_generate() {
-    build_and_test_psa_want_key_pair_partial "ECC" "GENERATE"
-}
-
-config_psa_crypto_accel_rsa () {
-    driver_only=$1
-
-    # Start from crypto_full config (no X.509, no TLS)
-    helper_libtestdriver1_adjust_config "crypto_full"
-
-    if [ "$driver_only" -eq 1 ]; then
-        # Remove RSA support and its dependencies
-        scripts/config.py unset MBEDTLS_RSA_C
-        scripts/config.py unset MBEDTLS_PKCS1_V15
-        scripts/config.py unset MBEDTLS_PKCS1_V21
-
-        # We need PEM parsing in the test library as well to support the import
-        # of PEM encoded RSA keys.
-        scripts/config.py -f "$CONFIG_TEST_DRIVER_H" set MBEDTLS_PEM_PARSE_C
-        scripts/config.py -f "$CONFIG_TEST_DRIVER_H" set MBEDTLS_BASE64_C
-    fi
-}
-
-component_test_psa_crypto_config_accel_rsa_crypto () {
-    msg "build: crypto_full with accelerated RSA"
-
-    loc_accel_list="ALG_RSA_OAEP ALG_RSA_PSS \
-                    ALG_RSA_PKCS1V15_CRYPT ALG_RSA_PKCS1V15_SIGN \
-                    KEY_TYPE_RSA_PUBLIC_KEY \
-                    KEY_TYPE_RSA_KEY_PAIR_BASIC \
-                    KEY_TYPE_RSA_KEY_PAIR_GENERATE \
-                    KEY_TYPE_RSA_KEY_PAIR_IMPORT \
-                    KEY_TYPE_RSA_KEY_PAIR_EXPORT"
-
-    # Configure
-    # ---------
-
-    config_psa_crypto_accel_rsa 1
-
-    # Build
-    # -----
-
-    # These hashes are needed for unit tests.
-    loc_extra_list="ALG_SHA_1 ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
-                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512 ALG_MD5"
-    helper_libtestdriver1_make_drivers "$loc_accel_list" "$loc_extra_list"
-
-    helper_libtestdriver1_make_main "$loc_accel_list"
-
-    # Make sure this was not re-enabled by accident (additive config)
-    not grep mbedtls_rsa library/rsa.o
-
-    # Run the tests
-    # -------------
-
-    msg "test: crypto_full with accelerated RSA"
-    make test
-}
-
-component_test_psa_crypto_config_reference_rsa_crypto () {
-    msg "build: crypto_full with non-accelerated RSA"
-
-    # Configure
-    # ---------
-    config_psa_crypto_accel_rsa 0
-
-    # Build
-    # -----
-    make
-
-    # Run the tests
-    # -------------
-    msg "test: crypto_full with non-accelerated RSA"
-    make test
-}
-
-# This is a temporary test to verify that full RSA support is present even when
-# only one single new symbols (PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) is defined.
-component_test_new_psa_want_key_pair_symbol() {
-    msg "Build: crypto config - MBEDTLS_RSA_C + PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC"
-
-    # Create a temporary output file unless there is already one set
-    if [ "$MBEDTLS_TEST_OUTCOME_FILE" ]; then
-        REMOVE_OUTCOME_ON_EXIT="no"
-    else
-        REMOVE_OUTCOME_ON_EXIT="yes"
-        MBEDTLS_TEST_OUTCOME_FILE="$PWD/out.csv"
-        export MBEDTLS_TEST_OUTCOME_FILE
-    fi
-
-    # Start from crypto configuration
-    scripts/config.py crypto
-
-    # Remove RSA support and its dependencies
-    scripts/config.py unset MBEDTLS_PKCS1_V15
-    scripts/config.py unset MBEDTLS_PKCS1_V21
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
-    scripts/config.py unset MBEDTLS_RSA_C
-    scripts/config.py unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
-
-    # Enable PSA support
-    scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
-
-    # Keep only PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC enabled in order to ensure
-    # that proper translations is done in crypto_legacy.h.
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE
-
-    make
-
-    msg "Test: crypto config - MBEDTLS_RSA_C + PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC"
-    make test
-
-    # Parse only 1 relevant line from the outcome file, i.e. a test which is
-    # performing RSA signature.
-    msg "Verify that 'RSA PKCS1 Sign #1 (SHA512, 1536 bits RSA)' is PASS"
-    cat $MBEDTLS_TEST_OUTCOME_FILE | grep 'RSA PKCS1 Sign #1 (SHA512, 1536 bits RSA)' | grep -q "PASS"
-
-    if [ "$REMOVE_OUTCOME_ON_EXIT" == "yes" ]; then
-        rm $MBEDTLS_TEST_OUTCOME_FILE
-    fi
-}
-
-component_test_psa_crypto_config_accel_hash () {
-    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated hash"
-
-    loc_accel_list="ALG_MD5 ALG_RIPEMD160 ALG_SHA_1 \
-                    ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
-                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
-
-    # Configure
-    # ---------
-
-    # Start from default config (no USE_PSA)
-    helper_libtestdriver1_adjust_config "default"
-
-    # Disable the things that are being accelerated
-    scripts/config.py unset MBEDTLS_MD5_C
-    scripts/config.py unset MBEDTLS_RIPEMD160_C
-    scripts/config.py unset MBEDTLS_SHA1_C
-    scripts/config.py unset MBEDTLS_SHA224_C
-    scripts/config.py unset MBEDTLS_SHA256_C
-    scripts/config.py unset MBEDTLS_SHA384_C
-    scripts/config.py unset MBEDTLS_SHA512_C
-    scripts/config.py unset MBEDTLS_SHA3_C
-
-    # Build
-    # -----
-
-    helper_libtestdriver1_make_drivers "$loc_accel_list"
-
-    helper_libtestdriver1_make_main "$loc_accel_list"
-
-    # There's a risk of something getting re-enabled via config_psa.h;
-    # make sure it did not happen. Note: it's OK for MD_C to be enabled.
-    not grep mbedtls_md5 library/md5.o
-    not grep mbedtls_sha1 library/sha1.o
-    not grep mbedtls_sha256 library/sha256.o
-    not grep mbedtls_sha512 library/sha512.o
-    not grep mbedtls_ripemd160 library/ripemd160.o
-
-    # Run the tests
-    # -------------
-
-    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated hash"
-    make test
-}
-
-component_test_psa_crypto_config_accel_hash_keep_builtins () {
-    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated+builtin hash"
-    # This component ensures that all the test cases for
-    # md_psa_dynamic_dispatch with legacy+driver in test_suite_md are run.
-
-    loc_accel_list="ALG_MD5 ALG_RIPEMD160 ALG_SHA_1 \
-                    ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
-                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
-
-    # Start from default config (no USE_PSA)
-    helper_libtestdriver1_adjust_config "default"
-
-    helper_libtestdriver1_make_drivers "$loc_accel_list"
-
-    helper_libtestdriver1_make_main "$loc_accel_list"
-
-    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated+builtin hash"
-    make test
-}
-
-# Auxiliary function to build config for hashes with and without drivers
-config_psa_crypto_hash_use_psa () {
-    driver_only="$1"
-    # start with config full for maximum coverage (also enables USE_PSA)
-    helper_libtestdriver1_adjust_config "full"
-    if [ "$driver_only" -eq 1 ]; then
-        # disable the built-in implementation of hashes
-        scripts/config.py unset MBEDTLS_MD5_C
-        scripts/config.py unset MBEDTLS_RIPEMD160_C
-        scripts/config.py unset MBEDTLS_SHA1_C
-        scripts/config.py unset MBEDTLS_SHA224_C
-        scripts/config.py unset MBEDTLS_SHA256_C # see external RNG below
-        scripts/config.py unset MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
-        scripts/config.py unset MBEDTLS_SHA384_C
-        scripts/config.py unset MBEDTLS_SHA512_C
-        scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
-        scripts/config.py unset MBEDTLS_SHA3_C
-    fi
-}
-
-# Note that component_test_psa_crypto_config_reference_hash_use_psa
-# is related to this component and both components need to be kept in sync.
-# For details please see comments for component_test_psa_crypto_config_reference_hash_use_psa.
-component_test_psa_crypto_config_accel_hash_use_psa () {
-    msg "test: full with accelerated hashes"
-
-    loc_accel_list="ALG_MD5 ALG_RIPEMD160 ALG_SHA_1 \
-                    ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
-                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
-
-    # Configure
-    # ---------
-
-    config_psa_crypto_hash_use_psa 1
-
-    # Build
-    # -----
-
-    helper_libtestdriver1_make_drivers "$loc_accel_list"
-
-    helper_libtestdriver1_make_main "$loc_accel_list"
-
-    # There's a risk of something getting re-enabled via config_psa.h;
-    # make sure it did not happen. Note: it's OK for MD_C to be enabled.
-    not grep mbedtls_md5 library/md5.o
-    not grep mbedtls_sha1 library/sha1.o
-    not grep mbedtls_sha256 library/sha256.o
-    not grep mbedtls_sha512 library/sha512.o
-    not grep mbedtls_ripemd160 library/ripemd160.o
-
-    # Run the tests
-    # -------------
-
-    msg "test: full with accelerated hashes"
-    make test
-
-    # This is mostly useful so that we can later compare outcome files with
-    # the reference config in analyze_outcomes.py, to check that the
-    # dependency declarations in ssl-opt.sh and in TLS code are correct.
-    msg "test: ssl-opt.sh, full with accelerated hashes"
-    tests/ssl-opt.sh
-
-    # This is to make sure all ciphersuites are exercised, but we don't need
-    # interop testing (besides, we already got some from ssl-opt.sh).
-    msg "test: compat.sh, full with accelerated hashes"
-    tests/compat.sh -p mbedTLS -V YES
-}
-
-# This component provides reference configuration for test_psa_crypto_config_accel_hash_use_psa
-# without accelerated hash. The outcome from both components are used by the analyze_outcomes.py
-# script to find regression in test coverage when accelerated hash is used (tests and ssl-opt).
-# Both components need to be kept in sync.
-component_test_psa_crypto_config_reference_hash_use_psa() {
-    msg "test: full without accelerated hashes"
-
-    config_psa_crypto_hash_use_psa 0
-
-    make
-
-    msg "test: full without accelerated hashes"
-    make test
-
-    msg "test: ssl-opt.sh, full without accelerated hashes"
-    tests/ssl-opt.sh
-}
-
-# Auxiliary function to build config for hashes with and without drivers
-config_psa_crypto_hmac_use_psa () {
-    driver_only="$1"
-    # start with config full for maximum coverage (also enables USE_PSA)
-    helper_libtestdriver1_adjust_config "full"
-
-    if [ "$driver_only" -eq 1 ]; then
-        # Disable MD_C in order to disable the builtin support for HMAC. MD_LIGHT
-        # is still enabled though (for ENTROPY_C among others).
-        scripts/config.py unset MBEDTLS_MD_C
-        # Disable also the builtin hashes since they are supported by the driver
-        # and MD module is able to perform PSA dispathing.
-        scripts/config.py unset-all MBEDTLS_SHA
-        scripts/config.py unset MBEDTLS_MD5_C
-        scripts/config.py unset MBEDTLS_RIPEMD160_C
-    fi
-
-    # Direct dependencies of MD_C. We disable them also in the reference
-    # component to work with the same set of features.
-    scripts/config.py unset MBEDTLS_PKCS7_C
-    scripts/config.py unset MBEDTLS_PKCS5_C
-    scripts/config.py unset MBEDTLS_HMAC_DRBG_C
-    scripts/config.py unset MBEDTLS_HKDF_C
-    # Dependencies of HMAC_DRBG
-    scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_DETERMINISTIC_ECDSA
-}
-
-component_test_psa_crypto_config_accel_hmac() {
-    msg "test: full with accelerated hmac"
-
-    loc_accel_list="ALG_HMAC KEY_TYPE_HMAC \
-                    ALG_MD5 ALG_RIPEMD160 ALG_SHA_1 \
-                    ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
-                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
-
-    # Configure
-    # ---------
-
-    config_psa_crypto_hmac_use_psa 1
-
-    # Build
-    # -----
-
-    helper_libtestdriver1_make_drivers "$loc_accel_list"
-
-    helper_libtestdriver1_make_main "$loc_accel_list"
-
-    # Ensure that built-in support for HMAC is disabled.
-    not grep mbedtls_md_hmac library/md.o
-
-    # Run the tests
-    # -------------
-
-    msg "test: full with accelerated hmac"
-    make test
-}
-
-component_test_psa_crypto_config_reference_hmac() {
-    msg "test: full without accelerated hmac"
-
-    config_psa_crypto_hmac_use_psa 0
-
-    make
-
-    msg "test: full without accelerated hmac"
-    make test
-}
-
-component_test_psa_crypto_config_accel_des () {
-    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated DES"
-
-    # Albeit this components aims at accelerating DES which should only support
-    # CBC and ECB modes, we need to accelerate more than that otherwise DES_C
-    # would automatically be re-enabled by "config_adjust_legacy_from_psa.c"
-    loc_accel_list="ALG_ECB_NO_PADDING ALG_CBC_NO_PADDING ALG_CBC_PKCS7 \
-                    ALG_CTR ALG_CFB ALG_OFB ALG_XTS ALG_CMAC \
-                    KEY_TYPE_DES"
-
-    # Note: we cannot accelerate all ciphers' key types otherwise we would also
-    # have to either disable CCM/GCM or accelerate them, but that's out of scope
-    # of this component. This limitation will be addressed by #8598.
-
-    # Configure
-    # ---------
-
-    # Start from the full config
-    helper_libtestdriver1_adjust_config "full"
-
-    # Disable the things that are being accelerated
-    scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
-    scripts/config.py unset MBEDTLS_CIPHER_PADDING_PKCS7
-    scripts/config.py unset MBEDTLS_CIPHER_MODE_CTR
-    scripts/config.py unset MBEDTLS_CIPHER_MODE_CFB
-    scripts/config.py unset MBEDTLS_CIPHER_MODE_OFB
-    scripts/config.py unset MBEDTLS_CIPHER_MODE_XTS
-    scripts/config.py unset MBEDTLS_DES_C
-    scripts/config.py unset MBEDTLS_CMAC_C
-
-    # Build
-    # -----
-
-    helper_libtestdriver1_make_drivers "$loc_accel_list"
-
-    helper_libtestdriver1_make_main "$loc_accel_list"
-
-    # Make sure this was not re-enabled by accident (additive config)
-    not grep mbedtls_des* library/des.o
-
-    # Run the tests
-    # -------------
-
-    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated DES"
-    make test
-}
-
-component_test_psa_crypto_config_accel_aead () {
-    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated AEAD"
-
-    loc_accel_list="ALG_GCM ALG_CCM ALG_CHACHA20_POLY1305 \
-                    KEY_TYPE_AES KEY_TYPE_CHACHA20 KEY_TYPE_ARIA KEY_TYPE_CAMELLIA"
-
-    # Configure
-    # ---------
-
-    # Start from full config
-    helper_libtestdriver1_adjust_config "full"
-
-    # Disable things that are being accelerated
-    scripts/config.py unset MBEDTLS_GCM_C
-    scripts/config.py unset MBEDTLS_CCM_C
-    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
-
-    # Disable CCM_STAR_NO_TAG because this re-enables CCM_C.
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CCM_STAR_NO_TAG
-
-    # Build
-    # -----
-
-    helper_libtestdriver1_make_drivers "$loc_accel_list"
-
-    helper_libtestdriver1_make_main "$loc_accel_list"
-
-    # Make sure this was not re-enabled by accident (additive config)
-    not grep mbedtls_ccm library/ccm.o
-    not grep mbedtls_gcm library/gcm.o
-    not grep mbedtls_chachapoly library/chachapoly.o
-
-    # Run the tests
-    # -------------
-
-    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated AEAD"
-    make test
-}
-
-# This is a common configuration function used in:
-# - component_test_psa_crypto_config_accel_cipher_aead_cmac
-# - component_test_psa_crypto_config_reference_cipher_aead_cmac
-common_psa_crypto_config_accel_cipher_aead_cmac() {
-    # Start from the full config
-    helper_libtestdriver1_adjust_config "full"
-
-    scripts/config.py unset MBEDTLS_NIST_KW_C
-}
-
-# The 2 following test components, i.e.
-# - component_test_psa_crypto_config_accel_cipher_aead_cmac
-# - component_test_psa_crypto_config_reference_cipher_aead_cmac
-# are meant to be used together in analyze_outcomes.py script in order to test
-# driver's coverage for ciphers and AEADs.
-component_test_psa_crypto_config_accel_cipher_aead_cmac () {
-    msg "build: full config with accelerated cipher inc. AEAD and CMAC"
-
-    loc_accel_list="ALG_ECB_NO_PADDING ALG_CBC_NO_PADDING ALG_CBC_PKCS7 ALG_CTR ALG_CFB \
-                    ALG_OFB ALG_XTS ALG_STREAM_CIPHER ALG_CCM_STAR_NO_TAG \
-                    ALG_GCM ALG_CCM ALG_CHACHA20_POLY1305 ALG_CMAC \
-                    KEY_TYPE_DES KEY_TYPE_AES KEY_TYPE_ARIA KEY_TYPE_CHACHA20 KEY_TYPE_CAMELLIA"
-
-    # Configure
-    # ---------
-
-    common_psa_crypto_config_accel_cipher_aead_cmac
-
-    # Disable the things that are being accelerated
-    scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
-    scripts/config.py unset MBEDTLS_CIPHER_PADDING_PKCS7
-    scripts/config.py unset MBEDTLS_CIPHER_MODE_CTR
-    scripts/config.py unset MBEDTLS_CIPHER_MODE_CFB
-    scripts/config.py unset MBEDTLS_CIPHER_MODE_OFB
-    scripts/config.py unset MBEDTLS_CIPHER_MODE_XTS
-    scripts/config.py unset MBEDTLS_GCM_C
-    scripts/config.py unset MBEDTLS_CCM_C
-    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
-    scripts/config.py unset MBEDTLS_CMAC_C
-    scripts/config.py unset MBEDTLS_DES_C
-    scripts/config.py unset MBEDTLS_AES_C
-    scripts/config.py unset MBEDTLS_ARIA_C
-    scripts/config.py unset MBEDTLS_CHACHA20_C
-    scripts/config.py unset MBEDTLS_CAMELLIA_C
-
-    # Disable CIPHER_C entirely as all ciphers/AEADs are accelerated and PSA
-    # does not depend on it.
-    scripts/config.py unset MBEDTLS_CIPHER_C
-
-    # Build
-    # -----
-
-    helper_libtestdriver1_make_drivers "$loc_accel_list"
-
-    helper_libtestdriver1_make_main "$loc_accel_list"
-
-    # Make sure this was not re-enabled by accident (additive config)
-    not grep mbedtls_cipher library/cipher.o
-    not grep mbedtls_des library/des.o
-    not grep mbedtls_aes library/aes.o
-    not grep mbedtls_aria library/aria.o
-    not grep mbedtls_camellia library/camellia.o
-    not grep mbedtls_ccm library/ccm.o
-    not grep mbedtls_gcm library/gcm.o
-    not grep mbedtls_chachapoly library/chachapoly.o
-    not grep mbedtls_cmac library/cmac.o
-
-    # Run the tests
-    # -------------
-
-    msg "test: full config with accelerated cipher inc. AEAD and CMAC"
-    make test
-
-    msg "ssl-opt: full config with accelerated cipher inc. AEAD and CMAC"
-    tests/ssl-opt.sh
-
-    msg "compat.sh: full config with accelerated cipher inc. AEAD and CMAC"
-    tests/compat.sh -V NO -p mbedTLS
-}
-
-component_test_psa_crypto_config_reference_cipher_aead_cmac () {
-    msg "build: full config with non-accelerated cipher inc. AEAD and CMAC"
-    common_psa_crypto_config_accel_cipher_aead_cmac
-
-    make
-
-    msg "test: full config with non-accelerated cipher inc. AEAD and CMAC"
-    make test
-
-    msg "ssl-opt: full config with non-accelerated cipher inc. AEAD and CMAC"
-    tests/ssl-opt.sh
-
-    msg "compat.sh: full config with non-accelerated cipher inc. AEAD and CMAC"
-    tests/compat.sh -V NO -p mbedTLS
-}
-
-common_block_cipher_dispatch() {
-    TEST_WITH_DRIVER="$1"
-
-    # Start from the full config
-    helper_libtestdriver1_adjust_config "full"
-
-    if [ "$TEST_WITH_DRIVER" -eq 1 ]; then
-        # Disable key types that are accelerated (there is no legacy equivalent
-        # symbol for ECB)
-        scripts/config.py unset MBEDTLS_AES_C
-        scripts/config.py unset MBEDTLS_ARIA_C
-        scripts/config.py unset MBEDTLS_CAMELLIA_C
-    fi
-
-    # Disable cipher's modes that, when not accelerated, cause
-    # legacy key types to be re-enabled in "config_adjust_legacy_from_psa.h".
-    # Keep this also in the reference component in order to skip the same tests
-    # that were skipped in the accelerated one.
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CTR
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CFB
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_OFB
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_NO_PADDING
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_PKCS7
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CMAC
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CCM_STAR_NO_TAG
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128
-
-    # Disable direct dependency on AES_C
-    scripts/config.py unset MBEDTLS_NIST_KW_C
-
-    # Prevent the cipher module from using deprecated PSA path. The reason is
-    # that otherwise there will be tests relying on "aes_info" (defined in
-    # "cipher_wrap.c") whose functions are not available when AES_C is
-    # not defined. ARIA and Camellia are not a problem in this case because
-    # the PSA path is not tested for these key types.
-    scripts/config.py set MBEDTLS_DEPRECATED_REMOVED
-}
-
-component_test_full_block_cipher_psa_dispatch () {
-    msg "build: full + PSA dispatch in block_cipher"
-
-    loc_accel_list="ALG_ECB_NO_PADDING \
-                    KEY_TYPE_AES KEY_TYPE_ARIA KEY_TYPE_CAMELLIA"
-
-    # Configure
-    # ---------
-
-    common_block_cipher_dispatch 1
-
-    # Build
-    # -----
-
-    helper_libtestdriver1_make_drivers "$loc_accel_list"
-
-    helper_libtestdriver1_make_main "$loc_accel_list"
-
-    # Make sure disabled components were not re-enabled by accident (additive
-    # config)
-    not grep mbedtls_aes_ library/aes.o
-    not grep mbedtls_aria_ library/aria.o
-    not grep mbedtls_camellia_ library/camellia.o
-
-    # Run the tests
-    # -------------
-
-    msg "test: full + PSA dispatch in block_cipher"
-    make test
-}
-
-# This is the reference component of component_test_full_block_cipher_psa_dispatch
-component_test_full_block_cipher_legacy_dispatch () {
-    msg "build: full + legacy dispatch in block_cipher"
-
-    common_block_cipher_dispatch 0
-
-    make
-
-    msg "test: full + legacy dispatch in block_cipher"
-    make test
-}
-
-component_test_aead_chachapoly_disabled() {
-    msg "build: full minus CHACHAPOLY"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CHACHA20_POLY1305
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
-
-    msg "test: full minus CHACHAPOLY"
-    make test
-}
-
-component_test_aead_only_ccm() {
-    msg "build: full minus CHACHAPOLY and GCM"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
-    scripts/config.py unset MBEDTLS_GCM_C
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CHACHA20_POLY1305
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_GCM
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
-
-    msg "test: full minus CHACHAPOLY and GCM"
-    make test
-}
-
-component_test_ccm_aes_sha256() {
-    msg "build: CCM + AES + SHA256 configuration"
-
-    cp "$CONFIG_TEST_DRIVER_H" "$CONFIG_H"
-    cp configs/crypto-config-ccm-aes-sha256.h "$CRYPTO_CONFIG_H"
-
-    make
-
-    msg "test: CCM + AES + SHA256 configuration"
-    make test
-}
-
-# This should be renamed to test and updated once the accelerator ECDH code is in place and ready to test.
-component_build_psa_accel_alg_ecdh() {
-    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_ECDH without MBEDTLS_ECDH_C"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    scripts/config.py unset MBEDTLS_ECDH_C
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_ECDH -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
-}
-
-# This should be renamed to test and updated once the accelerator HMAC code is in place and ready to test.
-component_build_psa_accel_alg_hmac() {
-    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_HMAC"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_HMAC -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
-}
-
-# This should be renamed to test and updated once the accelerator HKDF code is in place and ready to test.
-component_build_psa_accel_alg_hkdf() {
-    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_HKDF without MBEDTLS_HKDF_C"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_HKDF_C
-    # Make sure to unset TLS1_3 since it requires HKDF_C and will not build properly without it.
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_HKDF -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
-}
-
-# This should be renamed to test and updated once the accelerator MD5 code is in place and ready to test.
-component_build_psa_accel_alg_md5() {
-    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_MD5 - other hashes"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RIPEMD160
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_1
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_224
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_256
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_384
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_512
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
-    scripts/config.py unset MBEDTLS_LMS_C
-    scripts/config.py unset MBEDTLS_LMS_PRIVATE
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_MD5 -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
-}
-
-# This should be renamed to test and updated once the accelerator RIPEMD160 code is in place and ready to test.
-component_build_psa_accel_alg_ripemd160() {
-    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_RIPEMD160 - other hashes"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_MD5
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_1
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_224
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_256
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_384
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_512
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
-    scripts/config.py unset MBEDTLS_LMS_C
-    scripts/config.py unset MBEDTLS_LMS_PRIVATE
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_RIPEMD160 -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
-}
-
-# This should be renamed to test and updated once the accelerator SHA1 code is in place and ready to test.
-component_build_psa_accel_alg_sha1() {
-    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_SHA_1 - other hashes"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_MD5
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RIPEMD160
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_224
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_256
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_384
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_512
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
-    scripts/config.py unset MBEDTLS_LMS_C
-    scripts/config.py unset MBEDTLS_LMS_PRIVATE
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_SHA_1 -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
-}
-
-# This should be renamed to test and updated once the accelerator SHA224 code is in place and ready to test.
-component_build_psa_accel_alg_sha224() {
-    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_SHA_224 - other hashes"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_MD5
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RIPEMD160
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_1
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_384
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_512
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_SHA_224 -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
-}
-
-# This should be renamed to test and updated once the accelerator SHA256 code is in place and ready to test.
-component_build_psa_accel_alg_sha256() {
-    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_SHA_256 - other hashes"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_MD5
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RIPEMD160
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_1
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_224
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_384
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_512
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_SHA_256 -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
-}
-
-# This should be renamed to test and updated once the accelerator SHA384 code is in place and ready to test.
-component_build_psa_accel_alg_sha384() {
-    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_SHA_384 - other hashes"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_MD5
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RIPEMD160
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_1
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_224
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_256
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
-    scripts/config.py unset MBEDTLS_LMS_C
-    scripts/config.py unset MBEDTLS_LMS_PRIVATE
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_SHA_384 -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
-}
-
-# This should be renamed to test and updated once the accelerator SHA512 code is in place and ready to test.
-component_build_psa_accel_alg_sha512() {
-    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_SHA_512 - other hashes"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_MD5
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RIPEMD160
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_1
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_224
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_256
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_384
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
-    scripts/config.py unset MBEDTLS_LMS_C
-    scripts/config.py unset MBEDTLS_LMS_PRIVATE
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_SHA_512 -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
-}
-
-# This should be renamed to test and updated once the accelerator RSA code is in place and ready to test.
-component_build_psa_accel_alg_rsa_pkcs1v15_crypt() {
-    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_RSA_PKCS1V15_CRYPT + PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_ALG_RSA_PKCS1V15_CRYPT 1
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PKCS1V15_SIGN
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_OAEP
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PSS
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
-}
-
-# This should be renamed to test and updated once the accelerator RSA code is in place and ready to test.
-component_build_psa_accel_alg_rsa_pkcs1v15_sign() {
-    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_RSA_PKCS1V15_SIGN + PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_ALG_RSA_PKCS1V15_SIGN 1
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_OAEP
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PSS
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
-}
-
-# This should be renamed to test and updated once the accelerator RSA code is in place and ready to test.
-component_build_psa_accel_alg_rsa_oaep() {
-    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_RSA_OAEP + PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_ALG_RSA_OAEP 1
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PKCS1V15_SIGN
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PSS
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_RSA_OAEP -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
-}
-
-# This should be renamed to test and updated once the accelerator RSA code is in place and ready to test.
-component_build_psa_accel_alg_rsa_pss() {
-    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_RSA_PSS + PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_ALG_RSA_PSS 1
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PKCS1V15_SIGN
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_OAEP
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_RSA_PSS -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
-}
-
-# This should be renamed to test and updated once the accelerator RSA code is in place and ready to test.
-component_build_psa_accel_key_type_rsa_key_pair() {
-    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_xxx + PSA_WANT_ALG_RSA_PSS"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_ALG_RSA_PSS 1
-    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC 1
-    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1
-    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1
-    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE 1
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
-}
-
-# This should be renamed to test and updated once the accelerator RSA code is in place and ready to test.
-component_build_psa_accel_key_type_rsa_public_key() {
-    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY + PSA_WANT_ALG_RSA_PSS"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_ALG_RSA_PSS 1
-    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
-}
-
-
-support_build_tfm_armcc () {
-    support_build_armcc
-}
-
-component_build_tfm_armcc() {
-    # test the TF-M configuration can build cleanly with various warning flags enabled
-    cp configs/config-tfm.h "$CONFIG_H"
-
-    msg "build: TF-M config, armclang armv7-m thumb2"
-    armc6_build_test "--target=arm-arm-none-eabi -march=armv7-m -mthumb -Os -std=c99 -Werror -Wall -Wextra -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow -Wvla -Wformat=2 -Wno-format-nonliteral -Wshadow -Wasm-operand-widths -Wunused -I../tests/include/spe"
-}
-
-component_build_tfm() {
-    # Check that the TF-M configuration can build cleanly with various
-    # warning flags enabled. We don't build or run tests, since the
-    # TF-M configuration needs a TF-M platform. A tweaked version of
-    # the configuration that works on mainstream platforms is in
-    # configs/config-tfm.h, tested via test-ref-configs.pl.
-    cp configs/config-tfm.h "$CONFIG_H"
-
-    msg "build: TF-M config, clang, armv7-m thumb2"
-    make lib CC="clang" CFLAGS="--target=arm-linux-gnueabihf -march=armv7-m -mthumb -Os -std=c99 -Werror -Wall -Wextra -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow -Wvla -Wformat=2 -Wno-format-nonliteral -Wshadow -Wasm-operand-widths -Wunused -I../tests/include/spe"
-
-    msg "build: TF-M config, gcc native build"
-    make clean
-    make lib CC="gcc" CFLAGS="-Os -std=c99 -Werror -Wall -Wextra -Wwrite-strings -Wpointer-arith -Wshadow -Wvla -Wformat=2 -Wno-format-nonliteral -Wshadow -Wformat-signedness -Wlogical-op -I../tests/include/spe"
-}
-
-# Test that the given .o file builds with all (valid) combinations of the given options.
-#
-# Syntax: build_test_config_combos FILE VALIDATOR_FUNCTION OPT1 OPT2 ...
-#
-# The validator function is the name of a function to validate the combination of options.
-# It may be "" if all combinations are valid.
-# It receives a string containing a combination of options, as passed to the compiler,
-# e.g. "-DOPT1 -DOPT2 ...". It must return 0 iff the combination is valid, non-zero if invalid.
-build_test_config_combos() {
-    file=$1
-    shift
-    validate_options=$1
-    shift
-    options=("$@")
-
-    # clear all of the options so that they can be overridden on the clang commandline
-    for opt in "${options[@]}"; do
-        ./scripts/config.py unset ${opt}
-    done
-
-    # enter the directory containing the target file & strip the dir from the filename
-    cd $(dirname ${file})
-    file=$(basename ${file})
-
-    # The most common issue is unused variables/functions, so ensure -Wunused is set.
-    warning_flags="-Werror -Wall -Wextra -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow -Wvla -Wformat=2 -Wno-format-nonliteral -Wshadow -Wasm-operand-widths -Wunused"
-
-    # Extract the command generated by the Makefile to build the target file.
-    # This ensures that we have any include paths, macro definitions, etc
-    # that may be applied by make.
-    # Add -fsyntax-only as we only want a syntax check and don't need to generate a file.
-    compile_cmd="clang \$(LOCAL_CFLAGS) ${warning_flags} -fsyntax-only -c"
-
-    makefile=$(TMPDIR=. mktemp)
-    deps=""
-
-    len=${#options[@]}
-    source_file=${file%.o}.c
-
-    targets=0
-    echo 'include Makefile' >${makefile}
-
-    for ((i = 0; i < $((2**${len})); i++)); do
-        # generate each of 2^n combinations of options
-        # each bit of $i is used to determine if options[i] will be set or not
-        target="t"
-        clang_args=""
-        for ((j = 0; j < ${len}; j++)); do
-            if (((i >> j) & 1)); then
-                opt=-D${options[$j]}
-                clang_args="${clang_args} ${opt}"
-                target="${target}${opt}"
-            fi
-        done
-
-        # if combination is not known to be invalid, add it to the makefile
-        if [[ -z $validate_options ]] || $validate_options "${clang_args}"; then
-            cmd="${compile_cmd} ${clang_args}"
-            echo "${target}: ${source_file}; $cmd ${source_file}" >> ${makefile}
-
-            deps="${deps} ${target}"
-            ((++targets))
-        fi
-    done
-
-    echo "build_test_config_combos: ${deps}" >> ${makefile}
-
-    # execute all of the commands via Make (probably in parallel)
-    make -s -f ${makefile} build_test_config_combos
-    echo "$targets targets checked"
-
-    # clean up the temporary makefile
-    rm ${makefile}
-}
-
-validate_aes_config_variations() {
-    if [[ "$1" == *"MBEDTLS_AES_USE_HARDWARE_ONLY"* ]]; then
-        if [[ "$1" == *"MBEDTLS_PADLOCK_C"* ]]; then
-            return 1
-        fi
-        if [[ !(("$HOSTTYPE" == "aarch64" && "$1" != *"MBEDTLS_AESCE_C"*) || \
-                ("$HOSTTYPE" == "x86_64"  && "$1" != *"MBEDTLS_AESNI_C"*)) ]]; then
-            return 1
-        fi
-    fi
-    return 0
-}
-
-component_build_aes_variations() {
-    # 18s - around 90ms per clang invocation on M1 Pro
-    #
-    # aes.o has many #if defined(...) guards that intersect in complex ways.
-    # Test that all the combinations build cleanly.
-
-    MBEDTLS_ROOT_DIR="$PWD"
-    msg "build: aes.o for all combinations of relevant config options"
-
-    build_test_config_combos library/aes.o validate_aes_config_variations \
-        "MBEDTLS_AES_SETKEY_ENC_ALT" "MBEDTLS_AES_DECRYPT_ALT" \
-        "MBEDTLS_AES_ROM_TABLES" "MBEDTLS_AES_ENCRYPT_ALT" "MBEDTLS_AES_SETKEY_DEC_ALT" \
-        "MBEDTLS_AES_FEWER_TABLES" "MBEDTLS_PADLOCK_C" "MBEDTLS_AES_USE_HARDWARE_ONLY" \
-        "MBEDTLS_AESNI_C" "MBEDTLS_AESCE_C" "MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH"
-
-    cd "$MBEDTLS_ROOT_DIR"
-    msg "build: aes.o for all combinations of relevant config options + BLOCK_CIPHER_NO_DECRYPT"
-
-    # MBEDTLS_BLOCK_CIPHER_NO_DECRYPT is incompatible with ECB in PSA, CBC/XTS/NIST_KW/DES,
-    # manually set or unset those configurations to check
-    # MBEDTLS_BLOCK_CIPHER_NO_DECRYPT with various combinations in aes.o.
-    scripts/config.py set MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
-    scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
-    scripts/config.py unset MBEDTLS_CIPHER_MODE_XTS
-    scripts/config.py unset MBEDTLS_DES_C
-    scripts/config.py unset MBEDTLS_NIST_KW_C
-    build_test_config_combos library/aes.o validate_aes_config_variations \
-        "MBEDTLS_AES_SETKEY_ENC_ALT" "MBEDTLS_AES_DECRYPT_ALT" \
-        "MBEDTLS_AES_ROM_TABLES" "MBEDTLS_AES_ENCRYPT_ALT" "MBEDTLS_AES_SETKEY_DEC_ALT" \
-        "MBEDTLS_AES_FEWER_TABLES" "MBEDTLS_PADLOCK_C" "MBEDTLS_AES_USE_HARDWARE_ONLY" \
-        "MBEDTLS_AESNI_C" "MBEDTLS_AESCE_C" "MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH"
-}
-
-component_test_no_platform () {
-    # Full configuration build, without platform support, file IO and net sockets.
-    # This should catch missing mbedtls_printf definitions, and by disabling file
-    # IO, it should catch missing '#include <stdio.h>'
-    msg "build: full config except platform/fsio/net, make, gcc, C99" # ~ 30s
-    scripts/config.py full_no_platform
-    scripts/config.py unset MBEDTLS_PLATFORM_C
-    scripts/config.py unset MBEDTLS_NET_C
-    scripts/config.py unset MBEDTLS_FS_IO
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C
-    scripts/config.py unset MBEDTLS_PSA_ITS_FILE_C
-    scripts/config.py unset MBEDTLS_ENTROPY_NV_SEED
-    # Note, _DEFAULT_SOURCE needs to be defined for platforms using glibc version >2.19,
-    # to re-enable platform integration features otherwise disabled in C99 builds
-    make CC=gcc CFLAGS='-Werror -Wall -Wextra -std=c99 -pedantic -Os -D_DEFAULT_SOURCE' lib programs
-    make CC=gcc CFLAGS='-Werror -Wall -Wextra -Os' test
-}
-
-component_build_no_std_function () {
-    # catch compile bugs in _uninit functions
-    msg "build: full config with NO_STD_FUNCTION, make, gcc" # ~ 30s
-    scripts/config.py full
-    scripts/config.py set MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
-    scripts/config.py unset MBEDTLS_ENTROPY_NV_SEED
-    scripts/config.py unset MBEDTLS_PLATFORM_NV_SEED_ALT
-    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Check .
-    make
-}
-
-component_build_no_ssl_srv () {
-    msg "build: full config except SSL server, make, gcc" # ~ 30s
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_SSL_SRV_C
-    make CC=gcc CFLAGS='-Werror -Wall -Wextra -O1'
-}
-
-component_build_no_ssl_cli () {
-    msg "build: full config except SSL client, make, gcc" # ~ 30s
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_SSL_CLI_C
-    make CC=gcc CFLAGS='-Werror -Wall -Wextra -O1'
-}
-
-component_build_no_sockets () {
-    # Note, C99 compliance can also be tested with the sockets support disabled,
-    # as that requires a POSIX platform (which isn't the same as C99).
-    msg "build: full config except net_sockets.c, make, gcc -std=c99 -pedantic" # ~ 30s
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_NET_C # getaddrinfo() undeclared, etc.
-    scripts/config.py set MBEDTLS_NO_PLATFORM_ENTROPY # uses syscall() on GNU/Linux
-    make CC=gcc CFLAGS='-Werror -Wall -Wextra -O1 -std=c99 -pedantic' lib
-}
-
-component_test_memory_buffer_allocator_backtrace () {
-    msg "build: default config with memory buffer allocator and backtrace enabled"
-    scripts/config.py set MBEDTLS_MEMORY_BUFFER_ALLOC_C
-    scripts/config.py set MBEDTLS_PLATFORM_MEMORY
-    scripts/config.py set MBEDTLS_MEMORY_BACKTRACE
-    scripts/config.py set MBEDTLS_MEMORY_DEBUG
-    cmake -DCMAKE_BUILD_TYPE:String=Release .
-    make
-
-    msg "test: MBEDTLS_MEMORY_BUFFER_ALLOC_C and MBEDTLS_MEMORY_BACKTRACE"
-    make test
-}
-
-component_test_memory_buffer_allocator () {
-    msg "build: default config with memory buffer allocator"
-    scripts/config.py set MBEDTLS_MEMORY_BUFFER_ALLOC_C
-    scripts/config.py set MBEDTLS_PLATFORM_MEMORY
-    cmake -DCMAKE_BUILD_TYPE:String=Release .
-    make
-
-    msg "test: MBEDTLS_MEMORY_BUFFER_ALLOC_C"
-    make test
-
-    msg "test: ssl-opt.sh, MBEDTLS_MEMORY_BUFFER_ALLOC_C"
-    # MBEDTLS_MEMORY_BUFFER_ALLOC is slow. Skip tests that tend to time out.
-    tests/ssl-opt.sh -e '^DTLS proxy'
-}
-
-component_test_no_max_fragment_length () {
-    # Run max fragment length tests with MFL disabled
-    msg "build: default config except MFL extension (ASan build)" # ~ 30s
-    scripts/config.py unset MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: ssl-opt.sh, MFL-related tests"
-    tests/ssl-opt.sh -f "Max fragment length"
-}
-
-component_test_asan_remove_peer_certificate () {
-    msg "build: default config with MBEDTLS_SSL_KEEP_PEER_CERTIFICATE disabled (ASan build)"
-    scripts/config.py unset MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE"
-    make test
-
-    msg "test: ssl-opt.sh, !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE"
-    tests/ssl-opt.sh
-
-    msg "test: compat.sh, !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE"
-    tests/compat.sh
-
-    msg "test: context-info.sh, !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE"
-    tests/context-info.sh
-}
-
-component_test_no_max_fragment_length_small_ssl_out_content_len () {
-    msg "build: no MFL extension, small SSL_OUT_CONTENT_LEN (ASan build)"
-    scripts/config.py unset MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-    scripts/config.py set MBEDTLS_SSL_IN_CONTENT_LEN 16384
-    scripts/config.py set MBEDTLS_SSL_OUT_CONTENT_LEN 4096
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: MFL tests (disabled MFL extension case) & large packet tests"
-    tests/ssl-opt.sh -f "Max fragment length\|Large buffer"
-
-    msg "test: context-info.sh (disabled MFL extension case)"
-    tests/context-info.sh
-}
-
-component_test_variable_ssl_in_out_buffer_len () {
-    msg "build: MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH enabled (ASan build)"
-    scripts/config.py set MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH enabled"
-    make test
-
-    msg "test: ssl-opt.sh, MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH enabled"
-    tests/ssl-opt.sh
-
-    msg "test: compat.sh, MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH enabled"
-    tests/compat.sh
-}
-
-component_test_dtls_cid_legacy () {
-    msg "build: MBEDTLS_SSL_DTLS_CONNECTION_ID (legacy) enabled (ASan build)"
-    scripts/config.py set MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT 1
-
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: MBEDTLS_SSL_DTLS_CONNECTION_ID (legacy)"
-    make test
-
-    msg "test: ssl-opt.sh, MBEDTLS_SSL_DTLS_CONNECTION_ID (legacy) enabled"
-    tests/ssl-opt.sh
-
-    msg "test: compat.sh, MBEDTLS_SSL_DTLS_CONNECTION_ID (legacy) enabled"
-    tests/compat.sh
-}
-
-component_test_ssl_alloc_buffer_and_mfl () {
-    msg "build: default config with memory buffer allocator and MFL extension"
-    scripts/config.py set MBEDTLS_MEMORY_BUFFER_ALLOC_C
-    scripts/config.py set MBEDTLS_PLATFORM_MEMORY
-    scripts/config.py set MBEDTLS_MEMORY_DEBUG
-    scripts/config.py set MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-    scripts/config.py set MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
-    cmake -DCMAKE_BUILD_TYPE:String=Release .
-    make
-
-    msg "test: MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH, MBEDTLS_MEMORY_BUFFER_ALLOC_C, MBEDTLS_MEMORY_DEBUG and MBEDTLS_SSL_MAX_FRAGMENT_LENGTH"
-    make test
-
-    msg "test: MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH, MBEDTLS_MEMORY_BUFFER_ALLOC_C, MBEDTLS_MEMORY_DEBUG and MBEDTLS_SSL_MAX_FRAGMENT_LENGTH"
-    tests/ssl-opt.sh -f "Handshake memory usage"
-}
-
-component_test_when_no_ciphersuites_have_mac () {
-    msg "build: when no ciphersuites have MAC"
-    scripts/config.py unset MBEDTLS_CIPHER_NULL_CIPHER
-    scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
-    scripts/config.py unset MBEDTLS_CMAC_C
-    make
-
-    msg "test: !MBEDTLS_SSL_SOME_SUITES_USE_MAC"
-    make test
-
-    msg "test ssl-opt.sh: !MBEDTLS_SSL_SOME_SUITES_USE_MAC"
-    tests/ssl-opt.sh -f 'Default\|EtM' -e 'without EtM'
-}
-
-component_test_no_date_time () {
-    msg "build: default config without MBEDTLS_HAVE_TIME_DATE"
-    scripts/config.py unset MBEDTLS_HAVE_TIME_DATE
-    cmake -D CMAKE_BUILD_TYPE:String=Check .
-    make
-
-    msg "test: !MBEDTLS_HAVE_TIME_DATE - main suites"
-    make test
-}
-
-component_test_platform_calloc_macro () {
-    msg "build: MBEDTLS_PLATFORM_{CALLOC/FREE}_MACRO enabled (ASan build)"
-    scripts/config.py set MBEDTLS_PLATFORM_MEMORY
-    scripts/config.py set MBEDTLS_PLATFORM_CALLOC_MACRO calloc
-    scripts/config.py set MBEDTLS_PLATFORM_FREE_MACRO   free
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: MBEDTLS_PLATFORM_{CALLOC/FREE}_MACRO enabled (ASan build)"
-    make test
-}
-
-component_test_malloc_0_null () {
-    msg "build: malloc(0) returns NULL (ASan+UBSan build)"
-    scripts/config.py full
-    make CC=$ASAN_CC CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"$PWD/tests/configs/user-config-malloc-0-null.h\"' $ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
-
-    msg "test: malloc(0) returns NULL (ASan+UBSan build)"
-    make test
-
-    msg "selftest: malloc(0) returns NULL (ASan+UBSan build)"
-    # Just the calloc selftest. "make test" ran the others as part of the
-    # test suites.
-    programs/test/selftest calloc
-
-    msg "test ssl-opt.sh: malloc(0) returns NULL (ASan+UBSan build)"
-    # Run a subset of the tests. The choice is a balance between coverage
-    # and time (including time indirectly wasted due to flaky tests).
-    # The current choice is to skip tests whose description includes
-    # "proxy", which is an approximation of skipping tests that use the
-    # UDP proxy, which tend to be slower and flakier.
-    tests/ssl-opt.sh -e 'proxy'
-}
-
-support_test_aesni() {
-    # Check that gcc targets x86_64 (we can build AESNI), and check for
-    # AESNI support on the host (we can run AESNI).
-    #
-    # The name of this function is possibly slightly misleading, but needs to align
-    # with the name of the corresponding test, component_test_aesni.
-    #
-    # In principle 32-bit x86 can support AESNI, but our implementation does not
-    # support 32-bit x86, so we check for x86-64.
-    # We can only grep /proc/cpuinfo on Linux, so this also checks for Linux
-    (gcc -v 2>&1 | grep Target | grep -q x86_64) &&
-        [[ "$HOSTTYPE" == "x86_64" && "$OSTYPE" == "linux-gnu" ]] &&
-        (lscpu | grep -qw aes)
-}
-
-component_test_aesni () { # ~ 60s
-    # This tests the two AESNI implementations (intrinsics and assembly), and also the plain C
-    # fallback. It also tests the logic that is used to select which implementation(s) to build.
-    #
-    # This test does not require the host to have support for AESNI (if it doesn't, the run-time
-    # AESNI detection will fallback to the plain C implementation, so the tests will instead
-    # exercise the plain C impl).
-
-    msg "build: default config with different AES implementations"
-    scripts/config.py set MBEDTLS_AESNI_C
-    scripts/config.py unset MBEDTLS_AES_USE_HARDWARE_ONLY
-    scripts/config.py set MBEDTLS_HAVE_ASM
-
-    # test the intrinsics implementation
-    msg "AES tests, test intrinsics"
-    make clean
-    make CC=gcc CFLAGS='-Werror -Wall -Wextra -mpclmul -msse2 -maes'
-    # check that we built intrinsics - this should be used by default when supported by the compiler
-    ./programs/test/selftest aes | grep "AESNI code" | grep -q "intrinsics"
-
-    # test the asm implementation
-    msg "AES tests, test assembly"
-    make clean
-    make CC=gcc CFLAGS='-Werror -Wall -Wextra -mno-pclmul -mno-sse2 -mno-aes'
-    # check that we built assembly - this should be built if the compiler does not support intrinsics
-    ./programs/test/selftest aes | grep "AESNI code" | grep -q "assembly"
-
-    # test the plain C implementation
-    scripts/config.py unset MBEDTLS_AESNI_C
-    scripts/config.py unset MBEDTLS_AES_USE_HARDWARE_ONLY
-    msg "AES tests, plain C"
-    make clean
-    make CC=gcc CFLAGS='-O2 -Werror'
-    # check that there is no AESNI code present
-    ./programs/test/selftest aes | not grep -q "AESNI code"
-    not grep -q "AES note: using AESNI" ./programs/test/selftest
-    grep -q "AES note: built-in implementation." ./programs/test/selftest
-
-    # test the intrinsics implementation
-    scripts/config.py set MBEDTLS_AESNI_C
-    scripts/config.py set MBEDTLS_AES_USE_HARDWARE_ONLY
-    msg "AES tests, test AESNI only"
-    make clean
-    make CC=gcc CFLAGS='-Werror -Wall -Wextra -mpclmul -msse2 -maes'
-    ./programs/test/selftest aes | grep -q "AES note: using AESNI"
-    ./programs/test/selftest aes | not grep -q "AES note: built-in implementation."
-    grep -q "AES note: using AESNI" ./programs/test/selftest
-    not grep -q "AES note: built-in implementation." ./programs/test/selftest
-}
-
-component_test_sha3_variations() {
-    msg "sha3 loop unroll variations"
-
-    # define minimal config sufficient to test SHA3
-    cat > include/mbedtls/mbedtls_config.h << END
-        #define MBEDTLS_SELF_TEST
-        #define MBEDTLS_SHA3_C
-END
-
-    msg "all loops unrolled"
-    make clean
-    make -C tests test_suite_shax CFLAGS="-DMBEDTLS_SHA3_THETA_UNROLL=1 -DMBEDTLS_SHA3_PI_UNROLL=1 -DMBEDTLS_SHA3_CHI_UNROLL=1 -DMBEDTLS_SHA3_RHO_UNROLL=1"
-    ./tests/test_suite_shax
-
-    msg "all loops rolled up"
-    make clean
-    make -C tests test_suite_shax CFLAGS="-DMBEDTLS_SHA3_THETA_UNROLL=0 -DMBEDTLS_SHA3_PI_UNROLL=0 -DMBEDTLS_SHA3_CHI_UNROLL=0 -DMBEDTLS_SHA3_RHO_UNROLL=0"
-    ./tests/test_suite_shax
-}
-
-support_test_aesni_m32() {
-    support_test_m32_no_asm && (lscpu | grep -qw aes)
-}
-
-component_test_aesni_m32 () { # ~ 60s
-    # This tests are duplicated from component_test_aesni for i386 target
-    #
-    # AESNI intrinsic code supports i386 and assembly code does not support it.
-
-    msg "build: default config with different AES implementations"
-    scripts/config.py set MBEDTLS_AESNI_C
-    scripts/config.py set MBEDTLS_PADLOCK_C
-    scripts/config.py unset MBEDTLS_AES_USE_HARDWARE_ONLY
-    scripts/config.py set MBEDTLS_HAVE_ASM
-
-    # test the intrinsics implementation with gcc
-    msg "AES tests, test intrinsics (gcc)"
-    make clean
-    make CC=gcc CFLAGS='-m32 -Werror -Wall -Wextra' LDFLAGS='-m32'
-    # check that we built intrinsics - this should be used by default when supported by the compiler
-    ./programs/test/selftest aes | grep "AESNI code" | grep -q "intrinsics"
-    grep -q "AES note: using AESNI" ./programs/test/selftest
-    grep -q "AES note: built-in implementation." ./programs/test/selftest
-    grep -q "AES note: using VIA Padlock" ./programs/test/selftest
-    grep -q mbedtls_aesni_has_support ./programs/test/selftest
-
-    scripts/config.py set MBEDTLS_AESNI_C
-    scripts/config.py unset MBEDTLS_PADLOCK_C
-    scripts/config.py set MBEDTLS_AES_USE_HARDWARE_ONLY
-    msg "AES tests, test AESNI only"
-    make clean
-    make CC=gcc CFLAGS='-m32 -Werror -Wall -Wextra -mpclmul -msse2 -maes' LDFLAGS='-m32'
-    ./programs/test/selftest aes | grep -q "AES note: using AESNI"
-    ./programs/test/selftest aes | not grep -q "AES note: built-in implementation."
-    grep -q "AES note: using AESNI" ./programs/test/selftest
-    not grep -q "AES note: built-in implementation." ./programs/test/selftest
-    not grep -q "AES note: using VIA Padlock" ./programs/test/selftest
-    not grep -q mbedtls_aesni_has_support ./programs/test/selftest
-}
-
-support_test_aesni_m32_clang() {
-    # clang >= 4 is required to build with target attributes
-    support_test_aesni_m32 && [[ $(clang_version) -ge 4 ]]
-}
-
-component_test_aesni_m32_clang() {
-
-    scripts/config.py set MBEDTLS_AESNI_C
-    scripts/config.py set MBEDTLS_PADLOCK_C
-    scripts/config.py unset MBEDTLS_AES_USE_HARDWARE_ONLY
-    scripts/config.py set MBEDTLS_HAVE_ASM
-
-    # test the intrinsics implementation with clang
-    msg "AES tests, test intrinsics (clang)"
-    make clean
-    make CC=clang CFLAGS='-m32 -Werror -Wall -Wextra' LDFLAGS='-m32'
-    # check that we built intrinsics - this should be used by default when supported by the compiler
-    ./programs/test/selftest aes | grep "AESNI code" | grep -q "intrinsics"
-    grep -q "AES note: using AESNI" ./programs/test/selftest
-    grep -q "AES note: built-in implementation." ./programs/test/selftest
-    grep -q "AES note: using VIA Padlock" ./programs/test/selftest
-    grep -q mbedtls_aesni_has_support ./programs/test/selftest
-}
-
-# For timebeing, no aarch64 gcc available in CI and no arm64 CI node.
-component_build_aes_aesce_armcc () {
-    msg "Build: AESCE test on arm64 platform without plain C."
-    scripts/config.py baremetal
-
-    # armc[56] don't support SHA-512 intrinsics
-    scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
-
-    # Stop armclang warning about feature detection for A64_CRYPTO.
-    # With this enabled, the library does build correctly under armclang,
-    # but in baremetal builds (as tested here), feature detection is
-    # unavailable, and the user is notified via a #warning. So enabling
-    # this feature would prevent us from building with -Werror on
-    # armclang. Tracked in #7198.
-    scripts/config.py unset MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
-    scripts/config.py set MBEDTLS_HAVE_ASM
-
-    msg "AESCE, build with default configuration."
-    scripts/config.py set MBEDTLS_AESCE_C
-    scripts/config.py unset MBEDTLS_AES_USE_HARDWARE_ONLY
-    armc6_build_test "-O1 --target=aarch64-arm-none-eabi -march=armv8-a+crypto"
-
-    msg "AESCE, build AESCE only"
-    scripts/config.py set MBEDTLS_AESCE_C
-    scripts/config.py set MBEDTLS_AES_USE_HARDWARE_ONLY
-    armc6_build_test "-O1 --target=aarch64-arm-none-eabi -march=armv8-a+crypto"
-}
-
-support_build_aes_armce() {
-    # clang >= 11 is required to build with AES extensions
-    [[ $(clang_version) -ge 11 ]]
-}
-
-component_build_aes_armce () {
-    # Test variations of AES with Armv8 crypto extensions
-    scripts/config.py set MBEDTLS_AESCE_C
-    scripts/config.py set MBEDTLS_AES_USE_HARDWARE_ONLY
-
-    msg "MBEDTLS_AES_USE_HARDWARE_ONLY, clang, aarch64"
-    make -B library/aesce.o CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a+crypto"
-
-    msg "MBEDTLS_AES_USE_HARDWARE_ONLY, clang, arm"
-    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a72+crypto -marm"
-
-    msg "MBEDTLS_AES_USE_HARDWARE_ONLY, clang, thumb"
-    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a32+crypto -mthumb"
-
-    scripts/config.py unset MBEDTLS_AES_USE_HARDWARE_ONLY
-
-    msg "no MBEDTLS_AES_USE_HARDWARE_ONLY, clang, aarch64"
-    make -B library/aesce.o CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a+crypto"
-
-    msg "no MBEDTLS_AES_USE_HARDWARE_ONLY, clang, arm"
-    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a72+crypto -marm"
-
-    msg "no MBEDTLS_AES_USE_HARDWARE_ONLY, clang, thumb"
-    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a32+crypto -mthumb"
-
-    # test for presence of AES instructions
-    scripts/config.py set MBEDTLS_AES_USE_HARDWARE_ONLY
-    msg "clang, test A32 crypto instructions built"
-    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a72+crypto -marm -S"
-    grep -E 'aes[0-9a-z]+.[0-9]\s*[qv]' library/aesce.o
-    msg "clang, test T32 crypto instructions built"
-    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a32+crypto -mthumb -S"
-    grep -E 'aes[0-9a-z]+.[0-9]\s*[qv]' library/aesce.o
-    msg "clang, test aarch64 crypto instructions built"
-    make -B library/aesce.o CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a -S"
-    grep -E 'aes[a-z]+\s*[qv]' library/aesce.o
-
-    # test for absence of AES instructions
-    scripts/config.py unset MBEDTLS_AES_USE_HARDWARE_ONLY
-    scripts/config.py unset MBEDTLS_AESCE_C
-    msg "clang, test A32 crypto instructions not built"
-    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a72+crypto -marm -S"
-    not grep -E 'aes[0-9a-z]+.[0-9]\s*[qv]' library/aesce.o
-    msg "clang, test T32 crypto instructions not built"
-    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a32+crypto -mthumb -S"
-    not grep -E 'aes[0-9a-z]+.[0-9]\s*[qv]' library/aesce.o
-    msg "clang, test aarch64 crypto instructions not built"
-    make -B library/aesce.o CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a -S"
-    not grep -E 'aes[a-z]+\s*[qv]' library/aesce.o
-}
-
-support_build_sha_armce() {
-    # clang >= 4 is required to build with SHA extensions
-    [[ $(clang_version) -ge 4 ]]
-}
-
-component_build_sha_armce () {
-    scripts/config.py unset MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
-
-
-    # Test variations of SHA256 Armv8 crypto extensions
-    scripts/config.py set MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
-        msg "MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY clang, aarch64"
-        make -B library/sha256.o CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a"
-        msg "MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY clang, arm"
-        make -B library/sha256.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a72+crypto -marm"
-    scripts/config.py unset MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
-
-
-    # test the deprecated form of the config option
-    scripts/config.py set MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
-        msg "MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY clang, thumb"
-        make -B library/sha256.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a32+crypto -mthumb"
-    scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
-
-    scripts/config.py set MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
-        msg "MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT clang, aarch64"
-        make -B library/sha256.o CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a"
-    scripts/config.py unset MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
-
-
-    # test the deprecated form of the config option
-    scripts/config.py set MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
-        msg "MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT clang, arm"
-        make -B library/sha256.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a72+crypto -marm -std=c99"
-        msg "MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT clang, thumb"
-        make -B library/sha256.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a32+crypto -mthumb"
-    scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
-
-
-    # examine the disassembly for presence of SHA instructions
-    for opt in MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT; do
-        scripts/config.py set ${opt}
-            msg "${opt} clang, test A32 crypto instructions built"
-            make -B library/sha256.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a72+crypto -marm -S"
-            grep -E 'sha256[a-z0-9]+.32\s+[qv]' library/sha256.o
-
-            msg "${opt} clang, test T32 crypto instructions built"
-            make -B library/sha256.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a32+crypto -mthumb -S"
-            grep -E 'sha256[a-z0-9]+.32\s+[qv]' library/sha256.o
-
-            msg "${opt} clang, test aarch64 crypto instructions built"
-            make -B library/sha256.o CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a -S"
-            grep -E 'sha256[a-z0-9]+\s+[qv]' library/sha256.o
-        scripts/config.py unset ${opt}
-    done
-
-
-    # examine the disassembly for absence of SHA instructions
-    msg "clang, test A32 crypto instructions not built"
-    make -B library/sha256.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a72+crypto -marm -S"
-    not grep -E 'sha256[a-z0-9]+.32\s+[qv]' library/sha256.o
-
-    msg "clang, test T32 crypto instructions not built"
-    make -B library/sha256.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a32+crypto -mthumb -S"
-    not grep -E 'sha256[a-z0-9]+.32\s+[qv]' library/sha256.o
-
-    msg "clang, test aarch64 crypto instructions not built"
-    make -B library/sha256.o CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a -S"
-    not grep -E 'sha256[a-z0-9]+\s+[qv]' library/sha256.o
-}
-
-# For timebeing, no VIA Padlock platform available.
-component_build_aes_via_padlock () {
-
-    msg "AES:VIA PadLock, build with default configuration."
-    scripts/config.py unset MBEDTLS_AESNI_C
-    scripts/config.py set MBEDTLS_PADLOCK_C
-    scripts/config.py unset MBEDTLS_AES_USE_HARDWARE_ONLY
-    make CC=gcc CFLAGS="$ASAN_CFLAGS -m32" LDFLAGS="-m32 $ASAN_CFLAGS"
-    grep -q mbedtls_padlock_has_support ./programs/test/selftest
-
-}
-
-support_build_aes_via_padlock_only () {
-    ( [ "$MBEDTLS_TEST_PLATFORM" == "Linux-x86_64" ] || \
-        [ "$MBEDTLS_TEST_PLATFORM" == "Linux-amd64" ] ) && \
-    [ "`dpkg --print-foreign-architectures`" == "i386" ]
-}
-
-support_build_aes_aesce_armcc () {
-    support_build_armcc
-}
-
-component_test_aes_only_128_bit_keys () {
-    msg "build: default config + AES_ONLY_128_BIT_KEY_LENGTH"
-    scripts/config.py set MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
-    scripts/config.py unset MBEDTLS_PADLOCK_C
-
-    make CFLAGS='-O2 -Werror -Wall -Wextra'
-
-    msg "test: default config + AES_ONLY_128_BIT_KEY_LENGTH"
-    make test
-}
-
-component_test_no_ctr_drbg_aes_only_128_bit_keys () {
-    msg "build: default config + AES_ONLY_128_BIT_KEY_LENGTH - CTR_DRBG_C"
-    scripts/config.py set MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
-    scripts/config.py unset MBEDTLS_CTR_DRBG_C
-    scripts/config.py unset MBEDTLS_PADLOCK_C
-
-    make CC=clang CFLAGS='-Werror -Wall -Wextra'
-
-    msg "test: default config + AES_ONLY_128_BIT_KEY_LENGTH - CTR_DRBG_C"
-    make test
-}
-
-component_test_aes_only_128_bit_keys_have_builtins () {
-    msg "build: default config + AES_ONLY_128_BIT_KEY_LENGTH - AESNI_C - AESCE_C"
-    scripts/config.py set MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
-    scripts/config.py unset MBEDTLS_PADLOCK_C
-    scripts/config.py unset MBEDTLS_AESNI_C
-    scripts/config.py unset MBEDTLS_AESCE_C
-
-    make CFLAGS='-O2 -Werror -Wall -Wextra'
-
-    msg "test: default config + AES_ONLY_128_BIT_KEY_LENGTH - AESNI_C - AESCE_C"
-    make test
-
-    msg "selftest: default config + AES_ONLY_128_BIT_KEY_LENGTH - AESNI_C - AESCE_C"
-    programs/test/selftest
-}
-
-component_test_gcm_largetable () {
-    msg "build: default config + GCM_LARGE_TABLE - AESNI_C - AESCE_C"
-    scripts/config.py set MBEDTLS_GCM_LARGE_TABLE
-    scripts/config.py unset MBEDTLS_PADLOCK_C
-    scripts/config.py unset MBEDTLS_AESNI_C
-    scripts/config.py unset MBEDTLS_AESCE_C
-
-    make CFLAGS='-O2 -Werror -Wall -Wextra'
-
-    msg "test: default config - GCM_LARGE_TABLE - AESNI_C - AESCE_C"
-    make test
-}
-
-component_test_aes_fewer_tables () {
-    msg "build: default config with AES_FEWER_TABLES enabled"
-    scripts/config.py set MBEDTLS_AES_FEWER_TABLES
-    make CFLAGS='-O2 -Werror -Wall -Wextra'
-
-    msg "test: AES_FEWER_TABLES"
-    make test
-}
-
-component_test_aes_rom_tables () {
-    msg "build: default config with AES_ROM_TABLES enabled"
-    scripts/config.py set MBEDTLS_AES_ROM_TABLES
-    make CFLAGS='-O2 -Werror -Wall -Wextra'
-
-    msg "test: AES_ROM_TABLES"
-    make test
-}
-
-component_test_aes_fewer_tables_and_rom_tables () {
-    msg "build: default config with AES_ROM_TABLES and AES_FEWER_TABLES enabled"
-    scripts/config.py set MBEDTLS_AES_FEWER_TABLES
-    scripts/config.py set MBEDTLS_AES_ROM_TABLES
-    make CFLAGS='-O2 -Werror -Wall -Wextra'
-
-    msg "test: AES_FEWER_TABLES + AES_ROM_TABLES"
-    make test
-}
-
-# helper for common_block_cipher_no_decrypt() which:
-# - enable/disable the list of config options passed from -s/-u respectively.
-# - build
-# - test for tests_suite_xxx
-# - selftest
-#
-# Usage: helper_block_cipher_no_decrypt_build_test
-#        [-s set_opts] [-u unset_opts] [-c cflags] [-l ldflags] [option [...]]
-# Options:  -s set_opts     the list of config options to enable
-#           -u unset_opts   the list of config options to disable
-#           -c cflags       the list of options passed to CFLAGS
-#           -l ldflags      the list of options passed to LDFLAGS
-helper_block_cipher_no_decrypt_build_test () {
-    while [ $# -gt 0 ]; do
-        case "$1" in
-            -s)
-                shift; local set_opts="$1";;
-            -u)
-                shift; local unset_opts="$1";;
-            -c)
-                shift; local cflags="-Werror -Wall -Wextra $1";;
-            -l)
-                shift; local ldflags="$1";;
-        esac
-        shift
-    done
-    set_opts="${set_opts:-}"
-    unset_opts="${unset_opts:-}"
-    cflags="${cflags:-}"
-    ldflags="${ldflags:-}"
-
-    [ -n "$set_opts" ] && echo "Enabling: $set_opts" && scripts/config.py set-all $set_opts
-    [ -n "$unset_opts" ] && echo "Disabling: $unset_opts" && scripts/config.py unset-all $unset_opts
-
-    msg "build: default config + BLOCK_CIPHER_NO_DECRYPT${set_opts:+ + $set_opts}${unset_opts:+ - $unset_opts} with $cflags${ldflags:+, $ldflags}"
-    make clean
-    make CFLAGS="-O2 $cflags" LDFLAGS="$ldflags"
-
-    # Make sure we don't have mbedtls_xxx_setkey_dec in AES/ARIA/CAMELLIA
-    not grep mbedtls_aes_setkey_dec library/aes.o
-    not grep mbedtls_aria_setkey_dec library/aria.o
-    not grep mbedtls_camellia_setkey_dec library/camellia.o
-    # Make sure we don't have mbedtls_internal_aes_decrypt in AES
-    not grep mbedtls_internal_aes_decrypt library/aes.o
-    # Make sure we don't have mbedtls_aesni_inverse_key in AESNI
-    not grep mbedtls_aesni_inverse_key library/aesni.o
-
-    msg "test: default config + BLOCK_CIPHER_NO_DECRYPT${set_opts:+ + $set_opts}${unset_opts:+ - $unset_opts} with $cflags${ldflags:+, $ldflags}"
-    make test
-
-    msg "selftest: default config + BLOCK_CIPHER_NO_DECRYPT${set_opts:+ + $set_opts}${unset_opts:+ - $unset_opts} with $cflags${ldflags:+, $ldflags}"
-    programs/test/selftest
-}
-
-# This is a common configuration function used in:
-# - component_test_block_cipher_no_decrypt_aesni_legacy()
-# - component_test_block_cipher_no_decrypt_aesni_use_psa()
-# in order to test BLOCK_CIPHER_NO_DECRYPT with AESNI intrinsics,
-# AESNI assembly and AES C implementation on x86_64 and with AESNI intrinsics
-# on x86.
-common_block_cipher_no_decrypt () {
-    # test AESNI intrinsics
-    helper_block_cipher_no_decrypt_build_test \
-        -s "MBEDTLS_AESNI_C" \
-        -c "-mpclmul -msse2 -maes"
-
-    # test AESNI assembly
-    helper_block_cipher_no_decrypt_build_test \
-        -s "MBEDTLS_AESNI_C" \
-        -c "-mno-pclmul -mno-sse2 -mno-aes"
-
-    # test AES C implementation
-    helper_block_cipher_no_decrypt_build_test \
-        -u "MBEDTLS_AESNI_C"
-
-    # test AESNI intrinsics for i386 target
-    helper_block_cipher_no_decrypt_build_test \
-        -s "MBEDTLS_AESNI_C" \
-        -c "-m32 -mpclmul -msse2 -maes" \
-        -l "-m32"
-}
-
-# This is a configuration function used in component_test_block_cipher_no_decrypt_xxx:
-# usage: 0: no PSA crypto configuration
-#        1: use PSA crypto configuration
-config_block_cipher_no_decrypt () {
-    use_psa=$1
-
-    scripts/config.py set MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
-    scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
-    scripts/config.py unset MBEDTLS_CIPHER_MODE_XTS
-    scripts/config.py unset MBEDTLS_DES_C
-    scripts/config.py unset MBEDTLS_NIST_KW_C
-
-    if [ "$use_psa" -eq 1 ]; then
-        # Enable support for cryptographic mechanisms through the PSA API.
-        # Note: XTS, KW are not yet supported via the PSA API in Mbed TLS.
-        scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
-        scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_NO_PADDING
-        scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_PKCS7
-        scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_ECB_NO_PADDING
-        scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_DES
-    fi
-}
-
-component_test_block_cipher_no_decrypt_aesni () {
-    # This consistently causes an llvm crash on clang 3.8, so use gcc
-    export CC=gcc
-    config_block_cipher_no_decrypt 0
-    common_block_cipher_no_decrypt
-}
-
-component_test_block_cipher_no_decrypt_aesni_use_psa () {
-    # This consistently causes an llvm crash on clang 3.8, so use gcc
-    export CC=gcc
-    config_block_cipher_no_decrypt 1
-    common_block_cipher_no_decrypt
-}
-
-support_test_block_cipher_no_decrypt_aesce_armcc () {
-    support_build_armcc
-}
-
-component_test_block_cipher_no_decrypt_aesce_armcc () {
-    scripts/config.py baremetal
-
-    # armc[56] don't support SHA-512 intrinsics
-    scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
-
-    # Stop armclang warning about feature detection for A64_CRYPTO.
-    # With this enabled, the library does build correctly under armclang,
-    # but in baremetal builds (as tested here), feature detection is
-    # unavailable, and the user is notified via a #warning. So enabling
-    # this feature would prevent us from building with -Werror on
-    # armclang. Tracked in #7198.
-    scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
-    scripts/config.py set MBEDTLS_HAVE_ASM
-
-    config_block_cipher_no_decrypt 1
-
-    # test AESCE baremetal build
-    scripts/config.py set MBEDTLS_AESCE_C
-    msg "build: default config + BLOCK_CIPHER_NO_DECRYPT with AESCE"
-    armc6_build_test "-O1 --target=aarch64-arm-none-eabi -march=armv8-a+crypto -Werror -Wall -Wextra"
-
-    # Make sure we don't have mbedtls_xxx_setkey_dec in AES/ARIA/CAMELLIA
-    not grep mbedtls_aes_setkey_dec library/aes.o
-    not grep mbedtls_aria_setkey_dec library/aria.o
-    not grep mbedtls_camellia_setkey_dec library/camellia.o
-    # Make sure we don't have mbedtls_internal_aes_decrypt in AES
-    not grep mbedtls_internal_aes_decrypt library/aes.o
-    # Make sure we don't have mbedtls_aesce_inverse_key and aesce_decrypt_block in AESCE
-    not grep mbedtls_aesce_inverse_key library/aesce.o
-    not grep aesce_decrypt_block library/aesce.o
-}
-
-component_test_ctr_drbg_aes_256_sha_256 () {
-    msg "build: full + MBEDTLS_ENTROPY_FORCE_SHA256 (ASan build)"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
-    scripts/config.py set MBEDTLS_ENTROPY_FORCE_SHA256
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: full + MBEDTLS_ENTROPY_FORCE_SHA256 (ASan build)"
-    make test
-}
-
-component_test_ctr_drbg_aes_128_sha_512 () {
-    msg "build: full + MBEDTLS_CTR_DRBG_USE_128_BIT_KEY (ASan build)"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
-    scripts/config.py set MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: full + MBEDTLS_CTR_DRBG_USE_128_BIT_KEY (ASan build)"
-    make test
-}
-
-component_test_ctr_drbg_aes_128_sha_256 () {
-    msg "build: full + MBEDTLS_CTR_DRBG_USE_128_BIT_KEY + MBEDTLS_ENTROPY_FORCE_SHA256 (ASan build)"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
-    scripts/config.py set MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
-    scripts/config.py set MBEDTLS_ENTROPY_FORCE_SHA256
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: full + MBEDTLS_CTR_DRBG_USE_128_BIT_KEY + MBEDTLS_ENTROPY_FORCE_SHA256 (ASan build)"
-    make test
-}
-
-component_test_se_default () {
-    msg "build: default config + MBEDTLS_PSA_CRYPTO_SE_C"
-    scripts/config.py set MBEDTLS_PSA_CRYPTO_SE_C
-    make CC=clang CFLAGS="$ASAN_CFLAGS -Os" LDFLAGS="$ASAN_CFLAGS"
-
-    msg "test: default config + MBEDTLS_PSA_CRYPTO_SE_C"
-    make test
-}
-
-component_test_psa_crypto_drivers () {
-    msg "build: full + test drivers dispatching to builtins"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_CONFIG
-    loc_cflags="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST_ALL"
-    loc_cflags="${loc_cflags} '-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/user-config-for-test.h\"'"
-    loc_cflags="${loc_cflags} -I../tests/include -O2"
-
-    make CC=$ASAN_CC CFLAGS="${loc_cflags}" LDFLAGS="$ASAN_CFLAGS"
-
-    msg "test: full + test drivers dispatching to builtins"
-    make test
-}
-
-component_test_make_shared () {
-    msg "build/test: make shared" # ~ 40s
-    make SHARED=1 all check
-    ldd programs/util/strerror | grep libmbedcrypto
-    programs/test/dlopen_demo.sh
-}
-
-component_test_cmake_shared () {
-    msg "build/test: cmake shared" # ~ 2min
-    cmake -DUSE_SHARED_MBEDTLS_LIBRARY=On .
-    make
-    ldd programs/util/strerror | grep libmbedcrypto
-    make test
-    programs/test/dlopen_demo.sh
-}
-
-test_build_opt () {
-    info=$1 cc=$2; shift 2
-    $cc --version
-    for opt in "$@"; do
-          msg "build/test: $cc $opt, $info" # ~ 30s
-          make CC="$cc" CFLAGS="$opt -std=c99 -pedantic -Wall -Wextra -Werror"
-          # We're confident enough in compilers to not run _all_ the tests,
-          # but at least run the unit tests. In particular, runs with
-          # optimizations use inline assembly whereas runs with -O0
-          # skip inline assembly.
-          make test # ~30s
-          make clean
-    done
-}
-
-# For FreeBSD we invoke the function by name so this condition is added
-# to disable the existing test_clang_opt function for linux.
-if [[ $(uname) != "Linux" ]]; then
-    component_test_clang_opt () {
-        scripts/config.py full
-        test_build_opt 'full config' clang -O0 -Os -O2
-    }
-fi
-
-component_test_clang_latest_opt () {
-    scripts/config.py full
-    test_build_opt 'full config' "$CLANG_LATEST" -O0 -Os -O2
-}
-support_test_clang_latest_opt () {
-    type "$CLANG_LATEST" >/dev/null 2>/dev/null
-}
-
-component_test_clang_earliest_opt () {
-    scripts/config.py full
-    test_build_opt 'full config' "$CLANG_EARLIEST" -O0
-}
-support_test_clang_earliest_opt () {
-    type "$CLANG_EARLIEST" >/dev/null 2>/dev/null
-}
-
-component_test_gcc_latest_opt () {
-    scripts/config.py full
-    test_build_opt 'full config' "$GCC_LATEST" -O0 -Os -O2
-}
-support_test_gcc_latest_opt () {
-    type "$GCC_LATEST" >/dev/null 2>/dev/null
-}
-
-component_test_gcc_earliest_opt () {
-    scripts/config.py full
-    test_build_opt 'full config' "$GCC_EARLIEST" -O0
-}
-support_test_gcc_earliest_opt () {
-    type "$GCC_EARLIEST" >/dev/null 2>/dev/null
-}
-
-component_build_mbedtls_config_file () {
-    msg "build: make with MBEDTLS_CONFIG_FILE" # ~40s
-    scripts/config.py -w full_config.h full
-    echo '#error "MBEDTLS_CONFIG_FILE is not working"' >"$CONFIG_H"
-    make CFLAGS="-I '$PWD' -DMBEDTLS_CONFIG_FILE='\"full_config.h\"'"
-    # Make sure this feature is enabled. We'll disable it in the next phase.
-    programs/test/query_compile_time_config MBEDTLS_NIST_KW_C
-    make clean
-
-    msg "build: make with MBEDTLS_CONFIG_FILE + MBEDTLS_USER_CONFIG_FILE"
-    # In the user config, disable one feature (for simplicity, pick a feature
-    # that nothing else depends on).
-    echo '#undef MBEDTLS_NIST_KW_C' >user_config.h
-    make CFLAGS="-I '$PWD' -DMBEDTLS_CONFIG_FILE='\"full_config.h\"' -DMBEDTLS_USER_CONFIG_FILE='\"user_config.h\"'"
-    not programs/test/query_compile_time_config MBEDTLS_NIST_KW_C
-
-    rm -f user_config.h full_config.h
-}
-
-component_build_psa_config_file () {
-    msg "build: make with MBEDTLS_PSA_CRYPTO_CONFIG_FILE" # ~40s
-    scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
-    cp "$CRYPTO_CONFIG_H" psa_test_config.h
-    echo '#error "MBEDTLS_PSA_CRYPTO_CONFIG_FILE is not working"' >"$CRYPTO_CONFIG_H"
-    make CFLAGS="-I '$PWD' -DMBEDTLS_PSA_CRYPTO_CONFIG_FILE='\"psa_test_config.h\"'"
-    # Make sure this feature is enabled. We'll disable it in the next phase.
-    programs/test/query_compile_time_config MBEDTLS_CMAC_C
-    make clean
-
-    msg "build: make with MBEDTLS_PSA_CRYPTO_CONFIG_FILE + MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE" # ~40s
-    # In the user config, disable one feature and its dependencies, which will
-    # reflect on the mbedtls configuration so we can query it with
-    # query_compile_time_config.
-    echo '#undef PSA_WANT_ALG_CMAC' >psa_user_config.h
-    echo '#undef PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128' >> psa_user_config.h
-    scripts/config.py unset MBEDTLS_CMAC_C
-    make CFLAGS="-I '$PWD' -DMBEDTLS_PSA_CRYPTO_CONFIG_FILE='\"psa_test_config.h\"' -DMBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE='\"psa_user_config.h\"'"
-    not programs/test/query_compile_time_config MBEDTLS_CMAC_C
-
-    rm -f psa_test_config.h psa_user_config.h
-}
-
-component_build_psa_alt_headers () {
-    msg "build: make with PSA alt headers" # ~20s
-
-    # Generate alternative versions of the substitutable headers with the
-    # same content except different include guards.
-    make -C tests include/alt-extra/psa/crypto_platform_alt.h include/alt-extra/psa/crypto_struct_alt.h
-
-    # Build the library and some programs.
-    # Don't build the fuzzers to avoid having to go through hoops to set
-    # a correct include path for programs/fuzz/Makefile.
-    make CFLAGS="-I ../tests/include/alt-extra -DMBEDTLS_PSA_CRYPTO_PLATFORM_FILE='\"psa/crypto_platform_alt.h\"' -DMBEDTLS_PSA_CRYPTO_STRUCT_FILE='\"psa/crypto_struct_alt.h\"'" lib
-    make -C programs -o fuzz CFLAGS="-I ../tests/include/alt-extra -DMBEDTLS_PSA_CRYPTO_PLATFORM_FILE='\"psa/crypto_platform_alt.h\"' -DMBEDTLS_PSA_CRYPTO_STRUCT_FILE='\"psa/crypto_struct_alt.h\"'"
-
-    # Check that we're getting the alternative include guards and not the
-    # original include guards.
-    programs/test/query_included_headers | grep -x PSA_CRYPTO_PLATFORM_ALT_H
-    programs/test/query_included_headers | grep -x PSA_CRYPTO_STRUCT_ALT_H
-    programs/test/query_included_headers | not grep -x PSA_CRYPTO_PLATFORM_H
-    programs/test/query_included_headers | not grep -x PSA_CRYPTO_STRUCT_H
-}
-
-component_test_m32_no_asm () {
-    # Build without assembly, so as to use portable C code (in a 32-bit
-    # build) and not the i386-specific inline assembly.
-    #
-    # Note that we require gcc, because clang Asan builds fail to link for
-    # this target (cannot find libclang_rt.lsan-i386.a - this is a known clang issue).
-    msg "build: i386, make, gcc, no asm (ASan build)" # ~ 30s
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_HAVE_ASM
-    scripts/config.py unset MBEDTLS_PADLOCK_C
-    scripts/config.py unset MBEDTLS_AESNI_C # AESNI for 32-bit is tested in test_aesni_m32
-    make CC=gcc CFLAGS="$ASAN_CFLAGS -m32" LDFLAGS="-m32 $ASAN_CFLAGS"
-
-    msg "test: i386, make, gcc, no asm (ASan build)"
-    make test
-}
-support_test_m32_no_asm () {
-    case $(uname -m) in
-        amd64|x86_64) true;;
-        *) false;;
-    esac
-}
-
-component_test_m32_o2 () {
-    # Build with optimization, to use the i386 specific inline assembly
-    # and go faster for tests.
-    msg "build: i386, make, gcc -O2 (ASan build)" # ~ 30s
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_AESNI_C # AESNI for 32-bit is tested in test_aesni_m32
-    make CC=gcc CFLAGS="$ASAN_CFLAGS -m32" LDFLAGS="-m32 $ASAN_CFLAGS"
-
-    msg "test: i386, make, gcc -O2 (ASan build)"
-    make test
-
-    msg "test ssl-opt.sh, i386, make, gcc-O2"
-    tests/ssl-opt.sh
-}
-support_test_m32_o2 () {
-    support_test_m32_no_asm "$@"
-}
-
-component_test_m32_everest () {
-    msg "build: i386, Everest ECDH context (ASan build)" # ~ 6 min
-    scripts/config.py set MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED
-    scripts/config.py unset MBEDTLS_AESNI_C # AESNI for 32-bit is tested in test_aesni_m32
-    make CC=gcc CFLAGS="$ASAN_CFLAGS -m32" LDFLAGS="-m32 $ASAN_CFLAGS"
-
-    msg "test: i386, Everest ECDH context - main suites (inc. selftests) (ASan build)" # ~ 50s
-    make test
-
-    msg "test: i386, Everest ECDH context - ECDH-related part of ssl-opt.sh (ASan build)" # ~ 5s
-    tests/ssl-opt.sh -f ECDH
-
-    msg "test: i386, Everest ECDH context - compat.sh with some ECDH ciphersuites (ASan build)" # ~ 3 min
-    # Exclude some symmetric ciphers that are redundant here to gain time.
-    tests/compat.sh -f ECDH -V NO -e 'ARIA\|CAMELLIA\|CHACHA'
-}
-support_test_m32_everest () {
-    support_test_m32_no_asm "$@"
-}
-
-component_test_mx32 () {
-    msg "build: 64-bit ILP32, make, gcc" # ~ 30s
-    scripts/config.py full
-    make CC=gcc CFLAGS='-O2 -Werror -Wall -Wextra -mx32' LDFLAGS='-mx32'
-
-    msg "test: 64-bit ILP32, make, gcc"
-    make test
-}
-support_test_mx32 () {
-    case $(uname -m) in
-        amd64|x86_64) true;;
-        *) false;;
-    esac
-}
-
-component_test_min_mpi_window_size () {
-    msg "build: Default + MBEDTLS_MPI_WINDOW_SIZE=1 (ASan build)" # ~ 10s
-    scripts/config.py set MBEDTLS_MPI_WINDOW_SIZE 1
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: MBEDTLS_MPI_WINDOW_SIZE=1 - main suites (inc. selftests) (ASan build)" # ~ 10s
-    make test
-}
-
-component_test_have_int32 () {
-    msg "build: gcc, force 32-bit bignum limbs"
-    scripts/config.py unset MBEDTLS_HAVE_ASM
-    scripts/config.py unset MBEDTLS_AESNI_C
-    scripts/config.py unset MBEDTLS_PADLOCK_C
-    scripts/config.py unset MBEDTLS_AESCE_C
-    make CC=gcc CFLAGS='-O2 -Werror -Wall -Wextra -DMBEDTLS_HAVE_INT32'
-
-    msg "test: gcc, force 32-bit bignum limbs"
-    make test
-}
-
-component_test_have_int64 () {
-    msg "build: gcc, force 64-bit bignum limbs"
-    scripts/config.py unset MBEDTLS_HAVE_ASM
-    scripts/config.py unset MBEDTLS_AESNI_C
-    scripts/config.py unset MBEDTLS_PADLOCK_C
-    scripts/config.py unset MBEDTLS_AESCE_C
-    make CC=gcc CFLAGS='-O2 -Werror -Wall -Wextra -DMBEDTLS_HAVE_INT64'
-
-    msg "test: gcc, force 64-bit bignum limbs"
-    make test
-}
-
-component_test_have_int32_cmake_new_bignum () {
-    msg "build: gcc, force 32-bit bignum limbs, new bignum interface, test hooks (ASan build)"
-    scripts/config.py unset MBEDTLS_HAVE_ASM
-    scripts/config.py unset MBEDTLS_AESNI_C
-    scripts/config.py unset MBEDTLS_PADLOCK_C
-    scripts/config.py unset MBEDTLS_AESCE_C
-    scripts/config.py set MBEDTLS_TEST_HOOKS
-    scripts/config.py set MBEDTLS_ECP_WITH_MPI_UINT
-    make CC=gcc CFLAGS="$ASAN_CFLAGS -Werror -Wall -Wextra -DMBEDTLS_HAVE_INT32" LDFLAGS="$ASAN_CFLAGS"
-
-    msg "test: gcc, force 32-bit bignum limbs, new bignum interface, test hooks (ASan build)"
-    make test
-}
-
-component_test_no_udbl_division () {
-    msg "build: MBEDTLS_NO_UDBL_DIVISION native" # ~ 10s
-    scripts/config.py full
-    scripts/config.py set MBEDTLS_NO_UDBL_DIVISION
-    make CFLAGS='-Werror -O1'
-
-    msg "test: MBEDTLS_NO_UDBL_DIVISION native" # ~ 10s
-    make test
-}
-
-component_test_no_64bit_multiplication () {
-    msg "build: MBEDTLS_NO_64BIT_MULTIPLICATION native" # ~ 10s
-    scripts/config.py full
-    scripts/config.py set MBEDTLS_NO_64BIT_MULTIPLICATION
-    make CFLAGS='-Werror -O1'
-
-    msg "test: MBEDTLS_NO_64BIT_MULTIPLICATION native" # ~ 10s
-    make test
-}
-
-component_test_no_strings () {
-    msg "build: no strings" # ~10s
-    scripts/config.py full
-    # Disable options that activate a large amount of string constants.
-    scripts/config.py unset MBEDTLS_DEBUG_C
-    scripts/config.py unset MBEDTLS_ERROR_C
-    scripts/config.py set MBEDTLS_ERROR_STRERROR_DUMMY
-    scripts/config.py unset MBEDTLS_VERSION_FEATURES
-    make CFLAGS='-Werror -Os'
-
-    msg "test: no strings" # ~ 10s
-    make test
-}
-
-component_test_no_x509_info () {
-    msg "build: full + MBEDTLS_X509_REMOVE_INFO" # ~ 10s
-    scripts/config.pl full
-    scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
-    scripts/config.pl set MBEDTLS_X509_REMOVE_INFO
-    make CFLAGS='-Werror -O2'
-
-    msg "test: full + MBEDTLS_X509_REMOVE_INFO" # ~ 10s
-    make test
-
-    msg "test: ssl-opt.sh, full + MBEDTLS_X509_REMOVE_INFO" # ~ 1 min
-    tests/ssl-opt.sh
-}
-
-component_build_arm_none_eabi_gcc () {
-    msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -O1, baremetal+debug" # ~ 10s
-    scripts/config.py baremetal
-    make CC="${ARM_NONE_EABI_GCC_PREFIX}gcc" AR="${ARM_NONE_EABI_GCC_PREFIX}ar" LD="${ARM_NONE_EABI_GCC_PREFIX}ld" CFLAGS='-std=c99 -Werror -Wall -Wextra -O1' lib
-
-    msg "size: ${ARM_NONE_EABI_GCC_PREFIX}gcc -O1, baremetal+debug"
-    ${ARM_NONE_EABI_GCC_PREFIX}size -t library/*.o
-}
-
-component_build_arm_linux_gnueabi_gcc_arm5vte () {
-    msg "build: ${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc -march=arm5vte, baremetal+debug" # ~ 10s
-    scripts/config.py baremetal
-    # Build for a target platform that's close to what Debian uses
-    # for its "armel" distribution (https://wiki.debian.org/ArmEabiPort).
-    # See https://github.com/Mbed-TLS/mbedtls/pull/2169 and comments.
-    # Build everything including programs, see for example
-    # https://github.com/Mbed-TLS/mbedtls/pull/3449#issuecomment-675313720
-    make CC="${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc" AR="${ARM_LINUX_GNUEABI_GCC_PREFIX}ar" CFLAGS='-Werror -Wall -Wextra -march=armv5te -O1' LDFLAGS='-march=armv5te'
-
-    msg "size: ${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc -march=armv5te -O1, baremetal+debug"
-    ${ARM_LINUX_GNUEABI_GCC_PREFIX}size -t library/*.o
-}
-support_build_arm_linux_gnueabi_gcc_arm5vte () {
-    type ${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc >/dev/null 2>&1
-}
-
-component_build_arm_none_eabi_gcc_arm5vte () {
-    msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -march=arm5vte, baremetal+debug" # ~ 10s
-    scripts/config.py baremetal
-    # This is an imperfect substitute for
-    # component_build_arm_linux_gnueabi_gcc_arm5vte
-    # in case the gcc-arm-linux-gnueabi toolchain is not available
-    make CC="${ARM_NONE_EABI_GCC_PREFIX}gcc" AR="${ARM_NONE_EABI_GCC_PREFIX}ar" CFLAGS='-std=c99 -Werror -Wall -Wextra -march=armv5te -O1' LDFLAGS='-march=armv5te' SHELL='sh -x' lib
-
-    msg "size: ${ARM_NONE_EABI_GCC_PREFIX}gcc -march=armv5te -O1, baremetal+debug"
-    ${ARM_NONE_EABI_GCC_PREFIX}size -t library/*.o
-}
-
-component_build_arm_none_eabi_gcc_m0plus () {
-    msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -mthumb -mcpu=cortex-m0plus, baremetal_size" # ~ 10s
-    scripts/config.py baremetal_size
-    make CC="${ARM_NONE_EABI_GCC_PREFIX}gcc" AR="${ARM_NONE_EABI_GCC_PREFIX}ar" LD="${ARM_NONE_EABI_GCC_PREFIX}ld" CFLAGS='-std=c99 -Werror -Wall -Wextra -mthumb -mcpu=cortex-m0plus -Os' lib
-
-    msg "size: ${ARM_NONE_EABI_GCC_PREFIX}gcc -mthumb -mcpu=cortex-m0plus -Os, baremetal_size"
-    ${ARM_NONE_EABI_GCC_PREFIX}size -t library/*.o
-    for lib in library/*.a; do
-        echo "$lib:"
-        ${ARM_NONE_EABI_GCC_PREFIX}size -t $lib | grep TOTALS
-    done
-}
-
-component_build_arm_none_eabi_gcc_no_udbl_division () {
-    msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -DMBEDTLS_NO_UDBL_DIVISION, make" # ~ 10s
-    scripts/config.py baremetal
-    scripts/config.py set MBEDTLS_NO_UDBL_DIVISION
-    make CC="${ARM_NONE_EABI_GCC_PREFIX}gcc" AR="${ARM_NONE_EABI_GCC_PREFIX}ar" LD="${ARM_NONE_EABI_GCC_PREFIX}ld" CFLAGS='-std=c99 -Werror -Wall -Wextra' lib
-    echo "Checking that software 64-bit division is not required"
-    not grep __aeabi_uldiv library/*.o
-}
-
-component_build_arm_none_eabi_gcc_no_64bit_multiplication () {
-    msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc MBEDTLS_NO_64BIT_MULTIPLICATION, make" # ~ 10s
-    scripts/config.py baremetal
-    scripts/config.py set MBEDTLS_NO_64BIT_MULTIPLICATION
-    make CC="${ARM_NONE_EABI_GCC_PREFIX}gcc" AR="${ARM_NONE_EABI_GCC_PREFIX}ar" LD="${ARM_NONE_EABI_GCC_PREFIX}ld" CFLAGS='-std=c99 -Werror -O1 -march=armv6-m -mthumb' lib
-    echo "Checking that software 64-bit multiplication is not required"
-    not grep __aeabi_lmul library/*.o
-}
-
-component_build_arm_clang_thumb () {
-    # ~ 30s
-
-    scripts/config.py baremetal
-
-    msg "build: clang thumb 2, make"
-    make clean
-    make CC="clang" CFLAGS='-std=c99 -Werror -Os --target=arm-linux-gnueabihf -march=armv7-m -mthumb' lib
-
-    # Some Thumb 1 asm is sensitive to optimisation level, so test both -O0 and -Os
-    msg "build: clang thumb 1 -O0, make"
-    make clean
-    make CC="clang" CFLAGS='-std=c99 -Werror -O0 --target=arm-linux-gnueabihf -mcpu=arm1136j-s -mthumb' lib
-
-    msg "build: clang thumb 1 -Os, make"
-    make clean
-    make CC="clang" CFLAGS='-std=c99 -Werror -Os --target=arm-linux-gnueabihf -mcpu=arm1136j-s -mthumb' lib
-}
-
-component_build_armcc () {
-    msg "build: ARM Compiler 5"
-    scripts/config.py baremetal
-    # armc[56] don't support SHA-512 intrinsics
-    scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
-
-    # older versions of armcc/armclang don't support AESCE_C on 32-bit Arm
-    scripts/config.py unset MBEDTLS_AESCE_C
-
-    # Stop armclang warning about feature detection for A64_CRYPTO.
-    # With this enabled, the library does build correctly under armclang,
-    # but in baremetal builds (as tested here), feature detection is
-    # unavailable, and the user is notified via a #warning. So enabling
-    # this feature would prevent us from building with -Werror on
-    # armclang. Tracked in #7198.
-    scripts/config.py unset MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
-
-    scripts/config.py set MBEDTLS_HAVE_ASM
-
-    make CC="$ARMC5_CC" AR="$ARMC5_AR" WARNING_CFLAGS='--strict --c99' lib
-
-    msg "size: ARM Compiler 5"
-    "$ARMC5_FROMELF" -z library/*.o
-
-    # Compile mostly with -O1 since some Arm inline assembly is disabled for -O0.
-
-    # ARM Compiler 6 - Target ARMv7-A
-    armc6_build_test "-O1 --target=arm-arm-none-eabi -march=armv7-a"
-
-    # ARM Compiler 6 - Target ARMv7-M
-    armc6_build_test "-O1 --target=arm-arm-none-eabi -march=armv7-m"
-
-    # ARM Compiler 6 - Target ARMv7-M+DSP
-    armc6_build_test "-O1 --target=arm-arm-none-eabi -march=armv7-m+dsp"
-
-    # ARM Compiler 6 - Target ARMv8-A - AArch32
-    armc6_build_test "-O1 --target=arm-arm-none-eabi -march=armv8.2-a"
-
-    # ARM Compiler 6 - Target ARMv8-M
-    armc6_build_test "-O1 --target=arm-arm-none-eabi -march=armv8-m.main"
-
-    # ARM Compiler 6 - Target Cortex-M0 - no optimisation
-    armc6_build_test "-O0 --target=arm-arm-none-eabi -mcpu=cortex-m0"
-
-    # ARM Compiler 6 - Target Cortex-M0
-    armc6_build_test "-Os --target=arm-arm-none-eabi -mcpu=cortex-m0"
-
-    # ARM Compiler 6 - Target ARMv8.2-A - AArch64
-    #
-    # Re-enable MBEDTLS_AESCE_C as this should be supported by the version of armclang
-    # that we have in our CI
-    scripts/config.py set MBEDTLS_AESCE_C
-    armc6_build_test "-O1 --target=aarch64-arm-none-eabi -march=armv8.2-a+crypto"
-}
-
-support_build_armcc () {
-    armc5_cc="$ARMC5_BIN_DIR/armcc"
-    armc6_cc="$ARMC6_BIN_DIR/armclang"
-    (check_tools "$armc5_cc" "$armc6_cc" > /dev/null 2>&1)
-}
-
-component_test_tls12_only () {
-    msg "build: default config without MBEDTLS_SSL_PROTO_TLS1_3, cmake, gcc, ASan"
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: main suites (inc. selftests) (ASan build)"
-    make test
-
-    msg "test: ssl-opt.sh (ASan build)"
-    tests/ssl-opt.sh
-
-    msg "test: compat.sh (ASan build)"
-    tests/compat.sh
-}
-
-component_test_tls13_only () {
-    msg "build: default config without MBEDTLS_SSL_PROTO_TLS1_2"
-    scripts/config.py set MBEDTLS_SSL_EARLY_DATA
-    scripts/config.py set MBEDTLS_SSL_RECORD_SIZE_LIMIT
-    make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
-
-    msg "test: TLS 1.3 only, all key exchange modes enabled"
-    make test
-
-    msg "ssl-opt.sh: TLS 1.3 only, all key exchange modes enabled"
-    tests/ssl-opt.sh
-}
-
-component_test_tls13_only_psk () {
-    msg "build: TLS 1.3 only from default, only PSK key exchange mode"
-    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
-    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-    scripts/config.py unset MBEDTLS_ECDH_C
-    scripts/config.py unset MBEDTLS_DHM_C
-    scripts/config.py unset MBEDTLS_X509_CRT_PARSE_C
-    scripts/config.py unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
-    scripts/config.py unset MBEDTLS_SSL_SERVER_NAME_INDICATION
-    scripts/config.py unset MBEDTLS_ECDSA_C
-    scripts/config.py unset MBEDTLS_PKCS1_V21
-    scripts/config.py unset MBEDTLS_PKCS7_C
-    scripts/config.py set   MBEDTLS_SSL_EARLY_DATA
-    make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
-
-    msg "test_suite_ssl: TLS 1.3 only, only PSK key exchange mode enabled"
-    cd tests; ./test_suite_ssl; cd ..
-
-    msg "ssl-opt.sh: TLS 1.3 only, only PSK key exchange mode enabled"
-    tests/ssl-opt.sh
-}
-
-component_test_tls13_only_ephemeral () {
-    msg "build: TLS 1.3 only from default, only ephemeral key exchange mode"
-    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
-    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-    scripts/config.py unset MBEDTLS_SSL_EARLY_DATA
-    make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
-
-    msg "test_suite_ssl: TLS 1.3 only, only ephemeral key exchange mode"
-    cd tests; ./test_suite_ssl; cd ..
-
-    msg "ssl-opt.sh: TLS 1.3 only, only ephemeral key exchange mode"
-    tests/ssl-opt.sh
-}
-
-component_test_tls13_only_ephemeral_ffdh () {
-    msg "build: TLS 1.3 only from default, only ephemeral ffdh key exchange mode"
-    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
-    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
-    scripts/config.py unset MBEDTLS_SSL_EARLY_DATA
-    scripts/config.py unset MBEDTLS_ECDH_C
-
-    make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
-
-    msg "test_suite_ssl: TLS 1.3 only, only ephemeral ffdh key exchange mode"
-    cd tests; ./test_suite_ssl; cd ..
-
-    msg "ssl-opt.sh: TLS 1.3 only, only ephemeral ffdh key exchange mode"
-    tests/ssl-opt.sh
-}
-
-component_test_tls13_only_psk_ephemeral () {
-    msg "build: TLS 1.3 only from default, only PSK ephemeral key exchange mode"
-    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
-    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
-    scripts/config.py unset MBEDTLS_X509_CRT_PARSE_C
-    scripts/config.py unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
-    scripts/config.py unset MBEDTLS_SSL_SERVER_NAME_INDICATION
-    scripts/config.py unset MBEDTLS_ECDSA_C
-    scripts/config.py unset MBEDTLS_PKCS1_V21
-    scripts/config.py unset MBEDTLS_PKCS7_C
-    scripts/config.py set   MBEDTLS_SSL_EARLY_DATA
-    make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
-
-    msg "test_suite_ssl: TLS 1.3 only, only PSK ephemeral key exchange mode"
-    cd tests; ./test_suite_ssl; cd ..
-
-    msg "ssl-opt.sh: TLS 1.3 only, only PSK ephemeral key exchange mode"
-    tests/ssl-opt.sh
-}
-
-component_test_tls13_only_psk_ephemeral_ffdh () {
-    msg "build: TLS 1.3 only from default, only PSK ephemeral ffdh key exchange mode"
-    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
-    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
-    scripts/config.py unset MBEDTLS_X509_CRT_PARSE_C
-    scripts/config.py unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
-    scripts/config.py unset MBEDTLS_SSL_SERVER_NAME_INDICATION
-    scripts/config.py unset MBEDTLS_ECDSA_C
-    scripts/config.py unset MBEDTLS_PKCS1_V21
-    scripts/config.py unset MBEDTLS_PKCS7_C
-    scripts/config.py set   MBEDTLS_SSL_EARLY_DATA
-    scripts/config.py unset MBEDTLS_ECDH_C
-    make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
-
-    msg "test_suite_ssl: TLS 1.3 only, only PSK ephemeral ffdh key exchange mode"
-    cd tests; ./test_suite_ssl; cd ..
-
-    msg "ssl-opt.sh: TLS 1.3 only, only PSK ephemeral ffdh key exchange mode"
-    tests/ssl-opt.sh
-}
-
-component_test_tls13_only_psk_all () {
-    msg "build: TLS 1.3 only from default, without ephemeral key exchange mode"
-    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
-    scripts/config.py unset MBEDTLS_X509_CRT_PARSE_C
-    scripts/config.py unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
-    scripts/config.py unset MBEDTLS_SSL_SERVER_NAME_INDICATION
-    scripts/config.py unset MBEDTLS_ECDSA_C
-    scripts/config.py unset MBEDTLS_PKCS1_V21
-    scripts/config.py unset MBEDTLS_PKCS7_C
-    scripts/config.py set   MBEDTLS_SSL_EARLY_DATA
-    make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
-
-    msg "test_suite_ssl: TLS 1.3 only, PSK and PSK ephemeral key exchange modes"
-    cd tests; ./test_suite_ssl; cd ..
-
-    msg "ssl-opt.sh: TLS 1.3 only, PSK and PSK ephemeral key exchange modes"
-    tests/ssl-opt.sh
-}
-
-component_test_tls13_only_ephemeral_all () {
-    msg "build: TLS 1.3 only from default, without PSK key exchange mode"
-    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
-    scripts/config.py set   MBEDTLS_SSL_EARLY_DATA
-    make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
-
-    msg "test_suite_ssl: TLS 1.3 only, ephemeral and PSK ephemeral key exchange modes"
-    cd tests; ./test_suite_ssl; cd ..
-
-    msg "ssl-opt.sh: TLS 1.3 only, ephemeral and PSK ephemeral key exchange modes"
-    tests/ssl-opt.sh
-}
-
-component_test_tls13_no_padding () {
-    msg "build: default config plus early data minus padding"
-    scripts/config.py set MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY 1
-    scripts/config.py set MBEDTLS_SSL_EARLY_DATA
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-    msg "test: default config plus early data minus padding"
-    make test
-    msg "ssl-opt.sh (TLS 1.3 no padding)"
-    tests/ssl-opt.sh
-}
-
-component_test_tls13_no_compatibility_mode () {
-    msg "build: default config plus early data minus middlebox compatibility mode"
-    scripts/config.py unset MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
-    scripts/config.py set   MBEDTLS_SSL_EARLY_DATA
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-    msg "test: default config plus early data minus middlebox compatibility mode"
-    make test
-    msg "ssl-opt.sh (TLS 1.3 no compatibility mode)"
-    tests/ssl-opt.sh
-}
-
-component_test_full_minus_session_tickets() {
-    msg "build: full config without session tickets"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_SSL_SESSION_TICKETS
-    scripts/config.py unset MBEDTLS_SSL_EARLY_DATA
-    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-    msg "test: full config without session tickets"
-    make test
-    msg "ssl-opt.sh (full config without session tickets)"
-    tests/ssl-opt.sh
-}
-
-component_build_mingw () {
-    msg "build: Windows cross build - mingw64, make (Link Library)" # ~ 30s
-    make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra -maes -msse2 -mpclmul' WINDOWS_BUILD=1 lib programs
-
-    # note Make tests only builds the tests, but doesn't run them
-    make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -maes -msse2 -mpclmul' WINDOWS_BUILD=1 tests
-    make WINDOWS_BUILD=1 clean
-
-    msg "build: Windows cross build - mingw64, make (DLL)" # ~ 30s
-    make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra -maes -msse2 -mpclmul' WINDOWS_BUILD=1 SHARED=1 lib programs
-    make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra -maes -msse2 -mpclmul' WINDOWS_BUILD=1 SHARED=1 tests
-    make WINDOWS_BUILD=1 clean
-
-    msg "build: Windows cross build - mingw64, make (Library only, default config without MBEDTLS_AESNI_C)" # ~ 30s
-    ./scripts/config.py unset MBEDTLS_AESNI_C #
-    make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 lib
-    make WINDOWS_BUILD=1 clean
-}
-support_build_mingw() {
-    case $(i686-w64-mingw32-gcc -dumpversion 2>/dev/null) in
-        [0-5]*|"") false;;
-        *) true;;
-    esac
-}
-
-component_test_memsan () {
-    msg "build: MSan (clang)" # ~ 1 min 20s
-    scripts/config.py unset MBEDTLS_AESNI_C # memsan doesn't grok asm
-    CC=clang cmake -D CMAKE_BUILD_TYPE:String=MemSan .
-    make
-
-    msg "test: main suites (MSan)" # ~ 10s
-    make test
-
-    msg "test: metatests (MSan)"
-    tests/scripts/run-metatests.sh any msan
-
-    msg "program demos (MSan)" # ~20s
-    tests/scripts/run_demos.py
-
-    msg "test: ssl-opt.sh (MSan)" # ~ 1 min
-    tests/ssl-opt.sh
-
-    # Optional part(s)
-
-    if [ "$MEMORY" -gt 0 ]; then
-        msg "test: compat.sh (MSan)" # ~ 6 min 20s
-        tests/compat.sh
-    fi
-}
-
-component_release_test_valgrind () {
-    msg "build: Release (clang)"
-    # default config, in particular without MBEDTLS_USE_PSA_CRYPTO
-    CC=clang cmake -D CMAKE_BUILD_TYPE:String=Release .
-    make
-
-    msg "test: main suites, Valgrind (default config)"
-    make memcheck
-
-    # Optional parts (slow; currently broken on OS X because programs don't
-    # seem to receive signals under valgrind on OS X).
-    # These optional parts don't run on the CI.
-    if [ "$MEMORY" -gt 0 ]; then
-        msg "test: ssl-opt.sh --memcheck (default config)"
-        tests/ssl-opt.sh --memcheck
-    fi
-
-    if [ "$MEMORY" -gt 1 ]; then
-        msg "test: compat.sh --memcheck (default config)"
-        tests/compat.sh --memcheck
-    fi
-
-    if [ "$MEMORY" -gt 0 ]; then
-        msg "test: context-info.sh --memcheck (default config)"
-        tests/context-info.sh --memcheck
-    fi
-}
-
-component_release_test_valgrind_psa () {
-    msg "build: Release, full (clang)"
-    # full config, in particular with MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py full
-    CC=clang cmake -D CMAKE_BUILD_TYPE:String=Release .
-    make
-
-    msg "test: main suites, Valgrind (full config)"
-    make memcheck
-}
-
-support_test_cmake_out_of_source () {
-    distrib_id=""
-    distrib_ver=""
-    distrib_ver_minor=""
-    distrib_ver_major=""
-
-    # Attempt to parse lsb-release to find out distribution and version. If not
-    # found this should fail safe (test is supported).
-    if [[ -f /etc/lsb-release ]]; then
-
-        while read -r lsb_line; do
-            case "$lsb_line" in
-                "DISTRIB_ID"*) distrib_id=${lsb_line/#DISTRIB_ID=};;
-                "DISTRIB_RELEASE"*) distrib_ver=${lsb_line/#DISTRIB_RELEASE=};;
-            esac
-        done < /etc/lsb-release
-
-        distrib_ver_major="${distrib_ver%%.*}"
-        distrib_ver="${distrib_ver#*.}"
-        distrib_ver_minor="${distrib_ver%%.*}"
-    fi
-
-    # Running the out of source CMake test on Ubuntu 16.04 using more than one
-    # processor (as the CI does) can create a race condition whereby the build
-    # fails to see a generated file, despite that file actually having been
-    # generated. This problem appears to go away with 18.04 or newer, so make
-    # the out of source tests unsupported on Ubuntu 16.04.
-    [ "$distrib_id" != "Ubuntu" ] || [ "$distrib_ver_major" -gt 16 ]
-}
-
-component_test_cmake_out_of_source () {
-    # Remove existing generated files so that we use the ones cmake
-    # generates
-    make neat
-
-    msg "build: cmake 'out-of-source' build"
-    MBEDTLS_ROOT_DIR="$PWD"
-    mkdir "$OUT_OF_SOURCE_DIR"
-    cd "$OUT_OF_SOURCE_DIR"
-    # Note: Explicitly generate files as these are turned off in releases
-    cmake -D CMAKE_BUILD_TYPE:String=Check -D GEN_FILES=ON "$MBEDTLS_ROOT_DIR"
-    make
-
-    msg "test: cmake 'out-of-source' build"
-    make test
-    # Check that ssl-opt.sh can find the test programs.
-    # Also ensure that there are no error messages such as
-    # "No such file or directory", which would indicate that some required
-    # file is missing (ssl-opt.sh tolerates the absence of some files so
-    # may exit with status 0 but emit errors).
-    ./tests/ssl-opt.sh -f 'Default' >ssl-opt.out 2>ssl-opt.err
-    grep PASS ssl-opt.out
-    cat ssl-opt.err >&2
-    # If ssl-opt.err is non-empty, record an error and keep going.
-    [ ! -s ssl-opt.err ]
-    rm ssl-opt.out ssl-opt.err
-    cd "$MBEDTLS_ROOT_DIR"
-    rm -rf "$OUT_OF_SOURCE_DIR"
-}
-
-component_test_cmake_as_subdirectory () {
-    # Remove existing generated files so that we use the ones CMake
-    # generates
-    make neat
-
-    msg "build: cmake 'as-subdirectory' build"
-    cd programs/test/cmake_subproject
-    # Note: Explicitly generate files as these are turned off in releases
-    cmake -D GEN_FILES=ON .
-    make
-    ./cmake_subproject
-}
-support_test_cmake_as_subdirectory () {
-    support_test_cmake_out_of_source
-}
-
-component_test_cmake_as_package () {
-    # Remove existing generated files so that we use the ones CMake
-    # generates
-    make neat
-
-    msg "build: cmake 'as-package' build"
-    cd programs/test/cmake_package
-    cmake .
-    make
-    ./cmake_package
-}
-support_test_cmake_as_package () {
-    support_test_cmake_out_of_source
-}
-
-component_test_cmake_as_package_install () {
-    # Remove existing generated files so that we use the ones CMake
-    # generates
-    make neat
-
-    msg "build: cmake 'as-installed-package' build"
-    cd programs/test/cmake_package_install
-    cmake .
-    make
-    ./cmake_package_install
-}
-support_test_cmake_as_package_install () {
-    support_test_cmake_out_of_source
-}
-
-component_build_cmake_custom_config_file () {
-    # Make a copy of config file to use for the in-tree test
-    cp "$CONFIG_H" include/mbedtls_config_in_tree_copy.h
-
-    MBEDTLS_ROOT_DIR="$PWD"
-    mkdir "$OUT_OF_SOURCE_DIR"
-    cd "$OUT_OF_SOURCE_DIR"
-
-    # Build once to get the generated files (which need an intact config file)
-    cmake "$MBEDTLS_ROOT_DIR"
-    make
-
-    msg "build: cmake with -DMBEDTLS_CONFIG_FILE"
-    scripts/config.py -w full_config.h full
-    echo '#error "cmake -DMBEDTLS_CONFIG_FILE is not working."' > "$MBEDTLS_ROOT_DIR/$CONFIG_H"
-    cmake -DGEN_FILES=OFF -DMBEDTLS_CONFIG_FILE=full_config.h "$MBEDTLS_ROOT_DIR"
-    make
-
-    msg "build: cmake with -DMBEDTLS_CONFIG_FILE + -DMBEDTLS_USER_CONFIG_FILE"
-    # In the user config, disable one feature (for simplicity, pick a feature
-    # that nothing else depends on).
-    echo '#undef MBEDTLS_NIST_KW_C' >user_config.h
-
-    cmake -DGEN_FILES=OFF -DMBEDTLS_CONFIG_FILE=full_config.h -DMBEDTLS_USER_CONFIG_FILE=user_config.h "$MBEDTLS_ROOT_DIR"
-    make
-    not programs/test/query_compile_time_config MBEDTLS_NIST_KW_C
-
-    rm -f user_config.h full_config.h
-
-    cd "$MBEDTLS_ROOT_DIR"
-    rm -rf "$OUT_OF_SOURCE_DIR"
-
-    # Now repeat the test for an in-tree build:
-
-    # Restore config for the in-tree test
-    mv include/mbedtls_config_in_tree_copy.h "$CONFIG_H"
-
-    # Build once to get the generated files (which need an intact config)
-    cmake .
-    make
-
-    msg "build: cmake (in-tree) with -DMBEDTLS_CONFIG_FILE"
-    scripts/config.py -w full_config.h full
-    echo '#error "cmake -DMBEDTLS_CONFIG_FILE is not working."' > "$MBEDTLS_ROOT_DIR/$CONFIG_H"
-    cmake -DGEN_FILES=OFF -DMBEDTLS_CONFIG_FILE=full_config.h .
-    make
-
-    msg "build: cmake (in-tree) with -DMBEDTLS_CONFIG_FILE + -DMBEDTLS_USER_CONFIG_FILE"
-    # In the user config, disable one feature (for simplicity, pick a feature
-    # that nothing else depends on).
-    echo '#undef MBEDTLS_NIST_KW_C' >user_config.h
-
-    cmake -DGEN_FILES=OFF -DMBEDTLS_CONFIG_FILE=full_config.h -DMBEDTLS_USER_CONFIG_FILE=user_config.h .
-    make
-    not programs/test/query_compile_time_config MBEDTLS_NIST_KW_C
-
-    rm -f user_config.h full_config.h
-}
-support_build_cmake_custom_config_file () {
-    support_test_cmake_out_of_source
-}
-
-component_build_cmake_programs_no_testing () {
-    # Verify that the type of builds performed by oss-fuzz don't get accidentally broken
-    msg "build: cmake with -DENABLE_PROGRAMS=ON and -DENABLE_TESTING=OFF"
-    cmake -DENABLE_PROGRAMS=ON -DENABLE_TESTING=OFF .
-    make
-}
-support_build_cmake_programs_no_testing () {
-    support_test_cmake_out_of_source
-}
-
-component_build_zeroize_checks () {
-    msg "build: check for obviously wrong calls to mbedtls_platform_zeroize()"
-
-    scripts/config.py full
-
-    # Only compile - we're looking for sizeof-pointer-memaccess warnings
-    make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/user-config-zeroize-memset.h\"' -DMBEDTLS_TEST_DEFINES_ZEROIZE -Werror -Wsizeof-pointer-memaccess"
-}
-
-
-component_test_zeroize () {
-    # Test that the function mbedtls_platform_zeroize() is not optimized away by
-    # different combinations of compilers and optimization flags by using an
-    # auxiliary GDB script. Unfortunately, GDB does not return error values to the
-    # system in all cases that the script fails, so we must manually search the
-    # output to check whether the pass string is present and no failure strings
-    # were printed.
-
-    # Don't try to disable ASLR. We don't care about ASLR here. We do care
-    # about a spurious message if Gdb tries and fails, so suppress that.
-    gdb_disable_aslr=
-    if [ -z "$(gdb -batch -nw -ex 'set disable-randomization off' 2>&1)" ]; then
-        gdb_disable_aslr='set disable-randomization off'
-    fi
-
-    for optimization_flag in -O2 -O3 -Ofast -Os; do
-        for compiler in clang gcc; do
-            msg "test: $compiler $optimization_flag, mbedtls_platform_zeroize()"
-            make programs CC="$compiler" DEBUG=1 CFLAGS="$optimization_flag"
-            gdb -ex "$gdb_disable_aslr" -x tests/scripts/test_zeroize.gdb -nw -batch -nx 2>&1 | tee test_zeroize.log
-            grep "The buffer was correctly zeroized" test_zeroize.log
-            not grep -i "error" test_zeroize.log
-            rm -f test_zeroize.log
-            make clean
-        done
-    done
-}
-
-component_test_psa_compliance () {
-    # The arch tests build with gcc, so require use of gcc here to link properly
-    msg "build: make, default config (out-of-box), libmbedcrypto.a only"
-    CC=gcc make -C library libmbedcrypto.a
-
-    msg "unit test: test_psa_compliance.py"
-    CC=gcc ./tests/scripts/test_psa_compliance.py
-}
-
-support_test_psa_compliance () {
-    # psa-compliance-tests only supports CMake >= 3.10.0
-    ver="$(cmake --version)"
-    ver="${ver#cmake version }"
-    ver_major="${ver%%.*}"
-
-    ver="${ver#*.}"
-    ver_minor="${ver%%.*}"
-
-    [ "$ver_major" -eq 3 ] && [ "$ver_minor" -ge 10 ]
-}
-
-component_check_code_style () {
-    msg "Check C code style"
-    ./scripts/code_style.py
-}
-
-support_check_code_style() {
-    case $(uncrustify --version) in
-        *0.75.1*) true;;
-        *) false;;
-    esac
-}
-
-component_check_python_files () {
-    msg "Lint: Python scripts"
-    tests/scripts/check-python-files.sh
-}
-
-component_check_test_helpers () {
-    msg "unit test: generate_test_code.py"
-    # unittest writes out mundane stuff like number or tests run on stderr.
-    # Our convention is to reserve stderr for actual errors, and write
-    # harmless info on stdout so it can be suppress with --quiet.
-    ./framework/scripts/test_generate_test_code.py 2>&1
-
-    msg "unit test: translate_ciphers.py"
-    python3 -m unittest tests/scripts/translate_ciphers.py 2>&1
-}
-
+# Include the components from components.sh
+test_script_dir="${0%/*}"
+for file in "$test_script_dir"/components*.sh; do
+    source $file
+done
 
 ################################################################
 #### Termination
@@ -6461,8 +1024,6 @@
     final_report
 }
 
-
-
 ################################################################
 #### Run all the things
 ################################################################
diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py
index 993e23c..082ed01 100755
--- a/tests/scripts/analyze_outcomes.py
+++ b/tests/scripts/analyze_outcomes.py
@@ -642,8 +642,9 @@
                     re.compile(r'mbedtls_ct_memmove_left .*')
                 ],
                 'test_suite_psa_crypto': [
-                    # We don't support generate_key_ext entry points
+                    # We don't support generate_key_custom entry points
                     # in drivers yet.
+                    re.compile(r'PSA generate key custom: RSA, e=.*'),
                     re.compile(r'PSA generate key ext: RSA, e=.*'),
                 ],
             }
diff --git a/tests/scripts/components-basic-checks.sh b/tests/scripts/components-basic-checks.sh
new file mode 100644
index 0000000..053aacf
--- /dev/null
+++ b/tests/scripts/components-basic-checks.sh
@@ -0,0 +1,162 @@
+# components-basic-checks.sh
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+# This file contains test components that are executed by all.sh
+
+################################################################
+#### Basic checks
+################################################################
+
+component_check_recursion () {
+    msg "Check: recursion.pl" # < 1s
+    tests/scripts/recursion.pl library/*.c
+}
+
+component_check_generated_files () {
+    msg "Check: check-generated-files, files generated with make" # 2s
+    make generated_files
+    tests/scripts/check-generated-files.sh
+
+    msg "Check: check-generated-files -u, files present" # 2s
+    tests/scripts/check-generated-files.sh -u
+    # Check that the generated files are considered up to date.
+    tests/scripts/check-generated-files.sh
+
+    msg "Check: check-generated-files -u, files absent" # 2s
+    command make neat
+    tests/scripts/check-generated-files.sh -u
+    # Check that the generated files are considered up to date.
+    tests/scripts/check-generated-files.sh
+
+    # This component ends with the generated files present in the source tree.
+    # This is necessary for subsequent components!
+}
+
+component_check_doxy_blocks () {
+    msg "Check: doxygen markup outside doxygen blocks" # < 1s
+    tests/scripts/check-doxy-blocks.pl
+}
+
+component_check_files () {
+    msg "Check: file sanity checks (permissions, encodings)" # < 1s
+    tests/scripts/check_files.py
+}
+
+component_check_changelog () {
+    msg "Check: changelog entries" # < 1s
+    rm -f ChangeLog.new
+    scripts/assemble_changelog.py -o ChangeLog.new
+    if [ -e ChangeLog.new ]; then
+        # Show the diff for information. It isn't an error if the diff is
+        # non-empty.
+        diff -u ChangeLog ChangeLog.new || true
+        rm ChangeLog.new
+    fi
+}
+
+component_check_names () {
+    msg "Check: declared and exported names (builds the library)" # < 3s
+    tests/scripts/check_names.py -v
+}
+
+component_check_test_cases () {
+    msg "Check: test case descriptions" # < 1s
+    if [ $QUIET -eq 1 ]; then
+        opt='--quiet'
+    else
+        opt=''
+    fi
+    tests/scripts/check_test_cases.py -q $opt
+    unset opt
+}
+
+component_check_test_dependencies () {
+    msg "Check: test case dependencies: legacy vs PSA" # < 1s
+    # The purpose of this component is to catch unjustified dependencies on
+    # legacy feature macros (MBEDTLS_xxx) in PSA tests. Generally speaking,
+    # PSA test should use PSA feature macros (PSA_WANT_xxx, more rarely
+    # MBEDTLS_PSA_xxx).
+    #
+    # Most of the time, use of legacy MBEDTLS_xxx macros are mistakes, which
+    # this component is meant to catch. However a few of them are justified,
+    # mostly by the absence of a PSA equivalent, so this component includes a
+    # list of expected exceptions.
+
+    found="check-test-deps-found-$$"
+    expected="check-test-deps-expected-$$"
+
+    # Find legacy dependencies in PSA tests
+    grep 'depends_on' \
+        tests/suites/test_suite_psa*.data tests/suites/test_suite_psa*.function |
+        grep -Eo '!?MBEDTLS_[^: ]*' |
+        grep -v -e MBEDTLS_PSA_ -e MBEDTLS_TEST_ |
+        sort -u > $found
+
+    # Expected ones with justification - keep in sorted order by ASCII table!
+    rm -f $expected
+    # No PSA equivalent - WANT_KEY_TYPE_AES means all sizes
+    echo "!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH" >> $expected
+    # No PSA equivalent - used to skip decryption tests in PSA-ECB, CBC/XTS/NIST_KW/DES
+    echo "!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT" >> $expected
+    # MBEDTLS_ASN1_WRITE_C is used by import_rsa_made_up() in test_suite_psa_crypto
+    # in order to build a fake RSA key of the wanted size based on
+    # PSA_VENDOR_RSA_MAX_KEY_BITS. The legacy module is only used by
+    # the test code and that's probably the most convenient way of achieving
+    # the test's goal.
+    echo "MBEDTLS_ASN1_WRITE_C" >> $expected
+    # No PSA equivalent - we should probably have one in the future.
+    echo "MBEDTLS_ECP_RESTARTABLE" >> $expected
+    # No PSA equivalent - needed by some init tests
+    echo "MBEDTLS_ENTROPY_NV_SEED" >> $expected
+    # No PSA equivalent - required to run threaded tests.
+    echo "MBEDTLS_THREADING_PTHREAD" >> $expected
+
+    # Compare reality with expectation.
+    # We want an exact match, to ensure the above list remains up-to-date.
+    #
+    # The output should be empty. When it's not:
+    # - Each '+' line is a macro that was found but not expected. You want to
+    # find where that macro occurs, and either replace it with PSA macros, or
+    # add it to the exceptions list above with a justification.
+    # - Each '-' line is a macro that was expected but not found; it means the
+    # exceptions list above should be updated by removing that macro.
+    diff -U0 $expected $found
+
+    rm $found $expected
+}
+
+component_check_doxygen_warnings () {
+    msg "Check: doxygen warnings (builds the documentation)" # ~ 3s
+    tests/scripts/doxygen.sh
+}
+
+component_check_code_style () {
+    msg "Check C code style"
+    ./scripts/code_style.py
+}
+
+support_check_code_style () {
+    case $(uncrustify --version) in
+        *0.75.1*) true;;
+        *) false;;
+    esac
+}
+
+component_check_python_files () {
+    msg "Lint: Python scripts"
+    tests/scripts/check-python-files.sh
+}
+
+component_check_test_helpers () {
+    msg "unit test: generate_test_code.py"
+    # unittest writes out mundane stuff like number or tests run on stderr.
+    # Our convention is to reserve stderr for actual errors, and write
+    # harmless info on stdout so it can be suppress with --quiet.
+    ./framework/scripts/test_generate_test_code.py 2>&1
+
+    msg "unit test: translate_ciphers.py"
+    python3 -m unittest tests/scripts/translate_ciphers.py 2>&1
+}
+
diff --git a/tests/scripts/components-build-system.sh b/tests/scripts/components-build-system.sh
new file mode 100644
index 0000000..c41aa48
--- /dev/null
+++ b/tests/scripts/components-build-system.sh
@@ -0,0 +1,210 @@
+# components-build-system.sh
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+# This file contains test components that are executed by all.sh
+
+################################################################
+#### Build System Testing
+################################################################
+
+component_test_make_shared () {
+    msg "build/test: make shared" # ~ 40s
+    make SHARED=1 TEST_CPP=1 all check
+    ldd programs/util/strerror | grep libmbedcrypto
+    programs/test/dlopen_demo.sh
+}
+
+component_test_cmake_shared () {
+    msg "build/test: cmake shared" # ~ 2min
+    cmake -DUSE_SHARED_MBEDTLS_LIBRARY=On .
+    make
+    ldd programs/util/strerror | grep libmbedcrypto
+    make test
+    programs/test/dlopen_demo.sh
+}
+
+support_test_cmake_out_of_source () {
+    distrib_id=""
+    distrib_ver=""
+    distrib_ver_minor=""
+    distrib_ver_major=""
+
+    # Attempt to parse lsb-release to find out distribution and version. If not
+    # found this should fail safe (test is supported).
+    if [[ -f /etc/lsb-release ]]; then
+
+        while read -r lsb_line; do
+            case "$lsb_line" in
+                "DISTRIB_ID"*) distrib_id=${lsb_line/#DISTRIB_ID=};;
+                "DISTRIB_RELEASE"*) distrib_ver=${lsb_line/#DISTRIB_RELEASE=};;
+            esac
+        done < /etc/lsb-release
+
+        distrib_ver_major="${distrib_ver%%.*}"
+        distrib_ver="${distrib_ver#*.}"
+        distrib_ver_minor="${distrib_ver%%.*}"
+    fi
+
+    # Running the out of source CMake test on Ubuntu 16.04 using more than one
+    # processor (as the CI does) can create a race condition whereby the build
+    # fails to see a generated file, despite that file actually having been
+    # generated. This problem appears to go away with 18.04 or newer, so make
+    # the out of source tests unsupported on Ubuntu 16.04.
+    [ "$distrib_id" != "Ubuntu" ] || [ "$distrib_ver_major" -gt 16 ]
+}
+
+component_test_cmake_out_of_source () {
+    # Remove existing generated files so that we use the ones cmake
+    # generates
+    make neat
+
+    msg "build: cmake 'out-of-source' build"
+    MBEDTLS_ROOT_DIR="$PWD"
+    mkdir "$OUT_OF_SOURCE_DIR"
+    cd "$OUT_OF_SOURCE_DIR"
+    # Note: Explicitly generate files as these are turned off in releases
+    cmake -D CMAKE_BUILD_TYPE:String=Check -D GEN_FILES=ON -D TEST_CPP=1 "$MBEDTLS_ROOT_DIR"
+    make
+
+    msg "test: cmake 'out-of-source' build"
+    make test
+    # Check that ssl-opt.sh can find the test programs.
+    # Also ensure that there are no error messages such as
+    # "No such file or directory", which would indicate that some required
+    # file is missing (ssl-opt.sh tolerates the absence of some files so
+    # may exit with status 0 but emit errors).
+    ./tests/ssl-opt.sh -f 'Default' >ssl-opt.out 2>ssl-opt.err
+    grep PASS ssl-opt.out
+    cat ssl-opt.err >&2
+    # If ssl-opt.err is non-empty, record an error and keep going.
+    [ ! -s ssl-opt.err ]
+    rm ssl-opt.out ssl-opt.err
+    cd "$MBEDTLS_ROOT_DIR"
+    rm -rf "$OUT_OF_SOURCE_DIR"
+}
+
+component_test_cmake_as_subdirectory () {
+    # Remove existing generated files so that we use the ones CMake
+    # generates
+    make neat
+
+    msg "build: cmake 'as-subdirectory' build"
+    cd programs/test/cmake_subproject
+    # Note: Explicitly generate files as these are turned off in releases
+    cmake -D GEN_FILES=ON .
+    make
+    ./cmake_subproject
+}
+
+support_test_cmake_as_subdirectory () {
+    support_test_cmake_out_of_source
+}
+
+component_test_cmake_as_package () {
+    # Remove existing generated files so that we use the ones CMake
+    # generates
+    make neat
+
+    msg "build: cmake 'as-package' build"
+    cd programs/test/cmake_package
+    cmake .
+    make
+    ./cmake_package
+}
+
+support_test_cmake_as_package () {
+    support_test_cmake_out_of_source
+}
+
+component_test_cmake_as_package_install () {
+    # Remove existing generated files so that we use the ones CMake
+    # generates
+    make neat
+
+    msg "build: cmake 'as-installed-package' build"
+    cd programs/test/cmake_package_install
+    cmake .
+    make
+    ./cmake_package_install
+}
+
+support_test_cmake_as_package_install () {
+    support_test_cmake_out_of_source
+}
+
+component_build_cmake_custom_config_file () {
+    # Make a copy of config file to use for the in-tree test
+    cp "$CONFIG_H" include/mbedtls_config_in_tree_copy.h
+
+    MBEDTLS_ROOT_DIR="$PWD"
+    mkdir "$OUT_OF_SOURCE_DIR"
+    cd "$OUT_OF_SOURCE_DIR"
+
+    # Build once to get the generated files (which need an intact config file)
+    cmake "$MBEDTLS_ROOT_DIR"
+    make
+
+    msg "build: cmake with -DMBEDTLS_CONFIG_FILE"
+    scripts/config.py -w full_config.h full
+    echo '#error "cmake -DMBEDTLS_CONFIG_FILE is not working."' > "$MBEDTLS_ROOT_DIR/$CONFIG_H"
+    cmake -DGEN_FILES=OFF -DMBEDTLS_CONFIG_FILE=full_config.h "$MBEDTLS_ROOT_DIR"
+    make
+
+    msg "build: cmake with -DMBEDTLS_CONFIG_FILE + -DMBEDTLS_USER_CONFIG_FILE"
+    # In the user config, disable one feature (for simplicity, pick a feature
+    # that nothing else depends on).
+    echo '#undef MBEDTLS_NIST_KW_C' >user_config.h
+
+    cmake -DGEN_FILES=OFF -DMBEDTLS_CONFIG_FILE=full_config.h -DMBEDTLS_USER_CONFIG_FILE=user_config.h "$MBEDTLS_ROOT_DIR"
+    make
+    not programs/test/query_compile_time_config MBEDTLS_NIST_KW_C
+
+    rm -f user_config.h full_config.h
+
+    cd "$MBEDTLS_ROOT_DIR"
+    rm -rf "$OUT_OF_SOURCE_DIR"
+
+    # Now repeat the test for an in-tree build:
+
+    # Restore config for the in-tree test
+    mv include/mbedtls_config_in_tree_copy.h "$CONFIG_H"
+
+    # Build once to get the generated files (which need an intact config)
+    cmake .
+    make
+
+    msg "build: cmake (in-tree) with -DMBEDTLS_CONFIG_FILE"
+    scripts/config.py -w full_config.h full
+    echo '#error "cmake -DMBEDTLS_CONFIG_FILE is not working."' > "$MBEDTLS_ROOT_DIR/$CONFIG_H"
+    cmake -DGEN_FILES=OFF -DMBEDTLS_CONFIG_FILE=full_config.h .
+    make
+
+    msg "build: cmake (in-tree) with -DMBEDTLS_CONFIG_FILE + -DMBEDTLS_USER_CONFIG_FILE"
+    # In the user config, disable one feature (for simplicity, pick a feature
+    # that nothing else depends on).
+    echo '#undef MBEDTLS_NIST_KW_C' >user_config.h
+
+    cmake -DGEN_FILES=OFF -DMBEDTLS_CONFIG_FILE=full_config.h -DMBEDTLS_USER_CONFIG_FILE=user_config.h .
+    make
+    not programs/test/query_compile_time_config MBEDTLS_NIST_KW_C
+
+    rm -f user_config.h full_config.h
+}
+
+support_build_cmake_custom_config_file () {
+    support_test_cmake_out_of_source
+}
+
+component_build_cmake_programs_no_testing () {
+    # Verify that the type of builds performed by oss-fuzz don't get accidentally broken
+    msg "build: cmake with -DENABLE_PROGRAMS=ON and -DENABLE_TESTING=OFF"
+    cmake -DENABLE_PROGRAMS=ON -DENABLE_TESTING=OFF .
+    make
+}
+
+support_build_cmake_programs_no_testing () {
+    support_test_cmake_out_of_source
+}
+
diff --git a/tests/scripts/components-compiler.sh b/tests/scripts/components-compiler.sh
new file mode 100644
index 0000000..5badabb
--- /dev/null
+++ b/tests/scripts/components-compiler.sh
@@ -0,0 +1,145 @@
+# components-compiler.sh
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+# This file contains test components that are executed by all.sh
+
+################################################################
+#### Compiler Testing
+################################################################
+
+support_build_tfm_armcc () {
+    support_build_armcc
+}
+
+component_build_tfm_armcc () {
+    # test the TF-M configuration can build cleanly with various warning flags enabled
+    cp configs/config-tfm.h "$CONFIG_H"
+
+    msg "build: TF-M config, armclang armv7-m thumb2"
+    armc6_build_test "--target=arm-arm-none-eabi -march=armv7-m -mthumb -Os -std=c99 -Werror -Wall -Wextra -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow -Wvla -Wformat=2 -Wno-format-nonliteral -Wshadow -Wasm-operand-widths -Wunused -I../tests/include/spe"
+}
+
+test_build_opt () {
+    info=$1 cc=$2; shift 2
+    $cc --version
+    for opt in "$@"; do
+          msg "build/test: $cc $opt, $info" # ~ 30s
+          make CC="$cc" CFLAGS="$opt -std=c99 -pedantic -Wall -Wextra -Werror"
+          # We're confident enough in compilers to not run _all_ the tests,
+          # but at least run the unit tests. In particular, runs with
+          # optimizations use inline assembly whereas runs with -O0
+          # skip inline assembly.
+          make test # ~30s
+          make clean
+    done
+}
+
+# For FreeBSD we invoke the function by name so this condition is added
+# to disable the existing test_clang_opt function for linux.
+if [[ $(uname) != "Linux" ]]; then
+    component_test_clang_opt () {
+        scripts/config.py full
+        test_build_opt 'full config' clang -O0 -Os -O2
+    }
+fi
+
+component_test_clang_latest_opt () {
+    scripts/config.py full
+    test_build_opt 'full config' "$CLANG_LATEST" -O0 -Os -O2
+}
+
+support_test_clang_latest_opt () {
+    type "$CLANG_LATEST" >/dev/null 2>/dev/null
+}
+
+component_test_clang_earliest_opt () {
+    scripts/config.py full
+    test_build_opt 'full config' "$CLANG_EARLIEST" -O0
+}
+
+support_test_clang_earliest_opt () {
+    type "$CLANG_EARLIEST" >/dev/null 2>/dev/null
+}
+
+component_test_gcc_latest_opt () {
+    scripts/config.py full
+    test_build_opt 'full config' "$GCC_LATEST" -O0 -Os -O2
+}
+
+support_test_gcc_latest_opt () {
+    type "$GCC_LATEST" >/dev/null 2>/dev/null
+}
+
+component_test_gcc_earliest_opt () {
+    scripts/config.py full
+    test_build_opt 'full config' "$GCC_EARLIEST" -O0
+}
+
+support_test_gcc_earliest_opt () {
+    type "$GCC_EARLIEST" >/dev/null 2>/dev/null
+}
+
+component_build_mingw () {
+    msg "build: Windows cross build - mingw64, make (Link Library)" # ~ 30s
+    make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra -maes -msse2 -mpclmul' WINDOWS_BUILD=1 lib programs
+
+    # note Make tests only builds the tests, but doesn't run them
+    make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -maes -msse2 -mpclmul' WINDOWS_BUILD=1 tests
+    make WINDOWS_BUILD=1 clean
+
+    msg "build: Windows cross build - mingw64, make (DLL)" # ~ 30s
+    make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra -maes -msse2 -mpclmul' WINDOWS_BUILD=1 SHARED=1 lib programs
+    make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra -maes -msse2 -mpclmul' WINDOWS_BUILD=1 SHARED=1 tests
+    make WINDOWS_BUILD=1 clean
+
+    msg "build: Windows cross build - mingw64, make (Library only, default config without MBEDTLS_AESNI_C)" # ~ 30s
+    ./scripts/config.py unset MBEDTLS_AESNI_C #
+    make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 lib
+    make WINDOWS_BUILD=1 clean
+}
+
+support_build_mingw () {
+    case $(i686-w64-mingw32-gcc -dumpversion 2>/dev/null) in
+        [0-5]*|"") false;;
+        *) true;;
+    esac
+}
+
+component_build_zeroize_checks () {
+    msg "build: check for obviously wrong calls to mbedtls_platform_zeroize()"
+
+    scripts/config.py full
+
+    # Only compile - we're looking for sizeof-pointer-memaccess warnings
+    make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/user-config-zeroize-memset.h\"' -DMBEDTLS_TEST_DEFINES_ZEROIZE -Werror -Wsizeof-pointer-memaccess"
+}
+
+component_test_zeroize () {
+    # Test that the function mbedtls_platform_zeroize() is not optimized away by
+    # different combinations of compilers and optimization flags by using an
+    # auxiliary GDB script. Unfortunately, GDB does not return error values to the
+    # system in all cases that the script fails, so we must manually search the
+    # output to check whether the pass string is present and no failure strings
+    # were printed.
+
+    # Don't try to disable ASLR. We don't care about ASLR here. We do care
+    # about a spurious message if Gdb tries and fails, so suppress that.
+    gdb_disable_aslr=
+    if [ -z "$(gdb -batch -nw -ex 'set disable-randomization off' 2>&1)" ]; then
+        gdb_disable_aslr='set disable-randomization off'
+    fi
+
+    for optimization_flag in -O2 -O3 -Ofast -Os; do
+        for compiler in clang gcc; do
+            msg "test: $compiler $optimization_flag, mbedtls_platform_zeroize()"
+            make programs CC="$compiler" DEBUG=1 CFLAGS="$optimization_flag"
+            gdb -ex "$gdb_disable_aslr" -x tests/scripts/test_zeroize.gdb -nw -batch -nx 2>&1 | tee test_zeroize.log
+            grep "The buffer was correctly zeroized" test_zeroize.log
+            not grep -i "error" test_zeroize.log
+            rm -f test_zeroize.log
+            make clean
+        done
+    done
+}
diff --git a/tests/scripts/components-compliance.sh b/tests/scripts/components-compliance.sh
new file mode 100644
index 0000000..38bcd01
--- /dev/null
+++ b/tests/scripts/components-compliance.sh
@@ -0,0 +1,31 @@
+# components-compliance.sh
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+# This file contains test components that are executed by all.sh
+
+################################################################
+#### Compliance Testing
+################################################################
+
+component_test_psa_compliance () {
+    # The arch tests build with gcc, so require use of gcc here to link properly
+    msg "build: make, default config (out-of-box), libmbedcrypto.a only"
+    CC=gcc make -C library libmbedcrypto.a
+
+    msg "unit test: test_psa_compliance.py"
+    CC=gcc ./tests/scripts/test_psa_compliance.py
+}
+
+support_test_psa_compliance () {
+    # psa-compliance-tests only supports CMake >= 3.10.0
+    ver="$(cmake --version)"
+    ver="${ver#cmake version }"
+    ver_major="${ver%%.*}"
+
+    ver="${ver#*.}"
+    ver_minor="${ver%%.*}"
+
+    [ "$ver_major" -eq 3 ] && [ "$ver_minor" -ge 10 ]
+}
diff --git a/tests/scripts/components-configuration-crypto.sh b/tests/scripts/components-configuration-crypto.sh
new file mode 100644
index 0000000..39b9d5d
--- /dev/null
+++ b/tests/scripts/components-configuration-crypto.sh
@@ -0,0 +1,3107 @@
+# components-configuration-crypto.sh
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+# This file contains test components that are executed by all.sh
+
+################################################################
+#### Configuration Testing - Crypto
+################################################################
+
+component_test_psa_crypto_key_id_encodes_owner () {
+    msg "build: full config + PSA_CRYPTO_KEY_ID_ENCODES_OWNER, cmake, gcc, ASan"
+    scripts/config.py full
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
+    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: full config - USE_PSA_CRYPTO + PSA_CRYPTO_KEY_ID_ENCODES_OWNER, cmake, gcc, ASan"
+    make test
+}
+
+component_test_psa_assume_exclusive_buffers () {
+    msg "build: full config + MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS, cmake, gcc, ASan"
+    scripts/config.py full
+    scripts/config.py set MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS
+    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: full config + MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS, cmake, gcc, ASan"
+    make test
+}
+
+# check_renamed_symbols HEADER LIB
+# Check that if HEADER contains '#define MACRO ...' then MACRO is not a symbol
+# name in LIB.
+check_renamed_symbols () {
+    ! nm "$2" | sed 's/.* //' |
+      grep -x -F "$(sed -n 's/^ *# *define  *\([A-Z_a-z][0-9A-Z_a-z]*\)..*/\1/p' "$1")"
+}
+
+component_build_psa_crypto_spm () {
+    msg "build: full config + PSA_CRYPTO_KEY_ID_ENCODES_OWNER + PSA_CRYPTO_SPM, make, gcc"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_SPM
+    # We can only compile, not link, since our test and sample programs
+    # aren't equipped for the modified names used when MBEDTLS_PSA_CRYPTO_SPM
+    # is active.
+    make CC=gcc CFLAGS='-Werror -Wall -Wextra -I../tests/include/spe' lib
+
+    # Check that if a symbol is renamed by crypto_spe.h, the non-renamed
+    # version is not present.
+    echo "Checking for renamed symbols in the library"
+    check_renamed_symbols tests/include/spe/crypto_spe.h library/libmbedcrypto.a
+}
+
+# Get a list of library-wise undefined symbols and ensure that they only
+# belong to psa_xxx() functions and not to mbedtls_yyy() ones.
+# This function is a common helper used by both:
+# - component_test_default_psa_crypto_client_without_crypto_provider
+# - component_build_full_psa_crypto_client_without_crypto_provider.
+common_check_mbedtls_missing_symbols () {
+    nm library/libmbedcrypto.a | grep ' [TRrDC] ' | grep -Eo '(mbedtls_|psa_).*' | sort -u > sym_def.txt
+    nm library/libmbedcrypto.a | grep ' U ' | grep -Eo '(mbedtls_|psa_).*' | sort -u > sym_undef.txt
+    comm sym_def.txt sym_undef.txt -13 > linking_errors.txt
+    not grep mbedtls_ linking_errors.txt
+
+    rm sym_def.txt sym_undef.txt linking_errors.txt
+}
+
+component_test_default_psa_crypto_client_without_crypto_provider () {
+    msg "build: default config - PSA_CRYPTO_C + PSA_CRYPTO_CLIENT"
+
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_C
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C
+    scripts/config.py unset MBEDTLS_PSA_ITS_FILE_C
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_CLIENT
+    scripts/config.py unset MBEDTLS_LMS_C
+
+    make
+
+    msg "check missing symbols: default config - PSA_CRYPTO_C + PSA_CRYPTO_CLIENT"
+    common_check_mbedtls_missing_symbols
+
+    msg "test: default config - PSA_CRYPTO_C + PSA_CRYPTO_CLIENT"
+    make test
+}
+
+component_build_full_psa_crypto_client_without_crypto_provider () {
+    msg "build: full config - PSA_CRYPTO_C"
+
+    # Use full config which includes USE_PSA and CRYPTO_CLIENT.
+    scripts/config.py full
+
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_C
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C
+    # Dynamic secure element support is a deprecated feature and it is not
+    # available when CRYPTO_C and PSA_CRYPTO_STORAGE_C are disabled.
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
+
+    # Since there is no crypto provider in this build it is not possible to
+    # build all the test executables and progrems due to missing PSA functions
+    # at link time. Therefore we will just build libraries and we'll check
+    # that symbols of interest are there.
+    make lib
+
+    msg "check missing symbols: full config - PSA_CRYPTO_C"
+
+    common_check_mbedtls_missing_symbols
+
+    # Ensure that desired functions are included into the build (extend the
+    # following list as required).
+    grep mbedtls_pk_get_psa_attributes library/libmbedcrypto.a
+    grep mbedtls_pk_import_into_psa library/libmbedcrypto.a
+    grep mbedtls_pk_copy_from_psa library/libmbedcrypto.a
+}
+
+component_test_psa_crypto_rsa_no_genprime () {
+    msg "build: default config minus MBEDTLS_GENPRIME"
+    scripts/config.py unset MBEDTLS_GENPRIME
+    make
+
+    msg "test: default config minus MBEDTLS_GENPRIME"
+    make test
+}
+
+component_test_no_pem_no_fs () {
+    msg "build: Default + !MBEDTLS_PEM_PARSE_C + !MBEDTLS_FS_IO (ASan build)"
+    scripts/config.py unset MBEDTLS_PEM_PARSE_C
+    scripts/config.py unset MBEDTLS_FS_IO
+    scripts/config.py unset MBEDTLS_PSA_ITS_FILE_C # requires a filesystem
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C # requires PSA ITS
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: !MBEDTLS_PEM_PARSE_C !MBEDTLS_FS_IO - main suites (inc. selftests) (ASan build)" # ~ 50s
+    make test
+
+    msg "test: !MBEDTLS_PEM_PARSE_C !MBEDTLS_FS_IO - ssl-opt.sh (ASan build)" # ~ 6 min
+    tests/ssl-opt.sh
+}
+
+component_test_rsa_no_crt () {
+    msg "build: Default + RSA_NO_CRT (ASan build)" # ~ 6 min
+    scripts/config.py set MBEDTLS_RSA_NO_CRT
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: RSA_NO_CRT - main suites (inc. selftests) (ASan build)" # ~ 50s
+    make test
+
+    msg "test: RSA_NO_CRT - RSA-related part of ssl-opt.sh (ASan build)" # ~ 5s
+    tests/ssl-opt.sh -f RSA
+
+    msg "test: RSA_NO_CRT - RSA-related part of compat.sh (ASan build)" # ~ 3 min
+    tests/compat.sh -t RSA
+
+    msg "test: RSA_NO_CRT - RSA-related part of context-info.sh (ASan build)" # ~ 15 sec
+    tests/context-info.sh
+}
+
+component_test_no_ctr_drbg_classic () {
+    msg "build: Full minus CTR_DRBG, classic crypto in TLS"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_CTR_DRBG_C
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: Full minus CTR_DRBG, classic crypto - main suites"
+    make test
+
+    # In this configuration, the TLS test programs use HMAC_DRBG.
+    # The SSL tests are slow, so run a small subset, just enough to get
+    # confidence that the SSL code copes with HMAC_DRBG.
+    msg "test: Full minus CTR_DRBG, classic crypto - ssl-opt.sh (subset)"
+    tests/ssl-opt.sh -f 'Default\|SSL async private.*delay=\|tickets enabled on server'
+
+    msg "test: Full minus CTR_DRBG, classic crypto - compat.sh (subset)"
+    tests/compat.sh -m tls12 -t 'ECDSA PSK' -V NO -p OpenSSL
+}
+
+component_test_no_ctr_drbg_use_psa () {
+    msg "build: Full minus CTR_DRBG, PSA crypto in TLS"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_CTR_DRBG_C
+    scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
+
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: Full minus CTR_DRBG, USE_PSA_CRYPTO - main suites"
+    make test
+
+    # In this configuration, the TLS test programs use HMAC_DRBG.
+    # The SSL tests are slow, so run a small subset, just enough to get
+    # confidence that the SSL code copes with HMAC_DRBG.
+    msg "test: Full minus CTR_DRBG, USE_PSA_CRYPTO - ssl-opt.sh (subset)"
+    tests/ssl-opt.sh -f 'Default\|SSL async private.*delay=\|tickets enabled on server'
+
+    msg "test: Full minus CTR_DRBG, USE_PSA_CRYPTO - compat.sh (subset)"
+    tests/compat.sh -m tls12 -t 'ECDSA PSK' -V NO -p OpenSSL
+}
+
+component_test_no_hmac_drbg_classic () {
+    msg "build: Full minus HMAC_DRBG, classic crypto in TLS"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_HMAC_DRBG_C
+    scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC # requires HMAC_DRBG
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: Full minus HMAC_DRBG, classic crypto - main suites"
+    make test
+
+    # Normally our ECDSA implementation uses deterministic ECDSA. But since
+    # HMAC_DRBG is disabled in this configuration, randomized ECDSA is used
+    # instead.
+    # Test SSL with non-deterministic ECDSA. Only test features that
+    # might be affected by how ECDSA signature is performed.
+    msg "test: Full minus HMAC_DRBG, classic crypto - ssl-opt.sh (subset)"
+    tests/ssl-opt.sh -f 'Default\|SSL async private: sign'
+
+    # To save time, only test one protocol version, since this part of
+    # the protocol is identical in (D)TLS up to 1.2.
+    msg "test: Full minus HMAC_DRBG, classic crypto - compat.sh (ECDSA)"
+    tests/compat.sh -m tls12 -t 'ECDSA'
+}
+
+component_test_no_hmac_drbg_use_psa () {
+    msg "build: Full minus HMAC_DRBG, PSA crypto in TLS"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_HMAC_DRBG_C
+    scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC # requires HMAC_DRBG
+    scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
+
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: Full minus HMAC_DRBG, USE_PSA_CRYPTO - main suites"
+    make test
+
+    # Normally our ECDSA implementation uses deterministic ECDSA. But since
+    # HMAC_DRBG is disabled in this configuration, randomized ECDSA is used
+    # instead.
+    # Test SSL with non-deterministic ECDSA. Only test features that
+    # might be affected by how ECDSA signature is performed.
+    msg "test: Full minus HMAC_DRBG, USE_PSA_CRYPTO - ssl-opt.sh (subset)"
+    tests/ssl-opt.sh -f 'Default\|SSL async private: sign'
+
+    # To save time, only test one protocol version, since this part of
+    # the protocol is identical in (D)TLS up to 1.2.
+    msg "test: Full minus HMAC_DRBG, USE_PSA_CRYPTO - compat.sh (ECDSA)"
+    tests/compat.sh -m tls12 -t 'ECDSA'
+}
+
+component_test_psa_external_rng_no_drbg_classic () {
+    msg "build: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG, classic crypto in TLS"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
+    scripts/config.py unset MBEDTLS_ENTROPY_C
+    scripts/config.py unset MBEDTLS_ENTROPY_NV_SEED
+    scripts/config.py unset MBEDTLS_PLATFORM_NV_SEED_ALT
+    scripts/config.py unset MBEDTLS_CTR_DRBG_C
+    scripts/config.py unset MBEDTLS_HMAC_DRBG_C
+    scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC # requires HMAC_DRBG
+    # When MBEDTLS_USE_PSA_CRYPTO is disabled and there is no DRBG,
+    # the SSL test programs don't have an RNG and can't work. Explicitly
+    # make them use the PSA RNG with -DMBEDTLS_TEST_USE_PSA_CRYPTO_RNG.
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DMBEDTLS_TEST_USE_PSA_CRYPTO_RNG" LDFLAGS="$ASAN_CFLAGS"
+
+    msg "test: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG, classic crypto - main suites"
+    make test
+
+    msg "test: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG, classic crypto - ssl-opt.sh (subset)"
+    tests/ssl-opt.sh -f 'Default'
+}
+
+component_test_psa_external_rng_no_drbg_use_psa () {
+    msg "build: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG, PSA crypto in TLS"
+    scripts/config.py full
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
+    scripts/config.py unset MBEDTLS_ENTROPY_C
+    scripts/config.py unset MBEDTLS_ENTROPY_NV_SEED
+    scripts/config.py unset MBEDTLS_PLATFORM_NV_SEED_ALT
+    scripts/config.py unset MBEDTLS_CTR_DRBG_C
+    scripts/config.py unset MBEDTLS_HMAC_DRBG_C
+    scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC # requires HMAC_DRBG
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
+
+    msg "test: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG, PSA crypto - main suites"
+    make test
+
+    msg "test: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG, PSA crypto - ssl-opt.sh (subset)"
+    tests/ssl-opt.sh -f 'Default\|opaque'
+}
+
+component_test_psa_external_rng_use_psa_crypto () {
+    msg "build: full + PSA_CRYPTO_EXTERNAL_RNG + USE_PSA_CRYPTO minus CTR_DRBG"
+    scripts/config.py full
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
+    scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_CTR_DRBG_C
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
+
+    msg "test: full + PSA_CRYPTO_EXTERNAL_RNG + USE_PSA_CRYPTO minus CTR_DRBG"
+    make test
+
+    msg "test: full + PSA_CRYPTO_EXTERNAL_RNG + USE_PSA_CRYPTO minus CTR_DRBG"
+    tests/ssl-opt.sh -f 'Default\|opaque'
+}
+
+component_test_psa_inject_entropy () {
+    msg "build: full + MBEDTLS_PSA_INJECT_ENTROPY"
+    scripts/config.py full
+    scripts/config.py set MBEDTLS_PSA_INJECT_ENTROPY
+    scripts/config.py set MBEDTLS_ENTROPY_NV_SEED
+    scripts/config.py set MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+    scripts/config.py unset MBEDTLS_PLATFORM_NV_SEED_ALT
+    scripts/config.py unset MBEDTLS_PLATFORM_STD_NV_SEED_READ
+    scripts/config.py unset MBEDTLS_PLATFORM_STD_NV_SEED_WRITE
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS '-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/user-config-for-test.h\"'" LDFLAGS="$ASAN_CFLAGS"
+
+    msg "test: full + MBEDTLS_PSA_INJECT_ENTROPY"
+    make test
+}
+
+component_full_no_pkparse_pkwrite () {
+    msg "build: full without pkparse and pkwrite"
+
+    scripts/config.py crypto_full
+    scripts/config.py unset MBEDTLS_PK_PARSE_C
+    scripts/config.py unset MBEDTLS_PK_WRITE_C
+
+    make CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
+
+    # Ensure that PK_[PARSE|WRITE]_C were not re-enabled accidentally (additive config).
+    not grep mbedtls_pk_parse_key library/pkparse.o
+    not grep mbedtls_pk_write_key_der library/pkwrite.o
+
+    msg "test: full without pkparse and pkwrite"
+    make test
+}
+
+component_test_crypto_full_md_light_only () {
+    msg "build: crypto_full with only the light subset of MD"
+    scripts/config.py crypto_full
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_CONFIG
+    # Disable MD
+    scripts/config.py unset MBEDTLS_MD_C
+    # Disable direct dependencies of MD_C
+    scripts/config.py unset MBEDTLS_HKDF_C
+    scripts/config.py unset MBEDTLS_HMAC_DRBG_C
+    scripts/config.py unset MBEDTLS_PKCS7_C
+    # Disable indirect dependencies of MD_C
+    scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC # needs HMAC_DRBG
+    # Disable things that would auto-enable MD_C
+    scripts/config.py unset MBEDTLS_PKCS5_C
+
+    # Note: MD-light is auto-enabled in build_info.h by modules that need it,
+    # which we haven't disabled, so no need to explicitly enable it.
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
+
+    # Make sure we don't have the HMAC functions, but the hashing functions
+    not grep mbedtls_md_hmac library/md.o
+    grep mbedtls_md library/md.o
+
+    msg "test: crypto_full with only the light subset of MD"
+    make test
+}
+
+component_test_full_no_cipher_no_psa_crypto () {
+    msg "build: full no CIPHER no PSA_CRYPTO_C"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_CIPHER_C
+    # Don't pull in cipher via PSA mechanisms
+    # (currently ignored anyway because we completely disable PSA)
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_CONFIG
+    # Disable features that depend on CIPHER_C
+    scripts/config.py unset MBEDTLS_CMAC_C
+    scripts/config.py unset MBEDTLS_NIST_KW_C
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_C
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_CLIENT
+    scripts/config.py unset MBEDTLS_SSL_TLS_C
+    scripts/config.py unset MBEDTLS_SSL_TICKET_C
+    # Disable features that depend on PSA_CRYPTO_C
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_LMS_C
+    scripts/config.py unset MBEDTLS_LMS_PRIVATE
+
+    msg "test: full no CIPHER no PSA_CRYPTO_C"
+    make test
+}
+
+# This is a common configurator and test function that is used in:
+# - component_test_full_no_cipher_with_psa_crypto
+# - component_test_full_no_cipher_with_psa_crypto_config
+# It accepts 2 input parameters:
+# - $1: boolean value which basically reflects status of MBEDTLS_PSA_CRYPTO_CONFIG
+# - $2: a text string which describes the test component
+common_test_full_no_cipher_with_psa_crypto () {
+    USE_CRYPTO_CONFIG="$1"
+    COMPONENT_DESCRIPTION="$2"
+
+    msg "build: $COMPONENT_DESCRIPTION"
+
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_CIPHER_C
+
+    if [ "$USE_CRYPTO_CONFIG" -eq 1 ]; then
+        # The built-in implementation of the following algs/key-types depends
+        # on CIPHER_C so we disable them.
+        # This does not hold for KEY_TYPE_CHACHA20 and ALG_CHACHA20_POLY1305
+        # so we keep them enabled.
+        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_CCM_STAR_NO_TAG
+        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_CMAC
+        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_CBC_NO_PADDING
+        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_CBC_PKCS7
+        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_CFB
+        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_CTR
+        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_ECB_NO_PADDING
+        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_OFB
+        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128
+        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_STREAM_CIPHER
+        scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_KEY_TYPE_DES
+    else
+        # Don't pull in cipher via PSA mechanisms
+        scripts/config.py unset MBEDTLS_PSA_CRYPTO_CONFIG
+        # Disable cipher modes/keys that make PSA depend on CIPHER_C.
+        # Keep CHACHA20 and CHACHAPOLY enabled since they do not depend on CIPHER_C.
+        scripts/config.py unset-all MBEDTLS_CIPHER_MODE
+    fi
+    # The following modules directly depends on CIPHER_C
+    scripts/config.py unset MBEDTLS_CMAC_C
+    scripts/config.py unset MBEDTLS_NIST_KW_C
+
+    make
+
+    # Ensure that CIPHER_C was not re-enabled
+    not grep mbedtls_cipher_init library/cipher.o
+
+    msg "test: $COMPONENT_DESCRIPTION"
+    make test
+}
+
+component_test_full_no_cipher_with_psa_crypto () {
+    common_test_full_no_cipher_with_psa_crypto 0 "full no CIPHER no CRYPTO_CONFIG"
+}
+
+component_test_full_no_cipher_with_psa_crypto_config () {
+    common_test_full_no_cipher_with_psa_crypto 1 "full no CIPHER"
+}
+
+component_test_full_no_ccm () {
+    msg "build: full no PSA_WANT_ALG_CCM"
+
+    # Full config enables:
+    # - USE_PSA_CRYPTO so that TLS code dispatches cipher/AEAD to PSA
+    # - CRYPTO_CONFIG so that PSA_WANT config symbols are evaluated
+    scripts/config.py full
+
+    # Disable PSA_WANT_ALG_CCM so that CCM is not supported in PSA. CCM_C is still
+    # enabled, but not used from TLS since USE_PSA is set.
+    # This is helpful to ensure that TLS tests below have proper dependencies.
+    #
+    # Note: also PSA_WANT_ALG_CCM_STAR_NO_TAG is enabled, but it does not cause
+    # PSA_WANT_ALG_CCM to be re-enabled.
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CCM
+
+    make
+
+    msg "test: full no PSA_WANT_ALG_CCM"
+    make test
+}
+
+component_test_full_no_ccm_star_no_tag () {
+    msg "build: full no PSA_WANT_ALG_CCM_STAR_NO_TAG"
+
+    # Full config enables CRYPTO_CONFIG so that PSA_WANT config symbols are evaluated
+    scripts/config.py full
+
+    # Disable CCM_STAR_NO_TAG, which is the target of this test, as well as all
+    # other components that enable MBEDTLS_PSA_BUILTIN_CIPHER internal symbol.
+    # This basically disables all unauthenticated ciphers on the PSA side, while
+    # keeping AEADs enabled.
+    #
+    # Note: PSA_WANT_ALG_CCM is enabled, but it does not cause
+    # PSA_WANT_ALG_CCM_STAR_NO_TAG to be re-enabled.
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CCM_STAR_NO_TAG
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_STREAM_CIPHER
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CTR
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CFB
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_OFB
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_ECB_NO_PADDING
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_NO_PADDING
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_PKCS7
+
+    make
+
+    # Ensure MBEDTLS_PSA_BUILTIN_CIPHER was not enabled
+    not grep mbedtls_psa_cipher library/psa_crypto_cipher.o
+
+    msg "test: full no PSA_WANT_ALG_CCM_STAR_NO_TAG"
+    make test
+}
+
+component_test_full_no_bignum () {
+    msg "build: full minus bignum"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_BIGNUM_C
+    # Direct dependencies of bignum
+    scripts/config.py unset MBEDTLS_ECP_C
+    scripts/config.py unset MBEDTLS_RSA_C
+    scripts/config.py unset MBEDTLS_DHM_C
+    # Direct dependencies of ECP
+    scripts/config.py unset MBEDTLS_ECDH_C
+    scripts/config.py unset MBEDTLS_ECDSA_C
+    scripts/config.py unset MBEDTLS_ECJPAKE_C
+    scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
+    # Disable what auto-enables ECP_LIGHT
+    scripts/config.py unset MBEDTLS_PK_PARSE_EC_EXTENDED
+    scripts/config.py unset MBEDTLS_PK_PARSE_EC_COMPRESSED
+    # Indirect dependencies of ECP
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+    # Direct dependencies of DHM
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+    # Direct dependencies of RSA
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+    scripts/config.py unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
+    # PK and its dependencies
+    scripts/config.py unset MBEDTLS_PK_C
+    scripts/config.py unset MBEDTLS_PK_PARSE_C
+    scripts/config.py unset MBEDTLS_PK_WRITE_C
+    scripts/config.py unset MBEDTLS_X509_USE_C
+    scripts/config.py unset MBEDTLS_X509_CRT_PARSE_C
+    scripts/config.py unset MBEDTLS_X509_CRL_PARSE_C
+    scripts/config.py unset MBEDTLS_X509_CSR_PARSE_C
+    scripts/config.py unset MBEDTLS_X509_CREATE_C
+    scripts/config.py unset MBEDTLS_X509_CRT_WRITE_C
+    scripts/config.py unset MBEDTLS_X509_CSR_WRITE_C
+    scripts/config.py unset MBEDTLS_PKCS7_C
+    scripts/config.py unset MBEDTLS_SSL_SERVER_NAME_INDICATION
+    scripts/config.py unset MBEDTLS_SSL_ASYNC_PRIVATE
+    scripts/config.py unset MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+
+    make
+
+    msg "test: full minus bignum"
+    make test
+}
+
+component_build_dhm_alt () {
+    msg "build: MBEDTLS_DHM_ALT" # ~30s
+    scripts/config.py full
+    scripts/config.py set MBEDTLS_DHM_ALT
+    # debug.c currently references mbedtls_dhm_context fields directly.
+    scripts/config.py unset MBEDTLS_DEBUG_C
+    # We can only compile, not link, since we don't have any implementations
+    # suitable for testing with the dummy alt headers.
+    make CFLAGS='-Werror -Wall -Wextra -I../tests/include/alt-dummy' lib
+}
+
+component_test_everest () {
+    msg "build: Everest ECDH context (ASan build)" # ~ 6 min
+    scripts/config.py set MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED
+    CC=clang cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: Everest ECDH context - main suites (inc. selftests) (ASan build)" # ~ 50s
+    make test
+
+    msg "test: metatests (clang, ASan)"
+    tests/scripts/run-metatests.sh any asan poison
+
+    msg "test: Everest ECDH context - ECDH-related part of ssl-opt.sh (ASan build)" # ~ 5s
+    tests/ssl-opt.sh -f ECDH
+
+    msg "test: Everest ECDH context - compat.sh with some ECDH ciphersuites (ASan build)" # ~ 3 min
+    # Exclude some symmetric ciphers that are redundant here to gain time.
+    tests/compat.sh -f ECDH -V NO -e 'ARIA\|CAMELLIA\|CHACHA'
+}
+
+component_test_everest_curve25519_only () {
+    msg "build: Everest ECDH context, only Curve25519" # ~ 6 min
+    scripts/config.py set MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED
+    scripts/config.py unset MBEDTLS_ECDSA_C
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+    scripts/config.py unset MBEDTLS_ECJPAKE_C
+    # Disable all curves
+    scripts/config.py unset-all "MBEDTLS_ECP_DP_[0-9A-Z_a-z]*_ENABLED"
+    scripts/config.py set MBEDTLS_ECP_DP_CURVE25519_ENABLED
+
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
+
+    msg "test: Everest ECDH context, only Curve25519" # ~ 50s
+    make test
+}
+
+component_test_psa_collect_statuses () {
+  msg "build+test: psa_collect_statuses" # ~30s
+  scripts/config.py full
+  tests/scripts/psa_collect_statuses.py
+  # Check that psa_crypto_init() succeeded at least once
+  grep -q '^0:psa_crypto_init:' tests/statuses.log
+  rm -f tests/statuses.log
+}
+
+# Check that the specified libraries exist and are empty.
+are_empty_libraries () {
+  nm "$@" >/dev/null 2>/dev/null
+  ! nm "$@" 2>/dev/null | grep -v ':$' | grep .
+}
+
+component_build_crypto_default () {
+  msg "build: make, crypto only"
+  scripts/config.py crypto
+  make CFLAGS='-O1 -Werror'
+  are_empty_libraries library/libmbedx509.* library/libmbedtls.*
+}
+
+component_build_crypto_full () {
+  msg "build: make, crypto only, full config"
+  scripts/config.py crypto_full
+  make CFLAGS='-O1 -Werror'
+  are_empty_libraries library/libmbedx509.* library/libmbedtls.*
+}
+
+component_test_crypto_for_psa_service () {
+  msg "build: make, config for PSA crypto service"
+  scripts/config.py crypto
+  scripts/config.py set MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
+  # Disable things that are not needed for just cryptography, to
+  # reach a configuration that would be typical for a PSA cryptography
+  # service providing all implemented PSA algorithms.
+  # System stuff
+  scripts/config.py unset MBEDTLS_ERROR_C
+  scripts/config.py unset MBEDTLS_TIMING_C
+  scripts/config.py unset MBEDTLS_VERSION_FEATURES
+  # Crypto stuff with no PSA interface
+  scripts/config.py unset MBEDTLS_BASE64_C
+  # Keep MBEDTLS_CIPHER_C because psa_crypto_cipher, CCM and GCM need it.
+  scripts/config.py unset MBEDTLS_HKDF_C # PSA's HKDF is independent
+  # Keep MBEDTLS_MD_C because deterministic ECDSA needs it for HMAC_DRBG.
+  scripts/config.py unset MBEDTLS_NIST_KW_C
+  scripts/config.py unset MBEDTLS_PEM_PARSE_C
+  scripts/config.py unset MBEDTLS_PEM_WRITE_C
+  scripts/config.py unset MBEDTLS_PKCS12_C
+  scripts/config.py unset MBEDTLS_PKCS5_C
+  # MBEDTLS_PK_PARSE_C and MBEDTLS_PK_WRITE_C are actually currently needed
+  # in PSA code to work with RSA keys. We don't require users to set those:
+  # they will be reenabled in build_info.h.
+  scripts/config.py unset MBEDTLS_PK_C
+  scripts/config.py unset MBEDTLS_PK_PARSE_C
+  scripts/config.py unset MBEDTLS_PK_WRITE_C
+  make CFLAGS='-O1 -Werror' all test
+  are_empty_libraries library/libmbedx509.* library/libmbedtls.*
+}
+
+component_build_crypto_baremetal () {
+  msg "build: make, crypto only, baremetal config"
+  scripts/config.py crypto_baremetal
+  make CFLAGS="-O1 -Werror -I$PWD/tests/include/baremetal-override/"
+  are_empty_libraries library/libmbedx509.* library/libmbedtls.*
+}
+
+support_build_crypto_baremetal () {
+    support_build_baremetal "$@"
+}
+
+# depends.py family of tests
+component_test_depends_py_cipher_id () {
+    msg "test/build: depends.py cipher_id (gcc)"
+    tests/scripts/depends.py cipher_id --unset-use-psa
+}
+
+component_test_depends_py_cipher_chaining () {
+    msg "test/build: depends.py cipher_chaining (gcc)"
+    tests/scripts/depends.py cipher_chaining --unset-use-psa
+}
+
+component_test_depends_py_cipher_padding () {
+    msg "test/build: depends.py cipher_padding (gcc)"
+    tests/scripts/depends.py cipher_padding --unset-use-psa
+}
+
+component_test_depends_py_curves () {
+    msg "test/build: depends.py curves (gcc)"
+    tests/scripts/depends.py curves --unset-use-psa
+}
+
+component_test_depends_py_hashes () {
+    msg "test/build: depends.py hashes (gcc)"
+    tests/scripts/depends.py hashes --unset-use-psa
+}
+
+component_test_depends_py_pkalgs () {
+    msg "test/build: depends.py pkalgs (gcc)"
+    tests/scripts/depends.py pkalgs --unset-use-psa
+}
+
+# PSA equivalents of the depends.py tests
+component_test_depends_py_cipher_id_psa () {
+    msg "test/build: depends.py cipher_id (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
+    tests/scripts/depends.py cipher_id
+}
+
+component_test_depends_py_cipher_chaining_psa () {
+    msg "test/build: depends.py cipher_chaining (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
+    tests/scripts/depends.py cipher_chaining
+}
+
+component_test_depends_py_cipher_padding_psa () {
+    msg "test/build: depends.py cipher_padding (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
+    tests/scripts/depends.py cipher_padding
+}
+
+component_test_depends_py_curves_psa () {
+    msg "test/build: depends.py curves (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
+    tests/scripts/depends.py curves
+}
+
+component_test_depends_py_hashes_psa () {
+    msg "test/build: depends.py hashes (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
+    tests/scripts/depends.py hashes
+}
+
+component_test_depends_py_pkalgs_psa () {
+    msg "test/build: depends.py pkalgs (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
+    tests/scripts/depends.py pkalgs
+}
+
+component_test_psa_crypto_config_ffdh_2048_only () {
+    msg "build: full config - only DH 2048"
+
+    scripts/config.py full
+
+    # Disable all DH groups other than 2048.
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_DH_RFC7919_3072
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_DH_RFC7919_4096
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_DH_RFC7919_6144
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_DH_RFC7919_8192
+
+    make CFLAGS="$ASAN_CFLAGS -Werror" LDFLAGS="$ASAN_CFLAGS"
+
+    msg "test: full config - only DH 2048"
+    make test
+
+    msg "ssl-opt: full config - only DH 2048"
+    tests/ssl-opt.sh -f "ffdh"
+}
+
+component_build_no_pk_rsa_alt_support () {
+    msg "build: !MBEDTLS_PK_RSA_ALT_SUPPORT" # ~30s
+
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_PK_RSA_ALT_SUPPORT
+    scripts/config.py set MBEDTLS_RSA_C
+    scripts/config.py set MBEDTLS_X509_CRT_WRITE_C
+
+    # Only compile - this is primarily to test for compile issues
+    make CFLAGS='-Werror -Wall -Wextra -I../tests/include/alt-dummy'
+}
+
+component_build_module_alt () {
+    msg "build: MBEDTLS_XXX_ALT" # ~30s
+    scripts/config.py full
+
+    # Disable options that are incompatible with some ALT implementations:
+    # aesni.c and padlock.c reference mbedtls_aes_context fields directly.
+    scripts/config.py unset MBEDTLS_AESNI_C
+    scripts/config.py unset MBEDTLS_PADLOCK_C
+    scripts/config.py unset MBEDTLS_AESCE_C
+    # MBEDTLS_ECP_RESTARTABLE is documented as incompatible.
+    scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
+    # You can only have one threading implementation: alt or pthread, not both.
+    scripts/config.py unset MBEDTLS_THREADING_PTHREAD
+    # The SpecifiedECDomain parsing code accesses mbedtls_ecp_group fields
+    # directly and assumes the implementation works with partial groups.
+    scripts/config.py unset MBEDTLS_PK_PARSE_EC_EXTENDED
+    # MBEDTLS_SHA256_*ALT can't be used with MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*
+    scripts/config.py unset MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
+    scripts/config.py unset MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
+    # MBEDTLS_SHA512_*ALT can't be used with MBEDTLS_SHA512_USE_A64_CRYPTO_*
+    scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
+    scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
+
+    # Enable all MBEDTLS_XXX_ALT for whole modules. Do not enable
+    # MBEDTLS_XXX_YYY_ALT which are for single functions.
+    scripts/config.py set-all 'MBEDTLS_([A-Z0-9]*|NIST_KW)_ALT'
+    scripts/config.py unset MBEDTLS_DHM_ALT #incompatible with MBEDTLS_DEBUG_C
+
+    # We can only compile, not link, since we don't have any implementations
+    # suitable for testing with the dummy alt headers.
+    make CFLAGS='-Werror -Wall -Wextra -I../tests/include/alt-dummy' lib
+}
+
+component_test_psa_crypto_config_accel_ecdsa () {
+    msg "build: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated ECDSA"
+
+    # Algorithms and key types to accelerate
+    loc_accel_list="ALG_ECDSA ALG_DETERMINISTIC_ECDSA \
+                    $(helper_get_psa_key_type_list "ECC") \
+                    $(helper_get_psa_curve_list)"
+
+    # Configure
+    # ---------
+
+    # Start from default config (no USE_PSA) + TLS 1.3
+    helper_libtestdriver1_adjust_config "default"
+
+    # Disable the module that's accelerated
+    scripts/config.py unset MBEDTLS_ECDSA_C
+
+    # Disable things that depend on it
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+
+    # Build
+    # -----
+
+    # These hashes are needed for some ECDSA signature tests.
+    loc_extra_list="ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
+                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
+
+    helper_libtestdriver1_make_drivers "$loc_accel_list" "$loc_extra_list"
+
+    helper_libtestdriver1_make_main "$loc_accel_list"
+
+    # Make sure this was not re-enabled by accident (additive config)
+    not grep mbedtls_ecdsa_ library/ecdsa.o
+
+    # Run the tests
+    # -------------
+
+    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated ECDSA"
+    make test
+}
+
+component_test_psa_crypto_config_accel_ecdh () {
+    msg "build: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated ECDH"
+
+    # Algorithms and key types to accelerate
+    loc_accel_list="ALG_ECDH \
+                    $(helper_get_psa_key_type_list "ECC") \
+                    $(helper_get_psa_curve_list)"
+
+    # Configure
+    # ---------
+
+    # Start from default config (no USE_PSA)
+    helper_libtestdriver1_adjust_config "default"
+
+    # Disable the module that's accelerated
+    scripts/config.py unset MBEDTLS_ECDH_C
+
+    # Disable things that depend on it
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
+
+    # Build
+    # -----
+
+    helper_libtestdriver1_make_drivers "$loc_accel_list"
+
+    helper_libtestdriver1_make_main "$loc_accel_list"
+
+    # Make sure this was not re-enabled by accident (additive config)
+    not grep mbedtls_ecdh_ library/ecdh.o
+
+    # Run the tests
+    # -------------
+
+    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated ECDH"
+    make test
+}
+
+component_test_psa_crypto_config_accel_ffdh () {
+    msg "build: full with accelerated FFDH"
+
+    # Algorithms and key types to accelerate
+    loc_accel_list="ALG_FFDH \
+                    $(helper_get_psa_key_type_list "DH") \
+                    $(helper_get_psa_dh_group_list)"
+
+    # Configure
+    # ---------
+
+    # start with full (USE_PSA and TLS 1.3)
+    helper_libtestdriver1_adjust_config "full"
+
+    # Disable the module that's accelerated
+    scripts/config.py unset MBEDTLS_DHM_C
+
+    # Disable things that depend on it
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+
+    # Build
+    # -----
+
+    helper_libtestdriver1_make_drivers "$loc_accel_list"
+
+    helper_libtestdriver1_make_main "$loc_accel_list"
+
+    # Make sure this was not re-enabled by accident (additive config)
+    not grep mbedtls_dhm_ library/dhm.o
+
+    # Run the tests
+    # -------------
+
+    msg "test: full with accelerated FFDH"
+    make test
+
+    msg "ssl-opt: full with accelerated FFDH alg"
+    tests/ssl-opt.sh -f "ffdh"
+}
+
+component_test_psa_crypto_config_reference_ffdh () {
+    msg "build: full with non-accelerated FFDH"
+
+    # Start with full (USE_PSA and TLS 1.3)
+    helper_libtestdriver1_adjust_config "full"
+
+    # Disable things that are not supported
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+    make
+
+    msg "test suites: full with non-accelerated FFDH alg"
+    make test
+
+    msg "ssl-opt: full with non-accelerated FFDH alg"
+    tests/ssl-opt.sh -f "ffdh"
+}
+
+component_test_psa_crypto_config_accel_pake () {
+    msg "build: full with accelerated PAKE"
+
+    loc_accel_list="ALG_JPAKE \
+                    $(helper_get_psa_key_type_list "ECC") \
+                    $(helper_get_psa_curve_list)"
+
+    # Configure
+    # ---------
+
+    helper_libtestdriver1_adjust_config "full"
+
+    # Make built-in fallback not available
+    scripts/config.py unset MBEDTLS_ECJPAKE_C
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+
+    # Build
+    # -----
+
+    helper_libtestdriver1_make_drivers "$loc_accel_list"
+
+    helper_libtestdriver1_make_main "$loc_accel_list"
+
+    # Make sure this was not re-enabled by accident (additive config)
+    not grep mbedtls_ecjpake_init library/ecjpake.o
+
+    # Run the tests
+    # -------------
+
+    msg "test: full with accelerated PAKE"
+    make test
+}
+
+component_test_psa_crypto_config_accel_ecc_some_key_types () {
+    msg "build: full with accelerated EC algs and some key types"
+
+    # Algorithms and key types to accelerate
+    # For key types, use an explicitly list to omit GENERATE (and DERIVE)
+    loc_accel_list="ALG_ECDSA ALG_DETERMINISTIC_ECDSA \
+                    ALG_ECDH \
+                    ALG_JPAKE \
+                    KEY_TYPE_ECC_PUBLIC_KEY \
+                    KEY_TYPE_ECC_KEY_PAIR_BASIC \
+                    KEY_TYPE_ECC_KEY_PAIR_IMPORT \
+                    KEY_TYPE_ECC_KEY_PAIR_EXPORT \
+                    $(helper_get_psa_curve_list)"
+
+    # Configure
+    # ---------
+
+    # start with config full for maximum coverage (also enables USE_PSA)
+    helper_libtestdriver1_adjust_config "full"
+
+    # Disable modules that are accelerated - some will be re-enabled
+    scripts/config.py unset MBEDTLS_ECDSA_C
+    scripts/config.py unset MBEDTLS_ECDH_C
+    scripts/config.py unset MBEDTLS_ECJPAKE_C
+    scripts/config.py unset MBEDTLS_ECP_C
+
+    # Disable all curves - those that aren't accelerated should be re-enabled
+    helper_disable_builtin_curves
+
+    # Restartable feature is not yet supported by PSA. Once it will in
+    # the future, the following line could be removed (see issues
+    # 6061, 6332 and following ones)
+    scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
+
+    # this is not supported by the driver API yet
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE
+
+    # Build
+    # -----
+
+    # These hashes are needed for some ECDSA signature tests.
+    loc_extra_list="ALG_SHA_1 ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
+                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
+    helper_libtestdriver1_make_drivers "$loc_accel_list" "$loc_extra_list"
+
+    helper_libtestdriver1_make_main "$loc_accel_list"
+
+    # ECP should be re-enabled but not the others
+    not grep mbedtls_ecdh_ library/ecdh.o
+    not grep mbedtls_ecdsa library/ecdsa.o
+    not grep mbedtls_ecjpake  library/ecjpake.o
+    grep mbedtls_ecp library/ecp.o
+
+    # Run the tests
+    # -------------
+
+    msg "test suites: full with accelerated EC algs and some key types"
+    make test
+}
+
+# Run tests with only (non-)Weierstrass accelerated
+# Common code used in:
+# - component_test_psa_crypto_config_accel_ecc_weierstrass_curves
+# - component_test_psa_crypto_config_accel_ecc_non_weierstrass_curves
+common_test_psa_crypto_config_accel_ecc_some_curves () {
+    weierstrass=$1
+    if [ $weierstrass -eq 1 ]; then
+        desc="Weierstrass"
+    else
+        desc="non-Weierstrass"
+    fi
+
+    msg "build: crypto_full minus PK with accelerated EC algs and $desc curves"
+
+    # Note: Curves are handled in a special way by the libtestdriver machinery,
+    # so we only want to include them in the accel list when building the main
+    # libraries, hence the use of a separate variable.
+    # Note: the following loop is a modified version of
+    # helper_get_psa_curve_list that only keeps Weierstrass families.
+    loc_weierstrass_list=""
+    loc_non_weierstrass_list=""
+    for item in $(sed -n 's/^#define PSA_WANT_\(ECC_[0-9A-Z_a-z]*\).*/\1/p' <"$CRYPTO_CONFIG_H"); do
+        case $item in
+            ECC_BRAINPOOL*|ECC_SECP*)
+                loc_weierstrass_list="$loc_weierstrass_list $item"
+                ;;
+            *)
+                loc_non_weierstrass_list="$loc_non_weierstrass_list $item"
+                ;;
+        esac
+    done
+    if [ $weierstrass -eq 1 ]; then
+        loc_curve_list=$loc_weierstrass_list
+    else
+        loc_curve_list=$loc_non_weierstrass_list
+    fi
+
+    # Algorithms and key types to accelerate
+    loc_accel_list="ALG_ECDSA ALG_DETERMINISTIC_ECDSA \
+                    ALG_ECDH \
+                    ALG_JPAKE \
+                    $(helper_get_psa_key_type_list "ECC") \
+                    $loc_curve_list"
+
+    # Configure
+    # ---------
+
+    # Start with config crypto_full and remove PK_C:
+    # that's what's supported now, see docs/driver-only-builds.md.
+    helper_libtestdriver1_adjust_config "crypto_full"
+    scripts/config.py unset MBEDTLS_PK_C
+    scripts/config.py unset MBEDTLS_PK_PARSE_C
+    scripts/config.py unset MBEDTLS_PK_WRITE_C
+
+    # Disable modules that are accelerated - some will be re-enabled
+    scripts/config.py unset MBEDTLS_ECDSA_C
+    scripts/config.py unset MBEDTLS_ECDH_C
+    scripts/config.py unset MBEDTLS_ECJPAKE_C
+    scripts/config.py unset MBEDTLS_ECP_C
+
+    # Disable all curves - those that aren't accelerated should be re-enabled
+    helper_disable_builtin_curves
+
+    # Restartable feature is not yet supported by PSA. Once it will in
+    # the future, the following line could be removed (see issues
+    # 6061, 6332 and following ones)
+    scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
+
+    # this is not supported by the driver API yet
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE
+
+    # Build
+    # -----
+
+    # These hashes are needed for some ECDSA signature tests.
+    loc_extra_list="ALG_SHA_1 ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
+                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
+    helper_libtestdriver1_make_drivers "$loc_accel_list" "$loc_extra_list"
+
+    helper_libtestdriver1_make_main "$loc_accel_list"
+
+    # We expect ECDH to be re-enabled for the missing curves
+    grep mbedtls_ecdh_ library/ecdh.o
+    # We expect ECP to be re-enabled, however the parts specific to the
+    # families of curves that are accelerated should be ommited.
+    # - functions with mxz in the name are specific to Montgomery curves
+    # - ecp_muladd is specific to Weierstrass curves
+    ##nm library/ecp.o | tee ecp.syms
+    if [ $weierstrass -eq 1 ]; then
+        not grep mbedtls_ecp_muladd library/ecp.o
+        grep mxz library/ecp.o
+    else
+        grep mbedtls_ecp_muladd library/ecp.o
+        not grep mxz library/ecp.o
+    fi
+    # We expect ECDSA and ECJPAKE to be re-enabled only when
+    # Weierstrass curves are not accelerated
+    if [ $weierstrass -eq 1 ]; then
+        not grep mbedtls_ecdsa library/ecdsa.o
+        not grep mbedtls_ecjpake  library/ecjpake.o
+    else
+        grep mbedtls_ecdsa library/ecdsa.o
+        grep mbedtls_ecjpake  library/ecjpake.o
+    fi
+
+    # Run the tests
+    # -------------
+
+    msg "test suites: crypto_full minus PK with accelerated EC algs and $desc curves"
+    make test
+}
+
+component_test_psa_crypto_config_accel_ecc_weierstrass_curves () {
+    common_test_psa_crypto_config_accel_ecc_some_curves 1
+}
+
+component_test_psa_crypto_config_accel_ecc_non_weierstrass_curves () {
+    common_test_psa_crypto_config_accel_ecc_some_curves 0
+}
+
+# Auxiliary function to build config for all EC based algorithms (EC-JPAKE,
+# ECDH, ECDSA) with and without drivers.
+# The input parameter is a boolean value which indicates:
+# - 0 keep built-in EC algs,
+# - 1 exclude built-in EC algs (driver only).
+#
+# This is used by the two following components to ensure they always use the
+# same config, except for the use of driver or built-in EC algorithms:
+# - component_test_psa_crypto_config_accel_ecc_ecp_light_only;
+# - component_test_psa_crypto_config_reference_ecc_ecp_light_only.
+# This supports comparing their test coverage with analyze_outcomes.py.
+config_psa_crypto_config_ecp_light_only () {
+    driver_only="$1"
+    # start with config full for maximum coverage (also enables USE_PSA)
+    helper_libtestdriver1_adjust_config "full"
+    if [ "$driver_only" -eq 1 ]; then
+        # Disable modules that are accelerated
+        scripts/config.py unset MBEDTLS_ECDSA_C
+        scripts/config.py unset MBEDTLS_ECDH_C
+        scripts/config.py unset MBEDTLS_ECJPAKE_C
+        scripts/config.py unset MBEDTLS_ECP_C
+    fi
+
+    # Restartable feature is not yet supported by PSA. Once it will in
+    # the future, the following line could be removed (see issues
+    # 6061, 6332 and following ones)
+    scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
+}
+
+# Keep in sync with component_test_psa_crypto_config_reference_ecc_ecp_light_only
+component_test_psa_crypto_config_accel_ecc_ecp_light_only () {
+    msg "build: full with accelerated EC algs"
+
+    # Algorithms and key types to accelerate
+    loc_accel_list="ALG_ECDSA ALG_DETERMINISTIC_ECDSA \
+                    ALG_ECDH \
+                    ALG_JPAKE \
+                    $(helper_get_psa_key_type_list "ECC") \
+                    $(helper_get_psa_curve_list)"
+
+    # Configure
+    # ---------
+
+    # Use the same config as reference, only without built-in EC algs
+    config_psa_crypto_config_ecp_light_only 1
+
+    # Do not disable builtin curves because that support is required for:
+    # - MBEDTLS_PK_PARSE_EC_EXTENDED
+    # - MBEDTLS_PK_PARSE_EC_COMPRESSED
+
+    # Build
+    # -----
+
+    # These hashes are needed for some ECDSA signature tests.
+    loc_extra_list="ALG_SHA_1 ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
+                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
+    helper_libtestdriver1_make_drivers "$loc_accel_list" "$loc_extra_list"
+
+    helper_libtestdriver1_make_main "$loc_accel_list"
+
+    # Make sure any built-in EC alg was not re-enabled by accident (additive config)
+    not grep mbedtls_ecdsa_ library/ecdsa.o
+    not grep mbedtls_ecdh_ library/ecdh.o
+    not grep mbedtls_ecjpake_ library/ecjpake.o
+    not grep mbedtls_ecp_mul library/ecp.o
+
+    # Run the tests
+    # -------------
+
+    msg "test suites: full with accelerated EC algs"
+    make test
+
+    msg "ssl-opt: full with accelerated EC algs"
+    tests/ssl-opt.sh
+}
+
+# Keep in sync with component_test_psa_crypto_config_accel_ecc_ecp_light_only
+component_test_psa_crypto_config_reference_ecc_ecp_light_only () {
+    msg "build: MBEDTLS_PSA_CRYPTO_CONFIG with non-accelerated EC algs"
+
+    config_psa_crypto_config_ecp_light_only 0
+
+    make
+
+    msg "test suites: full with non-accelerated EC algs"
+    make test
+
+    msg "ssl-opt: full with non-accelerated EC algs"
+    tests/ssl-opt.sh
+}
+
+# This helper function is used by:
+# - component_test_psa_crypto_config_accel_ecc_no_ecp_at_all()
+# - component_test_psa_crypto_config_reference_ecc_no_ecp_at_all()
+# to ensure that both tests use the same underlying configuration when testing
+# driver's coverage with analyze_outcomes.py.
+#
+# This functions accepts 1 boolean parameter as follows:
+# - 1: building with accelerated EC algorithms (ECDSA, ECDH, ECJPAKE), therefore
+#      excluding their built-in implementation as well as ECP_C & ECP_LIGHT
+# - 0: include built-in implementation of EC algorithms.
+#
+# PK_C and RSA_C are always disabled to ensure there is no remaining dependency
+# on the ECP module.
+config_psa_crypto_no_ecp_at_all () {
+    driver_only="$1"
+    # start with full config for maximum coverage (also enables USE_PSA)
+    helper_libtestdriver1_adjust_config "full"
+
+    if [ "$driver_only" -eq 1 ]; then
+        # Disable modules that are accelerated
+        scripts/config.py unset MBEDTLS_ECDSA_C
+        scripts/config.py unset MBEDTLS_ECDH_C
+        scripts/config.py unset MBEDTLS_ECJPAKE_C
+        # Disable ECP module (entirely)
+        scripts/config.py unset MBEDTLS_ECP_C
+    fi
+
+    # Disable all the features that auto-enable ECP_LIGHT (see build_info.h)
+    scripts/config.py unset MBEDTLS_PK_PARSE_EC_EXTENDED
+    scripts/config.py unset MBEDTLS_PK_PARSE_EC_COMPRESSED
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE
+
+    # Restartable feature is not yet supported by PSA. Once it will in
+    # the future, the following line could be removed (see issues
+    # 6061, 6332 and following ones)
+    scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
+}
+
+# Build and test a configuration where driver accelerates all EC algs while
+# all support and dependencies from ECP and ECP_LIGHT are removed on the library
+# side.
+#
+# Keep in sync with component_test_psa_crypto_config_reference_ecc_no_ecp_at_all()
+component_test_psa_crypto_config_accel_ecc_no_ecp_at_all () {
+    msg "build: full + accelerated EC algs - ECP"
+
+    # Algorithms and key types to accelerate
+    loc_accel_list="ALG_ECDSA ALG_DETERMINISTIC_ECDSA \
+                    ALG_ECDH \
+                    ALG_JPAKE \
+                    $(helper_get_psa_key_type_list "ECC") \
+                    $(helper_get_psa_curve_list)"
+
+    # Configure
+    # ---------
+
+    # Set common configurations between library's and driver's builds
+    config_psa_crypto_no_ecp_at_all 1
+    # Disable all the builtin curves. All the required algs are accelerated.
+    helper_disable_builtin_curves
+
+    # Build
+    # -----
+
+    # Things we wanted supported in libtestdriver1, but not accelerated in the main library:
+    # SHA-1 and all SHA-2/3 variants, as they are used by ECDSA deterministic.
+    loc_extra_list="ALG_SHA_1 ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
+                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
+
+    helper_libtestdriver1_make_drivers "$loc_accel_list" "$loc_extra_list"
+
+    helper_libtestdriver1_make_main "$loc_accel_list"
+
+    # Make sure any built-in EC alg was not re-enabled by accident (additive config)
+    not grep mbedtls_ecdsa_ library/ecdsa.o
+    not grep mbedtls_ecdh_ library/ecdh.o
+    not grep mbedtls_ecjpake_ library/ecjpake.o
+    # Also ensure that ECP module was not re-enabled
+    not grep mbedtls_ecp_ library/ecp.o
+
+    # Run the tests
+    # -------------
+
+    msg "test: full + accelerated EC algs - ECP"
+    make test
+
+    msg "ssl-opt: full + accelerated EC algs - ECP"
+    tests/ssl-opt.sh
+}
+
+# Reference function used for driver's coverage analysis in analyze_outcomes.py
+# in conjunction with component_test_psa_crypto_config_accel_ecc_no_ecp_at_all().
+# Keep in sync with its accelerated counterpart.
+component_test_psa_crypto_config_reference_ecc_no_ecp_at_all () {
+    msg "build: full + non accelerated EC algs"
+
+    config_psa_crypto_no_ecp_at_all 0
+
+    make
+
+    msg "test: full + non accelerated EC algs"
+    make test
+
+    msg "ssl-opt: full + non accelerated EC algs"
+    tests/ssl-opt.sh
+}
+
+# This is a common configuration helper used directly from:
+# - common_test_psa_crypto_config_accel_ecc_ffdh_no_bignum
+# - common_test_psa_crypto_config_reference_ecc_ffdh_no_bignum
+# and indirectly from:
+# - component_test_psa_crypto_config_accel_ecc_no_bignum
+#       - accelerate all EC algs, disable RSA and FFDH
+# - component_test_psa_crypto_config_reference_ecc_no_bignum
+#       - this is the reference component of the above
+#       - it still disables RSA and FFDH, but it uses builtin EC algs
+# - component_test_psa_crypto_config_accel_ecc_ffdh_no_bignum
+#       - accelerate all EC and FFDH algs, disable only RSA
+# - component_test_psa_crypto_config_reference_ecc_ffdh_no_bignum
+#       - this is the reference component of the above
+#       - it still disables RSA, but it uses builtin EC and FFDH algs
+#
+# This function accepts 2 parameters:
+# $1: a boolean value which states if we are testing an accelerated scenario
+#     or not.
+# $2: a string value which states which components are tested. Allowed values
+#     are "ECC" or "ECC_DH".
+config_psa_crypto_config_accel_ecc_ffdh_no_bignum () {
+    driver_only="$1"
+    test_target="$2"
+    # start with full config for maximum coverage (also enables USE_PSA)
+    helper_libtestdriver1_adjust_config "full"
+
+    if [ "$driver_only" -eq 1 ]; then
+        # Disable modules that are accelerated
+        scripts/config.py unset MBEDTLS_ECDSA_C
+        scripts/config.py unset MBEDTLS_ECDH_C
+        scripts/config.py unset MBEDTLS_ECJPAKE_C
+        # Disable ECP module (entirely)
+        scripts/config.py unset MBEDTLS_ECP_C
+        # Also disable bignum
+        scripts/config.py unset MBEDTLS_BIGNUM_C
+    fi
+
+    # Disable all the features that auto-enable ECP_LIGHT (see build_info.h)
+    scripts/config.py unset MBEDTLS_PK_PARSE_EC_EXTENDED
+    scripts/config.py unset MBEDTLS_PK_PARSE_EC_COMPRESSED
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE
+
+    # RSA support is intentionally disabled on this test because RSA_C depends
+    # on BIGNUM_C.
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset-all "PSA_WANT_KEY_TYPE_RSA_[0-9A-Z_a-z]*"
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset-all "PSA_WANT_ALG_RSA_[0-9A-Z_a-z]*"
+    scripts/config.py unset MBEDTLS_RSA_C
+    scripts/config.py unset MBEDTLS_PKCS1_V15
+    scripts/config.py unset MBEDTLS_PKCS1_V21
+    scripts/config.py unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
+    # Also disable key exchanges that depend on RSA
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+
+    if [ "$test_target" = "ECC" ]; then
+        # When testing ECC only, we disable FFDH support, both from builtin and
+        # PSA sides, and also disable the key exchanges that depend on DHM.
+        scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_FFDH
+        scripts/config.py -f "$CRYPTO_CONFIG_H" unset-all "PSA_WANT_KEY_TYPE_DH_[0-9A-Z_a-z]*"
+        scripts/config.py -f "$CRYPTO_CONFIG_H" unset-all "PSA_WANT_DH_RFC7919_[0-9]*"
+        scripts/config.py unset MBEDTLS_DHM_C
+        scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+        scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+    else
+        # When testing ECC and DH instead, we disable DHM and depending key
+        # exchanges only in the accelerated build
+        if [ "$driver_only" -eq 1 ]; then
+            scripts/config.py unset MBEDTLS_DHM_C
+            scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+            scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+        fi
+    fi
+
+    # Restartable feature is not yet supported by PSA. Once it will in
+    # the future, the following line could be removed (see issues
+    # 6061, 6332 and following ones)
+    scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
+}
+
+# Common helper used by:
+# - component_test_psa_crypto_config_accel_ecc_no_bignum
+# - component_test_psa_crypto_config_accel_ecc_ffdh_no_bignum
+#
+# The goal is to build and test accelerating either:
+# - ECC only or
+# - both ECC and FFDH
+#
+# It is meant to be used in conjunction with
+# common_test_psa_crypto_config_reference_ecc_ffdh_no_bignum() for drivers
+# coverage analysis in the "analyze_outcomes.py" script.
+common_test_psa_crypto_config_accel_ecc_ffdh_no_bignum () {
+    test_target="$1"
+
+    # This is an internal helper to simplify text message handling
+    if [ "$test_target" = "ECC_DH" ]; then
+        accel_text="ECC/FFDH"
+        removed_text="ECP - DH"
+    else
+        accel_text="ECC"
+        removed_text="ECP"
+    fi
+
+    msg "build: full + accelerated $accel_text algs + USE_PSA - $removed_text - BIGNUM"
+
+    # By default we accelerate all EC keys/algs
+    loc_accel_list="ALG_ECDSA ALG_DETERMINISTIC_ECDSA \
+                    ALG_ECDH \
+                    ALG_JPAKE \
+                    $(helper_get_psa_key_type_list "ECC") \
+                    $(helper_get_psa_curve_list)"
+    # Optionally we can also add DH to the list of accelerated items
+    if [ "$test_target" = "ECC_DH" ]; then
+        loc_accel_list="$loc_accel_list \
+                        ALG_FFDH \
+                        $(helper_get_psa_key_type_list "DH") \
+                        $(helper_get_psa_dh_group_list)"
+    fi
+
+    # Configure
+    # ---------
+
+    # Set common configurations between library's and driver's builds
+    config_psa_crypto_config_accel_ecc_ffdh_no_bignum 1 "$test_target"
+    # Disable all the builtin curves. All the required algs are accelerated.
+    helper_disable_builtin_curves
+
+    # Build
+    # -----
+
+    # Things we wanted supported in libtestdriver1, but not accelerated in the main library:
+    # SHA-1 and all SHA-2/3 variants, as they are used by ECDSA deterministic.
+    loc_extra_list="ALG_SHA_1 ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
+                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
+
+    helper_libtestdriver1_make_drivers "$loc_accel_list" "$loc_extra_list"
+
+    helper_libtestdriver1_make_main "$loc_accel_list"
+
+    # Make sure any built-in EC alg was not re-enabled by accident (additive config)
+    not grep mbedtls_ecdsa_ library/ecdsa.o
+    not grep mbedtls_ecdh_ library/ecdh.o
+    not grep mbedtls_ecjpake_ library/ecjpake.o
+    # Also ensure that ECP, RSA, [DHM] or BIGNUM modules were not re-enabled
+    not grep mbedtls_ecp_ library/ecp.o
+    not grep mbedtls_rsa_ library/rsa.o
+    not grep mbedtls_mpi_ library/bignum.o
+    not grep mbedtls_dhm_ library/dhm.o
+
+    # Run the tests
+    # -------------
+
+    msg "test suites: full + accelerated $accel_text algs + USE_PSA - $removed_text - DHM - BIGNUM"
+
+    make test
+
+    msg "ssl-opt: full + accelerated $accel_text algs + USE_PSA - $removed_text - BIGNUM"
+    tests/ssl-opt.sh
+}
+
+# Common helper used by:
+# - component_test_psa_crypto_config_reference_ecc_no_bignum
+# - component_test_psa_crypto_config_reference_ecc_ffdh_no_bignum
+#
+# The goal is to build and test a reference scenario (i.e. with builtin
+# components) compared to the ones used in
+# common_test_psa_crypto_config_accel_ecc_ffdh_no_bignum() above.
+#
+# It is meant to be used in conjunction with
+# common_test_psa_crypto_config_accel_ecc_ffdh_no_bignum() for drivers'
+# coverage analysis in "analyze_outcomes.py" script.
+common_test_psa_crypto_config_reference_ecc_ffdh_no_bignum () {
+    test_target="$1"
+
+    # This is an internal helper to simplify text message handling
+    if [ "$test_target" = "ECC_DH" ]; then
+        accel_text="ECC/FFDH"
+    else
+        accel_text="ECC"
+    fi
+
+    msg "build: full + non accelerated $accel_text algs + USE_PSA"
+
+    config_psa_crypto_config_accel_ecc_ffdh_no_bignum 0 "$test_target"
+
+    make
+
+    msg "test suites: full + non accelerated EC algs + USE_PSA"
+    make test
+
+    msg "ssl-opt: full + non accelerated $accel_text algs + USE_PSA"
+    tests/ssl-opt.sh
+}
+
+component_test_psa_crypto_config_accel_ecc_no_bignum () {
+    common_test_psa_crypto_config_accel_ecc_ffdh_no_bignum "ECC"
+}
+
+component_test_psa_crypto_config_reference_ecc_no_bignum () {
+    common_test_psa_crypto_config_reference_ecc_ffdh_no_bignum "ECC"
+}
+
+component_test_psa_crypto_config_accel_ecc_ffdh_no_bignum () {
+    common_test_psa_crypto_config_accel_ecc_ffdh_no_bignum "ECC_DH"
+}
+
+component_test_psa_crypto_config_reference_ecc_ffdh_no_bignum () {
+    common_test_psa_crypto_config_reference_ecc_ffdh_no_bignum "ECC_DH"
+}
+
+# Helper for setting common configurations between:
+# - component_test_tfm_config_p256m_driver_accel_ec()
+# - component_test_tfm_config()
+common_tfm_config () {
+    # Enable TF-M config
+    cp configs/config-tfm.h "$CONFIG_H"
+    echo "#undef MBEDTLS_PSA_CRYPTO_CONFIG_FILE" >> "$CONFIG_H"
+    cp configs/ext/crypto_config_profile_medium.h "$CRYPTO_CONFIG_H"
+
+    # Other config adjustment to make the tests pass.
+    # This should probably be adopted upstream.
+    #
+    # - USE_PSA_CRYPTO for PK_HAVE_ECC_KEYS
+    echo "#define MBEDTLS_USE_PSA_CRYPTO" >> "$CONFIG_H"
+
+    # Config adjustment for better test coverage in our environment.
+    # This is not needed just to build and pass tests.
+    #
+    # Enable filesystem I/O for the benefit of PK parse/write tests.
+    echo "#define MBEDTLS_FS_IO" >> "$CONFIG_H"
+}
+
+# Keep this in sync with component_test_tfm_config() as they are both meant
+# to be used in analyze_outcomes.py for driver's coverage analysis.
+component_test_tfm_config_p256m_driver_accel_ec () {
+    msg "build: TF-M config + p256m driver + accel ECDH(E)/ECDSA"
+
+    common_tfm_config
+
+    # Build crypto library
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -I../tests/include/spe" LDFLAGS="$ASAN_CFLAGS"
+
+    # Make sure any built-in EC alg was not re-enabled by accident (additive config)
+    not grep mbedtls_ecdsa_ library/ecdsa.o
+    not grep mbedtls_ecdh_ library/ecdh.o
+    not grep mbedtls_ecjpake_ library/ecjpake.o
+    # Also ensure that ECP, RSA, DHM or BIGNUM modules were not re-enabled
+    not grep mbedtls_ecp_ library/ecp.o
+    not grep mbedtls_rsa_ library/rsa.o
+    not grep mbedtls_dhm_ library/dhm.o
+    not grep mbedtls_mpi_ library/bignum.o
+    # Check that p256m was built
+    grep -q p256_ecdsa_ library/libmbedcrypto.a
+
+    # In "config-tfm.h" we disabled CIPHER_C tweaking TF-M's configuration
+    # files, so we want to ensure that it has not be re-enabled accidentally.
+    not grep mbedtls_cipher library/cipher.o
+
+    # Run the tests
+    msg "test: TF-M config + p256m driver + accel ECDH(E)/ECDSA"
+    make test
+}
+
+# Keep this in sync with component_test_tfm_config_p256m_driver_accel_ec() as
+# they are both meant to be used in analyze_outcomes.py for driver's coverage
+# analysis.
+component_test_tfm_config () {
+    common_tfm_config
+
+    # Disable P256M driver, which is on by default, so that analyze_outcomes
+    # can compare this test with test_tfm_config_p256m_driver_accel_ec
+    echo "#undef MBEDTLS_PSA_P256M_DRIVER_ENABLED" >> "$CONFIG_H"
+
+    msg "build: TF-M config"
+    make CFLAGS='-Werror -Wall -Wextra -I../tests/include/spe' tests
+
+    # Check that p256m was not built
+    not grep p256_ecdsa_ library/libmbedcrypto.a
+
+    # In "config-tfm.h" we disabled CIPHER_C tweaking TF-M's configuration
+    # files, so we want to ensure that it has not be re-enabled accidentally.
+    not grep mbedtls_cipher library/cipher.o
+
+    msg "test: TF-M config"
+    make test
+}
+
+# This is an helper used by:
+# - component_test_psa_ecc_key_pair_no_derive
+# - component_test_psa_ecc_key_pair_no_generate
+# The goal is to test with all PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_yyy symbols
+# enabled, but one. Input arguments are as follows:
+# - $1 is the key type under test, i.e. ECC/RSA/DH
+# - $2 is the key option to be unset (i.e. generate, derive, etc)
+build_and_test_psa_want_key_pair_partial () {
+    key_type=$1
+    unset_option=$2
+    disabled_psa_want="PSA_WANT_KEY_TYPE_${key_type}_KEY_PAIR_${unset_option}"
+
+    msg "build: full - MBEDTLS_USE_PSA_CRYPTO - ${disabled_psa_want}"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+
+    # All the PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_yyy are enabled by default in
+    # crypto_config.h so we just disable the one we don't want.
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset "$disabled_psa_want"
+
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
+
+    msg "test: full - MBEDTLS_USE_PSA_CRYPTO - ${disabled_psa_want}"
+    make test
+}
+
+component_test_psa_ecc_key_pair_no_derive () {
+    build_and_test_psa_want_key_pair_partial "ECC" "DERIVE"
+}
+
+component_test_psa_ecc_key_pair_no_generate () {
+    build_and_test_psa_want_key_pair_partial "ECC" "GENERATE"
+}
+
+config_psa_crypto_accel_rsa () {
+    driver_only=$1
+
+    # Start from crypto_full config (no X.509, no TLS)
+    helper_libtestdriver1_adjust_config "crypto_full"
+
+    if [ "$driver_only" -eq 1 ]; then
+        # Remove RSA support and its dependencies
+        scripts/config.py unset MBEDTLS_RSA_C
+        scripts/config.py unset MBEDTLS_PKCS1_V15
+        scripts/config.py unset MBEDTLS_PKCS1_V21
+
+        # We need PEM parsing in the test library as well to support the import
+        # of PEM encoded RSA keys.
+        scripts/config.py -f "$CONFIG_TEST_DRIVER_H" set MBEDTLS_PEM_PARSE_C
+        scripts/config.py -f "$CONFIG_TEST_DRIVER_H" set MBEDTLS_BASE64_C
+    fi
+}
+
+component_test_psa_crypto_config_accel_rsa_crypto () {
+    msg "build: crypto_full with accelerated RSA"
+
+    loc_accel_list="ALG_RSA_OAEP ALG_RSA_PSS \
+                    ALG_RSA_PKCS1V15_CRYPT ALG_RSA_PKCS1V15_SIGN \
+                    KEY_TYPE_RSA_PUBLIC_KEY \
+                    KEY_TYPE_RSA_KEY_PAIR_BASIC \
+                    KEY_TYPE_RSA_KEY_PAIR_GENERATE \
+                    KEY_TYPE_RSA_KEY_PAIR_IMPORT \
+                    KEY_TYPE_RSA_KEY_PAIR_EXPORT"
+
+    # Configure
+    # ---------
+
+    config_psa_crypto_accel_rsa 1
+
+    # Build
+    # -----
+
+    # These hashes are needed for unit tests.
+    loc_extra_list="ALG_SHA_1 ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
+                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512 ALG_MD5"
+    helper_libtestdriver1_make_drivers "$loc_accel_list" "$loc_extra_list"
+
+    helper_libtestdriver1_make_main "$loc_accel_list"
+
+    # Make sure this was not re-enabled by accident (additive config)
+    not grep mbedtls_rsa library/rsa.o
+
+    # Run the tests
+    # -------------
+
+    msg "test: crypto_full with accelerated RSA"
+    make test
+}
+
+component_test_psa_crypto_config_reference_rsa_crypto () {
+    msg "build: crypto_full with non-accelerated RSA"
+
+    # Configure
+    # ---------
+    config_psa_crypto_accel_rsa 0
+
+    # Build
+    # -----
+    make
+
+    # Run the tests
+    # -------------
+    msg "test: crypto_full with non-accelerated RSA"
+    make test
+}
+
+# This is a temporary test to verify that full RSA support is present even when
+# only one single new symbols (PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) is defined.
+component_test_new_psa_want_key_pair_symbol () {
+    msg "Build: crypto config - MBEDTLS_RSA_C + PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC"
+
+    # Create a temporary output file unless there is already one set
+    if [ "$MBEDTLS_TEST_OUTCOME_FILE" ]; then
+        REMOVE_OUTCOME_ON_EXIT="no"
+    else
+        REMOVE_OUTCOME_ON_EXIT="yes"
+        MBEDTLS_TEST_OUTCOME_FILE="$PWD/out.csv"
+        export MBEDTLS_TEST_OUTCOME_FILE
+    fi
+
+    # Start from crypto configuration
+    scripts/config.py crypto
+
+    # Remove RSA support and its dependencies
+    scripts/config.py unset MBEDTLS_PKCS1_V15
+    scripts/config.py unset MBEDTLS_PKCS1_V21
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+    scripts/config.py unset MBEDTLS_RSA_C
+    scripts/config.py unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
+
+    # Enable PSA support
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
+
+    # Keep only PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC enabled in order to ensure
+    # that proper translations is done in crypto_legacy.h.
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE
+
+    make
+
+    msg "Test: crypto config - MBEDTLS_RSA_C + PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC"
+    make test
+
+    # Parse only 1 relevant line from the outcome file, i.e. a test which is
+    # performing RSA signature.
+    msg "Verify that 'RSA PKCS1 Sign #1 (SHA512, 1536 bits RSA)' is PASS"
+    cat $MBEDTLS_TEST_OUTCOME_FILE | grep 'RSA PKCS1 Sign #1 (SHA512, 1536 bits RSA)' | grep -q "PASS"
+
+    if [ "$REMOVE_OUTCOME_ON_EXIT" == "yes" ]; then
+        rm $MBEDTLS_TEST_OUTCOME_FILE
+    fi
+}
+
+component_test_psa_crypto_config_accel_hash () {
+    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated hash"
+
+    loc_accel_list="ALG_MD5 ALG_RIPEMD160 ALG_SHA_1 \
+                    ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
+                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
+
+    # Configure
+    # ---------
+
+    # Start from default config (no USE_PSA)
+    helper_libtestdriver1_adjust_config "default"
+
+    # Disable the things that are being accelerated
+    scripts/config.py unset MBEDTLS_MD5_C
+    scripts/config.py unset MBEDTLS_RIPEMD160_C
+    scripts/config.py unset MBEDTLS_SHA1_C
+    scripts/config.py unset MBEDTLS_SHA224_C
+    scripts/config.py unset MBEDTLS_SHA256_C
+    scripts/config.py unset MBEDTLS_SHA384_C
+    scripts/config.py unset MBEDTLS_SHA512_C
+    scripts/config.py unset MBEDTLS_SHA3_C
+
+    # Build
+    # -----
+
+    helper_libtestdriver1_make_drivers "$loc_accel_list"
+
+    helper_libtestdriver1_make_main "$loc_accel_list"
+
+    # There's a risk of something getting re-enabled via config_psa.h;
+    # make sure it did not happen. Note: it's OK for MD_C to be enabled.
+    not grep mbedtls_md5 library/md5.o
+    not grep mbedtls_sha1 library/sha1.o
+    not grep mbedtls_sha256 library/sha256.o
+    not grep mbedtls_sha512 library/sha512.o
+    not grep mbedtls_ripemd160 library/ripemd160.o
+
+    # Run the tests
+    # -------------
+
+    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated hash"
+    make test
+}
+
+component_test_psa_crypto_config_accel_hash_keep_builtins () {
+    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated+builtin hash"
+    # This component ensures that all the test cases for
+    # md_psa_dynamic_dispatch with legacy+driver in test_suite_md are run.
+
+    loc_accel_list="ALG_MD5 ALG_RIPEMD160 ALG_SHA_1 \
+                    ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
+                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
+
+    # Start from default config (no USE_PSA)
+    helper_libtestdriver1_adjust_config "default"
+
+    helper_libtestdriver1_make_drivers "$loc_accel_list"
+
+    helper_libtestdriver1_make_main "$loc_accel_list"
+
+    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated+builtin hash"
+    make test
+}
+
+# This should be renamed to test and updated once the accelerator ECDH code is in place and ready to test.
+component_build_psa_accel_alg_ecdh () {
+    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_ECDH without MBEDTLS_ECDH_C"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    scripts/config.py unset MBEDTLS_ECDH_C
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
+    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_ECDH -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
+}
+
+# This should be renamed to test and updated once the accelerator HMAC code is in place and ready to test.
+component_build_psa_accel_alg_hmac () {
+    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_HMAC"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_HMAC -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
+}
+
+# This should be renamed to test and updated once the accelerator HKDF code is in place and ready to test.
+component_build_psa_accel_alg_hkdf () {
+    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_HKDF without MBEDTLS_HKDF_C"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_HKDF_C
+    # Make sure to unset TLS1_3 since it requires HKDF_C and will not build properly without it.
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_HKDF -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
+}
+
+# This should be renamed to test and updated once the accelerator MD5 code is in place and ready to test.
+component_build_psa_accel_alg_md5 () {
+    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_MD5 - other hashes"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RIPEMD160
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_1
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_224
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_256
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_384
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_512
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
+    scripts/config.py unset MBEDTLS_LMS_C
+    scripts/config.py unset MBEDTLS_LMS_PRIVATE
+    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_MD5 -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
+}
+
+# This should be renamed to test and updated once the accelerator RIPEMD160 code is in place and ready to test.
+component_build_psa_accel_alg_ripemd160 () {
+    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_RIPEMD160 - other hashes"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_MD5
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_1
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_224
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_256
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_384
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_512
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
+    scripts/config.py unset MBEDTLS_LMS_C
+    scripts/config.py unset MBEDTLS_LMS_PRIVATE
+    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_RIPEMD160 -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
+}
+
+# This should be renamed to test and updated once the accelerator SHA1 code is in place and ready to test.
+component_build_psa_accel_alg_sha1 () {
+    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_SHA_1 - other hashes"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_MD5
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RIPEMD160
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_224
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_256
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_384
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_512
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
+    scripts/config.py unset MBEDTLS_LMS_C
+    scripts/config.py unset MBEDTLS_LMS_PRIVATE
+    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_SHA_1 -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
+}
+
+# This should be renamed to test and updated once the accelerator SHA224 code is in place and ready to test.
+component_build_psa_accel_alg_sha224 () {
+    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_SHA_224 - other hashes"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_MD5
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RIPEMD160
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_1
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_384
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_512
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
+    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_SHA_224 -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
+}
+
+# This should be renamed to test and updated once the accelerator SHA256 code is in place and ready to test.
+component_build_psa_accel_alg_sha256 () {
+    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_SHA_256 - other hashes"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_MD5
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RIPEMD160
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_1
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_224
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_384
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_512
+    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_SHA_256 -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
+}
+
+# This should be renamed to test and updated once the accelerator SHA384 code is in place and ready to test.
+component_build_psa_accel_alg_sha384 () {
+    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_SHA_384 - other hashes"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_MD5
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RIPEMD160
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_1
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_224
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_256
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
+    scripts/config.py unset MBEDTLS_LMS_C
+    scripts/config.py unset MBEDTLS_LMS_PRIVATE
+    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_SHA_384 -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
+}
+
+# This should be renamed to test and updated once the accelerator SHA512 code is in place and ready to test.
+component_build_psa_accel_alg_sha512 () {
+    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_SHA_512 - other hashes"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_MD5
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RIPEMD160
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_1
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_224
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_256
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_384
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
+    scripts/config.py unset MBEDTLS_LMS_C
+    scripts/config.py unset MBEDTLS_LMS_PRIVATE
+    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_SHA_512 -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
+}
+
+# This should be renamed to test and updated once the accelerator RSA code is in place and ready to test.
+component_build_psa_accel_alg_rsa_pkcs1v15_crypt () {
+    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_RSA_PKCS1V15_CRYPT + PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_ALG_RSA_PKCS1V15_CRYPT 1
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PKCS1V15_SIGN
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_OAEP
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PSS
+    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
+}
+
+# This should be renamed to test and updated once the accelerator RSA code is in place and ready to test.
+component_build_psa_accel_alg_rsa_pkcs1v15_sign () {
+    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_RSA_PKCS1V15_SIGN + PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_ALG_RSA_PKCS1V15_SIGN 1
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_OAEP
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PSS
+    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
+}
+
+# This should be renamed to test and updated once the accelerator RSA code is in place and ready to test.
+component_build_psa_accel_alg_rsa_oaep () {
+    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_RSA_OAEP + PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_ALG_RSA_OAEP 1
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PKCS1V15_SIGN
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PSS
+    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_RSA_OAEP -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
+}
+
+# This should be renamed to test and updated once the accelerator RSA code is in place and ready to test.
+component_build_psa_accel_alg_rsa_pss () {
+    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_RSA_PSS + PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_ALG_RSA_PSS 1
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PKCS1V15_SIGN
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_OAEP
+    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_RSA_PSS -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
+}
+
+# This should be renamed to test and updated once the accelerator RSA code is in place and ready to test.
+component_build_psa_accel_key_type_rsa_key_pair () {
+    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_xxx + PSA_WANT_ALG_RSA_PSS"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_ALG_RSA_PSS 1
+    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC 1
+    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1
+    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1
+    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE 1
+    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
+}
+
+# This should be renamed to test and updated once the accelerator RSA code is in place and ready to test.
+component_build_psa_accel_key_type_rsa_public_key () {
+    msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY + PSA_WANT_ALG_RSA_PSS"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_ALG_RSA_PSS 1
+    scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1
+    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY -I../tests/include" LDFLAGS="$ASAN_CFLAGS"
+}
+
+# Auxiliary function to build config for hashes with and without drivers
+config_psa_crypto_hash_use_psa () {
+    driver_only="$1"
+    # start with config full for maximum coverage (also enables USE_PSA)
+    helper_libtestdriver1_adjust_config "full"
+    if [ "$driver_only" -eq 1 ]; then
+        # disable the built-in implementation of hashes
+        scripts/config.py unset MBEDTLS_MD5_C
+        scripts/config.py unset MBEDTLS_RIPEMD160_C
+        scripts/config.py unset MBEDTLS_SHA1_C
+        scripts/config.py unset MBEDTLS_SHA224_C
+        scripts/config.py unset MBEDTLS_SHA256_C # see external RNG below
+        scripts/config.py unset MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
+        scripts/config.py unset MBEDTLS_SHA384_C
+        scripts/config.py unset MBEDTLS_SHA512_C
+        scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
+        scripts/config.py unset MBEDTLS_SHA3_C
+    fi
+}
+
+# Note that component_test_psa_crypto_config_reference_hash_use_psa
+# is related to this component and both components need to be kept in sync.
+# For details please see comments for component_test_psa_crypto_config_reference_hash_use_psa.
+component_test_psa_crypto_config_accel_hash_use_psa () {
+    msg "test: full with accelerated hashes"
+
+    loc_accel_list="ALG_MD5 ALG_RIPEMD160 ALG_SHA_1 \
+                    ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
+                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
+
+    # Configure
+    # ---------
+
+    config_psa_crypto_hash_use_psa 1
+
+    # Build
+    # -----
+
+    helper_libtestdriver1_make_drivers "$loc_accel_list"
+
+    helper_libtestdriver1_make_main "$loc_accel_list"
+
+    # There's a risk of something getting re-enabled via config_psa.h;
+    # make sure it did not happen. Note: it's OK for MD_C to be enabled.
+    not grep mbedtls_md5 library/md5.o
+    not grep mbedtls_sha1 library/sha1.o
+    not grep mbedtls_sha256 library/sha256.o
+    not grep mbedtls_sha512 library/sha512.o
+    not grep mbedtls_ripemd160 library/ripemd160.o
+
+    # Run the tests
+    # -------------
+
+    msg "test: full with accelerated hashes"
+    make test
+
+    # This is mostly useful so that we can later compare outcome files with
+    # the reference config in analyze_outcomes.py, to check that the
+    # dependency declarations in ssl-opt.sh and in TLS code are correct.
+    msg "test: ssl-opt.sh, full with accelerated hashes"
+    tests/ssl-opt.sh
+
+    # This is to make sure all ciphersuites are exercised, but we don't need
+    # interop testing (besides, we already got some from ssl-opt.sh).
+    msg "test: compat.sh, full with accelerated hashes"
+    tests/compat.sh -p mbedTLS -V YES
+}
+
+# This component provides reference configuration for test_psa_crypto_config_accel_hash_use_psa
+# without accelerated hash. The outcome from both components are used by the analyze_outcomes.py
+# script to find regression in test coverage when accelerated hash is used (tests and ssl-opt).
+# Both components need to be kept in sync.
+component_test_psa_crypto_config_reference_hash_use_psa () {
+    msg "test: full without accelerated hashes"
+
+    config_psa_crypto_hash_use_psa 0
+
+    make
+
+    msg "test: full without accelerated hashes"
+    make test
+
+    msg "test: ssl-opt.sh, full without accelerated hashes"
+    tests/ssl-opt.sh
+}
+
+# Auxiliary function to build config for hashes with and without drivers
+config_psa_crypto_hmac_use_psa () {
+    driver_only="$1"
+    # start with config full for maximum coverage (also enables USE_PSA)
+    helper_libtestdriver1_adjust_config "full"
+
+    if [ "$driver_only" -eq 1 ]; then
+        # Disable MD_C in order to disable the builtin support for HMAC. MD_LIGHT
+        # is still enabled though (for ENTROPY_C among others).
+        scripts/config.py unset MBEDTLS_MD_C
+        # Disable also the builtin hashes since they are supported by the driver
+        # and MD module is able to perform PSA dispathing.
+        scripts/config.py unset-all MBEDTLS_SHA
+        scripts/config.py unset MBEDTLS_MD5_C
+        scripts/config.py unset MBEDTLS_RIPEMD160_C
+    fi
+
+    # Direct dependencies of MD_C. We disable them also in the reference
+    # component to work with the same set of features.
+    scripts/config.py unset MBEDTLS_PKCS7_C
+    scripts/config.py unset MBEDTLS_PKCS5_C
+    scripts/config.py unset MBEDTLS_HMAC_DRBG_C
+    scripts/config.py unset MBEDTLS_HKDF_C
+    # Dependencies of HMAC_DRBG
+    scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_DETERMINISTIC_ECDSA
+}
+
+component_test_psa_crypto_config_accel_hmac () {
+    msg "test: full with accelerated hmac"
+
+    loc_accel_list="ALG_HMAC KEY_TYPE_HMAC \
+                    ALG_MD5 ALG_RIPEMD160 ALG_SHA_1 \
+                    ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
+                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
+
+    # Configure
+    # ---------
+
+    config_psa_crypto_hmac_use_psa 1
+
+    # Build
+    # -----
+
+    helper_libtestdriver1_make_drivers "$loc_accel_list"
+
+    helper_libtestdriver1_make_main "$loc_accel_list"
+
+    # Ensure that built-in support for HMAC is disabled.
+    not grep mbedtls_md_hmac library/md.o
+
+    # Run the tests
+    # -------------
+
+    msg "test: full with accelerated hmac"
+    make test
+}
+
+component_test_psa_crypto_config_reference_hmac () {
+    msg "test: full without accelerated hmac"
+
+    config_psa_crypto_hmac_use_psa 0
+
+    make
+
+    msg "test: full without accelerated hmac"
+    make test
+}
+
+component_test_psa_crypto_config_accel_des () {
+    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated DES"
+
+    # Albeit this components aims at accelerating DES which should only support
+    # CBC and ECB modes, we need to accelerate more than that otherwise DES_C
+    # would automatically be re-enabled by "config_adjust_legacy_from_psa.c"
+    loc_accel_list="ALG_ECB_NO_PADDING ALG_CBC_NO_PADDING ALG_CBC_PKCS7 \
+                    ALG_CTR ALG_CFB ALG_OFB ALG_XTS ALG_CMAC \
+                    KEY_TYPE_DES"
+
+    # Note: we cannot accelerate all ciphers' key types otherwise we would also
+    # have to either disable CCM/GCM or accelerate them, but that's out of scope
+    # of this component. This limitation will be addressed by #8598.
+
+    # Configure
+    # ---------
+
+    # Start from the full config
+    helper_libtestdriver1_adjust_config "full"
+
+    # Disable the things that are being accelerated
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
+    scripts/config.py unset MBEDTLS_CIPHER_PADDING_PKCS7
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_CTR
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_CFB
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_OFB
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_XTS
+    scripts/config.py unset MBEDTLS_DES_C
+    scripts/config.py unset MBEDTLS_CMAC_C
+
+    # Build
+    # -----
+
+    helper_libtestdriver1_make_drivers "$loc_accel_list"
+
+    helper_libtestdriver1_make_main "$loc_accel_list"
+
+    # Make sure this was not re-enabled by accident (additive config)
+    not grep mbedtls_des* library/des.o
+
+    # Run the tests
+    # -------------
+
+    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated DES"
+    make test
+}
+
+component_test_psa_crypto_config_accel_aead () {
+    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated AEAD"
+
+    loc_accel_list="ALG_GCM ALG_CCM ALG_CHACHA20_POLY1305 \
+                    KEY_TYPE_AES KEY_TYPE_CHACHA20 KEY_TYPE_ARIA KEY_TYPE_CAMELLIA"
+
+    # Configure
+    # ---------
+
+    # Start from full config
+    helper_libtestdriver1_adjust_config "full"
+
+    # Disable things that are being accelerated
+    scripts/config.py unset MBEDTLS_GCM_C
+    scripts/config.py unset MBEDTLS_CCM_C
+    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
+
+    # Disable CCM_STAR_NO_TAG because this re-enables CCM_C.
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CCM_STAR_NO_TAG
+
+    # Build
+    # -----
+
+    helper_libtestdriver1_make_drivers "$loc_accel_list"
+
+    helper_libtestdriver1_make_main "$loc_accel_list"
+
+    # Make sure this was not re-enabled by accident (additive config)
+    not grep mbedtls_ccm library/ccm.o
+    not grep mbedtls_gcm library/gcm.o
+    not grep mbedtls_chachapoly library/chachapoly.o
+
+    # Run the tests
+    # -------------
+
+    msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated AEAD"
+    make test
+}
+
+# This is a common configuration function used in:
+# - component_test_psa_crypto_config_accel_cipher_aead_cmac
+# - component_test_psa_crypto_config_reference_cipher_aead_cmac
+common_psa_crypto_config_accel_cipher_aead_cmac () {
+    # Start from the full config
+    helper_libtestdriver1_adjust_config "full"
+
+    scripts/config.py unset MBEDTLS_NIST_KW_C
+}
+
+# The 2 following test components, i.e.
+# - component_test_psa_crypto_config_accel_cipher_aead_cmac
+# - component_test_psa_crypto_config_reference_cipher_aead_cmac
+# are meant to be used together in analyze_outcomes.py script in order to test
+# driver's coverage for ciphers and AEADs.
+component_test_psa_crypto_config_accel_cipher_aead_cmac () {
+    msg "build: full config with accelerated cipher inc. AEAD and CMAC"
+
+    loc_accel_list="ALG_ECB_NO_PADDING ALG_CBC_NO_PADDING ALG_CBC_PKCS7 ALG_CTR ALG_CFB \
+                    ALG_OFB ALG_XTS ALG_STREAM_CIPHER ALG_CCM_STAR_NO_TAG \
+                    ALG_GCM ALG_CCM ALG_CHACHA20_POLY1305 ALG_CMAC \
+                    KEY_TYPE_DES KEY_TYPE_AES KEY_TYPE_ARIA KEY_TYPE_CHACHA20 KEY_TYPE_CAMELLIA"
+
+    # Configure
+    # ---------
+
+    common_psa_crypto_config_accel_cipher_aead_cmac
+
+    # Disable the things that are being accelerated
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
+    scripts/config.py unset MBEDTLS_CIPHER_PADDING_PKCS7
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_CTR
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_CFB
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_OFB
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_XTS
+    scripts/config.py unset MBEDTLS_GCM_C
+    scripts/config.py unset MBEDTLS_CCM_C
+    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
+    scripts/config.py unset MBEDTLS_CMAC_C
+    scripts/config.py unset MBEDTLS_DES_C
+    scripts/config.py unset MBEDTLS_AES_C
+    scripts/config.py unset MBEDTLS_ARIA_C
+    scripts/config.py unset MBEDTLS_CHACHA20_C
+    scripts/config.py unset MBEDTLS_CAMELLIA_C
+
+    # Disable CIPHER_C entirely as all ciphers/AEADs are accelerated and PSA
+    # does not depend on it.
+    scripts/config.py unset MBEDTLS_CIPHER_C
+
+    # Build
+    # -----
+
+    helper_libtestdriver1_make_drivers "$loc_accel_list"
+
+    helper_libtestdriver1_make_main "$loc_accel_list"
+
+    # Make sure this was not re-enabled by accident (additive config)
+    not grep mbedtls_cipher library/cipher.o
+    not grep mbedtls_des library/des.o
+    not grep mbedtls_aes library/aes.o
+    not grep mbedtls_aria library/aria.o
+    not grep mbedtls_camellia library/camellia.o
+    not grep mbedtls_ccm library/ccm.o
+    not grep mbedtls_gcm library/gcm.o
+    not grep mbedtls_chachapoly library/chachapoly.o
+    not grep mbedtls_cmac library/cmac.o
+
+    # Run the tests
+    # -------------
+
+    msg "test: full config with accelerated cipher inc. AEAD and CMAC"
+    make test
+
+    msg "ssl-opt: full config with accelerated cipher inc. AEAD and CMAC"
+    tests/ssl-opt.sh
+
+    msg "compat.sh: full config with accelerated cipher inc. AEAD and CMAC"
+    tests/compat.sh -V NO -p mbedTLS
+}
+
+component_test_psa_crypto_config_reference_cipher_aead_cmac () {
+    msg "build: full config with non-accelerated cipher inc. AEAD and CMAC"
+    common_psa_crypto_config_accel_cipher_aead_cmac
+
+    make
+
+    msg "test: full config with non-accelerated cipher inc. AEAD and CMAC"
+    make test
+
+    msg "ssl-opt: full config with non-accelerated cipher inc. AEAD and CMAC"
+    tests/ssl-opt.sh
+
+    msg "compat.sh: full config with non-accelerated cipher inc. AEAD and CMAC"
+    tests/compat.sh -V NO -p mbedTLS
+}
+
+common_block_cipher_dispatch () {
+    TEST_WITH_DRIVER="$1"
+
+    # Start from the full config
+    helper_libtestdriver1_adjust_config "full"
+
+    if [ "$TEST_WITH_DRIVER" -eq 1 ]; then
+        # Disable key types that are accelerated (there is no legacy equivalent
+        # symbol for ECB)
+        scripts/config.py unset MBEDTLS_AES_C
+        scripts/config.py unset MBEDTLS_ARIA_C
+        scripts/config.py unset MBEDTLS_CAMELLIA_C
+    fi
+
+    # Disable cipher's modes that, when not accelerated, cause
+    # legacy key types to be re-enabled in "config_adjust_legacy_from_psa.h".
+    # Keep this also in the reference component in order to skip the same tests
+    # that were skipped in the accelerated one.
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CTR
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CFB
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_OFB
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_NO_PADDING
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_PKCS7
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CMAC
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CCM_STAR_NO_TAG
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128
+
+    # Disable direct dependency on AES_C
+    scripts/config.py unset MBEDTLS_NIST_KW_C
+
+    # Prevent the cipher module from using deprecated PSA path. The reason is
+    # that otherwise there will be tests relying on "aes_info" (defined in
+    # "cipher_wrap.c") whose functions are not available when AES_C is
+    # not defined. ARIA and Camellia are not a problem in this case because
+    # the PSA path is not tested for these key types.
+    scripts/config.py set MBEDTLS_DEPRECATED_REMOVED
+}
+
+component_test_full_block_cipher_psa_dispatch () {
+    msg "build: full + PSA dispatch in block_cipher"
+
+    loc_accel_list="ALG_ECB_NO_PADDING \
+                    KEY_TYPE_AES KEY_TYPE_ARIA KEY_TYPE_CAMELLIA"
+
+    # Configure
+    # ---------
+
+    common_block_cipher_dispatch 1
+
+    # Build
+    # -----
+
+    helper_libtestdriver1_make_drivers "$loc_accel_list"
+
+    helper_libtestdriver1_make_main "$loc_accel_list"
+
+    # Make sure disabled components were not re-enabled by accident (additive
+    # config)
+    not grep mbedtls_aes_ library/aes.o
+    not grep mbedtls_aria_ library/aria.o
+    not grep mbedtls_camellia_ library/camellia.o
+
+    # Run the tests
+    # -------------
+
+    msg "test: full + PSA dispatch in block_cipher"
+    make test
+}
+
+# This is the reference component of component_test_full_block_cipher_psa_dispatch
+component_test_full_block_cipher_legacy_dispatch () {
+    msg "build: full + legacy dispatch in block_cipher"
+
+    common_block_cipher_dispatch 0
+
+    make
+
+    msg "test: full + legacy dispatch in block_cipher"
+    make test
+}
+
+component_test_aead_chachapoly_disabled () {
+    msg "build: full minus CHACHAPOLY"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CHACHA20_POLY1305
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
+
+    msg "test: full minus CHACHAPOLY"
+    make test
+}
+
+component_test_aead_only_ccm () {
+    msg "build: full minus CHACHAPOLY and GCM"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
+    scripts/config.py unset MBEDTLS_GCM_C
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CHACHA20_POLY1305
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_GCM
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
+
+    msg "test: full minus CHACHAPOLY and GCM"
+    make test
+}
+
+component_test_ccm_aes_sha256 () {
+    msg "build: CCM + AES + SHA256 configuration"
+
+    cp "$CONFIG_TEST_DRIVER_H" "$CONFIG_H"
+    cp configs/crypto-config-ccm-aes-sha256.h "$CRYPTO_CONFIG_H"
+
+    make
+
+    msg "test: CCM + AES + SHA256 configuration"
+    make test
+}
+
+# Test that the given .o file builds with all (valid) combinations of the given options.
+#
+# Syntax: build_test_config_combos FILE VALIDATOR_FUNCTION OPT1 OPT2 ...
+#
+# The validator function is the name of a function to validate the combination of options.
+# It may be "" if all combinations are valid.
+# It receives a string containing a combination of options, as passed to the compiler,
+# e.g. "-DOPT1 -DOPT2 ...". It must return 0 iff the combination is valid, non-zero if invalid.
+build_test_config_combos () {
+    file=$1
+    shift
+    validate_options=$1
+    shift
+    options=("$@")
+
+    # clear all of the options so that they can be overridden on the clang commandline
+    for opt in "${options[@]}"; do
+        ./scripts/config.py unset ${opt}
+    done
+
+    # enter the directory containing the target file & strip the dir from the filename
+    cd $(dirname ${file})
+    file=$(basename ${file})
+
+    # The most common issue is unused variables/functions, so ensure -Wunused is set.
+    warning_flags="-Werror -Wall -Wextra -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow -Wvla -Wformat=2 -Wno-format-nonliteral -Wshadow -Wasm-operand-widths -Wunused"
+
+    # Extract the command generated by the Makefile to build the target file.
+    # This ensures that we have any include paths, macro definitions, etc
+    # that may be applied by make.
+    # Add -fsyntax-only as we only want a syntax check and don't need to generate a file.
+    compile_cmd="clang \$(LOCAL_CFLAGS) ${warning_flags} -fsyntax-only -c"
+
+    makefile=$(TMPDIR=. mktemp)
+    deps=""
+
+    len=${#options[@]}
+    source_file=${file%.o}.c
+
+    targets=0
+    echo 'include Makefile' >${makefile}
+
+    for ((i = 0; i < $((2**${len})); i++)); do
+        # generate each of 2^n combinations of options
+        # each bit of $i is used to determine if options[i] will be set or not
+        target="t"
+        clang_args=""
+        for ((j = 0; j < ${len}; j++)); do
+            if (((i >> j) & 1)); then
+                opt=-D${options[$j]}
+                clang_args="${clang_args} ${opt}"
+                target="${target}${opt}"
+            fi
+        done
+
+        # if combination is not known to be invalid, add it to the makefile
+        if [[ -z $validate_options ]] || $validate_options "${clang_args}"; then
+            cmd="${compile_cmd} ${clang_args}"
+            echo "${target}: ${source_file}; $cmd ${source_file}" >> ${makefile}
+
+            deps="${deps} ${target}"
+            ((++targets))
+        fi
+    done
+
+    echo "build_test_config_combos: ${deps}" >> ${makefile}
+
+    # execute all of the commands via Make (probably in parallel)
+    make -s -f ${makefile} build_test_config_combos
+    echo "$targets targets checked"
+
+    # clean up the temporary makefile
+    rm ${makefile}
+}
+
+validate_aes_config_variations () {
+    if [[ "$1" == *"MBEDTLS_AES_USE_HARDWARE_ONLY"* ]]; then
+        if [[ "$1" == *"MBEDTLS_PADLOCK_C"* ]]; then
+            return 1
+        fi
+        if [[ !(("$HOSTTYPE" == "aarch64" && "$1" != *"MBEDTLS_AESCE_C"*) || \
+                ("$HOSTTYPE" == "x86_64"  && "$1" != *"MBEDTLS_AESNI_C"*)) ]]; then
+            return 1
+        fi
+    fi
+    return 0
+}
+
+component_build_aes_variations () {
+    # 18s - around 90ms per clang invocation on M1 Pro
+    #
+    # aes.o has many #if defined(...) guards that intersect in complex ways.
+    # Test that all the combinations build cleanly.
+
+    MBEDTLS_ROOT_DIR="$PWD"
+    msg "build: aes.o for all combinations of relevant config options"
+
+    build_test_config_combos library/aes.o validate_aes_config_variations \
+        "MBEDTLS_AES_SETKEY_ENC_ALT" "MBEDTLS_AES_DECRYPT_ALT" \
+        "MBEDTLS_AES_ROM_TABLES" "MBEDTLS_AES_ENCRYPT_ALT" "MBEDTLS_AES_SETKEY_DEC_ALT" \
+        "MBEDTLS_AES_FEWER_TABLES" "MBEDTLS_PADLOCK_C" "MBEDTLS_AES_USE_HARDWARE_ONLY" \
+        "MBEDTLS_AESNI_C" "MBEDTLS_AESCE_C" "MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH"
+
+    cd "$MBEDTLS_ROOT_DIR"
+    msg "build: aes.o for all combinations of relevant config options + BLOCK_CIPHER_NO_DECRYPT"
+
+    # MBEDTLS_BLOCK_CIPHER_NO_DECRYPT is incompatible with ECB in PSA, CBC/XTS/NIST_KW/DES,
+    # manually set or unset those configurations to check
+    # MBEDTLS_BLOCK_CIPHER_NO_DECRYPT with various combinations in aes.o.
+    scripts/config.py set MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_XTS
+    scripts/config.py unset MBEDTLS_DES_C
+    scripts/config.py unset MBEDTLS_NIST_KW_C
+    build_test_config_combos library/aes.o validate_aes_config_variations \
+        "MBEDTLS_AES_SETKEY_ENC_ALT" "MBEDTLS_AES_DECRYPT_ALT" \
+        "MBEDTLS_AES_ROM_TABLES" "MBEDTLS_AES_ENCRYPT_ALT" "MBEDTLS_AES_SETKEY_DEC_ALT" \
+        "MBEDTLS_AES_FEWER_TABLES" "MBEDTLS_PADLOCK_C" "MBEDTLS_AES_USE_HARDWARE_ONLY" \
+        "MBEDTLS_AESNI_C" "MBEDTLS_AESCE_C" "MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH"
+}
+
+component_test_sha3_variations () {
+    msg "sha3 loop unroll variations"
+
+    # define minimal config sufficient to test SHA3
+    cat > include/mbedtls/mbedtls_config.h << END
+        #define MBEDTLS_SELF_TEST
+        #define MBEDTLS_SHA3_C
+END
+
+    msg "all loops unrolled"
+    make clean
+    make -C tests test_suite_shax CFLAGS="-DMBEDTLS_SHA3_THETA_UNROLL=1 -DMBEDTLS_SHA3_PI_UNROLL=1 -DMBEDTLS_SHA3_CHI_UNROLL=1 -DMBEDTLS_SHA3_RHO_UNROLL=1"
+    ./tests/test_suite_shax
+
+    msg "all loops rolled up"
+    make clean
+    make -C tests test_suite_shax CFLAGS="-DMBEDTLS_SHA3_THETA_UNROLL=0 -DMBEDTLS_SHA3_PI_UNROLL=0 -DMBEDTLS_SHA3_CHI_UNROLL=0 -DMBEDTLS_SHA3_RHO_UNROLL=0"
+    ./tests/test_suite_shax
+}
+
+# For timebeing, no aarch64 gcc available in CI and no arm64 CI node.
+component_build_aes_aesce_armcc () {
+    msg "Build: AESCE test on arm64 platform without plain C."
+    scripts/config.py baremetal
+
+    # armc[56] don't support SHA-512 intrinsics
+    scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
+
+    # Stop armclang warning about feature detection for A64_CRYPTO.
+    # With this enabled, the library does build correctly under armclang,
+    # but in baremetal builds (as tested here), feature detection is
+    # unavailable, and the user is notified via a #warning. So enabling
+    # this feature would prevent us from building with -Werror on
+    # armclang. Tracked in #7198.
+    scripts/config.py unset MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
+    scripts/config.py set MBEDTLS_HAVE_ASM
+
+    msg "AESCE, build with default configuration."
+    scripts/config.py set MBEDTLS_AESCE_C
+    scripts/config.py unset MBEDTLS_AES_USE_HARDWARE_ONLY
+    armc6_build_test "-O1 --target=aarch64-arm-none-eabi -march=armv8-a+crypto"
+
+    msg "AESCE, build AESCE only"
+    scripts/config.py set MBEDTLS_AESCE_C
+    scripts/config.py set MBEDTLS_AES_USE_HARDWARE_ONLY
+    armc6_build_test "-O1 --target=aarch64-arm-none-eabi -march=armv8-a+crypto"
+}
+
+support_build_aes_aesce_armcc () {
+    support_build_armcc
+}
+
+component_test_aes_only_128_bit_keys () {
+    msg "build: default config + AES_ONLY_128_BIT_KEY_LENGTH"
+    scripts/config.py set MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+    scripts/config.py unset MBEDTLS_PADLOCK_C
+
+    make CFLAGS='-O2 -Werror -Wall -Wextra'
+
+    msg "test: default config + AES_ONLY_128_BIT_KEY_LENGTH"
+    make test
+}
+
+component_test_no_ctr_drbg_aes_only_128_bit_keys () {
+    msg "build: default config + AES_ONLY_128_BIT_KEY_LENGTH - CTR_DRBG_C"
+    scripts/config.py set MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+    scripts/config.py unset MBEDTLS_CTR_DRBG_C
+    scripts/config.py unset MBEDTLS_PADLOCK_C
+
+    make CC=clang CFLAGS='-Werror -Wall -Wextra'
+
+    msg "test: default config + AES_ONLY_128_BIT_KEY_LENGTH - CTR_DRBG_C"
+    make test
+}
+
+component_test_aes_only_128_bit_keys_have_builtins () {
+    msg "build: default config + AES_ONLY_128_BIT_KEY_LENGTH - AESNI_C - AESCE_C"
+    scripts/config.py set MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+    scripts/config.py unset MBEDTLS_PADLOCK_C
+    scripts/config.py unset MBEDTLS_AESNI_C
+    scripts/config.py unset MBEDTLS_AESCE_C
+
+    make CFLAGS='-O2 -Werror -Wall -Wextra'
+
+    msg "test: default config + AES_ONLY_128_BIT_KEY_LENGTH - AESNI_C - AESCE_C"
+    make test
+
+    msg "selftest: default config + AES_ONLY_128_BIT_KEY_LENGTH - AESNI_C - AESCE_C"
+    programs/test/selftest
+}
+
+component_test_gcm_largetable () {
+    msg "build: default config + GCM_LARGE_TABLE - AESNI_C - AESCE_C"
+    scripts/config.py set MBEDTLS_GCM_LARGE_TABLE
+    scripts/config.py unset MBEDTLS_PADLOCK_C
+    scripts/config.py unset MBEDTLS_AESNI_C
+    scripts/config.py unset MBEDTLS_AESCE_C
+
+    make CFLAGS='-O2 -Werror -Wall -Wextra'
+
+    msg "test: default config - GCM_LARGE_TABLE - AESNI_C - AESCE_C"
+    make test
+}
+
+component_test_aes_fewer_tables () {
+    msg "build: default config with AES_FEWER_TABLES enabled"
+    scripts/config.py set MBEDTLS_AES_FEWER_TABLES
+    make CFLAGS='-O2 -Werror -Wall -Wextra'
+
+    msg "test: AES_FEWER_TABLES"
+    make test
+}
+
+component_test_aes_rom_tables () {
+    msg "build: default config with AES_ROM_TABLES enabled"
+    scripts/config.py set MBEDTLS_AES_ROM_TABLES
+    make CFLAGS='-O2 -Werror -Wall -Wextra'
+
+    msg "test: AES_ROM_TABLES"
+    make test
+}
+
+component_test_aes_fewer_tables_and_rom_tables () {
+    msg "build: default config with AES_ROM_TABLES and AES_FEWER_TABLES enabled"
+    scripts/config.py set MBEDTLS_AES_FEWER_TABLES
+    scripts/config.py set MBEDTLS_AES_ROM_TABLES
+    make CFLAGS='-O2 -Werror -Wall -Wextra'
+
+    msg "test: AES_FEWER_TABLES + AES_ROM_TABLES"
+    make test
+}
+
+# helper for common_block_cipher_no_decrypt() which:
+# - enable/disable the list of config options passed from -s/-u respectively.
+# - build
+# - test for tests_suite_xxx
+# - selftest
+#
+# Usage: helper_block_cipher_no_decrypt_build_test
+#        [-s set_opts] [-u unset_opts] [-c cflags] [-l ldflags] [option [...]]
+# Options:  -s set_opts     the list of config options to enable
+#           -u unset_opts   the list of config options to disable
+#           -c cflags       the list of options passed to CFLAGS
+#           -l ldflags      the list of options passed to LDFLAGS
+helper_block_cipher_no_decrypt_build_test () {
+    while [ $# -gt 0 ]; do
+        case "$1" in
+            -s)
+                shift; local set_opts="$1";;
+            -u)
+                shift; local unset_opts="$1";;
+            -c)
+                shift; local cflags="-Werror -Wall -Wextra $1";;
+            -l)
+                shift; local ldflags="$1";;
+        esac
+        shift
+    done
+    set_opts="${set_opts:-}"
+    unset_opts="${unset_opts:-}"
+    cflags="${cflags:-}"
+    ldflags="${ldflags:-}"
+
+    [ -n "$set_opts" ] && echo "Enabling: $set_opts" && scripts/config.py set-all $set_opts
+    [ -n "$unset_opts" ] && echo "Disabling: $unset_opts" && scripts/config.py unset-all $unset_opts
+
+    msg "build: default config + BLOCK_CIPHER_NO_DECRYPT${set_opts:+ + $set_opts}${unset_opts:+ - $unset_opts} with $cflags${ldflags:+, $ldflags}"
+    make clean
+    make CFLAGS="-O2 $cflags" LDFLAGS="$ldflags"
+
+    # Make sure we don't have mbedtls_xxx_setkey_dec in AES/ARIA/CAMELLIA
+    not grep mbedtls_aes_setkey_dec library/aes.o
+    not grep mbedtls_aria_setkey_dec library/aria.o
+    not grep mbedtls_camellia_setkey_dec library/camellia.o
+    # Make sure we don't have mbedtls_internal_aes_decrypt in AES
+    not grep mbedtls_internal_aes_decrypt library/aes.o
+    # Make sure we don't have mbedtls_aesni_inverse_key in AESNI
+    not grep mbedtls_aesni_inverse_key library/aesni.o
+
+    msg "test: default config + BLOCK_CIPHER_NO_DECRYPT${set_opts:+ + $set_opts}${unset_opts:+ - $unset_opts} with $cflags${ldflags:+, $ldflags}"
+    make test
+
+    msg "selftest: default config + BLOCK_CIPHER_NO_DECRYPT${set_opts:+ + $set_opts}${unset_opts:+ - $unset_opts} with $cflags${ldflags:+, $ldflags}"
+    programs/test/selftest
+}
+
+# This is a common configuration function used in:
+# - component_test_block_cipher_no_decrypt_aesni_legacy()
+# - component_test_block_cipher_no_decrypt_aesni_use_psa()
+# in order to test BLOCK_CIPHER_NO_DECRYPT with AESNI intrinsics,
+# AESNI assembly and AES C implementation on x86_64 and with AESNI intrinsics
+# on x86.
+common_block_cipher_no_decrypt () {
+    # test AESNI intrinsics
+    helper_block_cipher_no_decrypt_build_test \
+        -s "MBEDTLS_AESNI_C" \
+        -c "-mpclmul -msse2 -maes"
+
+    # test AESNI assembly
+    helper_block_cipher_no_decrypt_build_test \
+        -s "MBEDTLS_AESNI_C" \
+        -c "-mno-pclmul -mno-sse2 -mno-aes"
+
+    # test AES C implementation
+    helper_block_cipher_no_decrypt_build_test \
+        -u "MBEDTLS_AESNI_C"
+
+    # test AESNI intrinsics for i386 target
+    helper_block_cipher_no_decrypt_build_test \
+        -s "MBEDTLS_AESNI_C" \
+        -c "-m32 -mpclmul -msse2 -maes" \
+        -l "-m32"
+}
+
+# This is a configuration function used in component_test_block_cipher_no_decrypt_xxx:
+# usage: 0: no PSA crypto configuration
+#        1: use PSA crypto configuration
+config_block_cipher_no_decrypt () {
+    use_psa=$1
+
+    scripts/config.py set MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_XTS
+    scripts/config.py unset MBEDTLS_DES_C
+    scripts/config.py unset MBEDTLS_NIST_KW_C
+
+    if [ "$use_psa" -eq 1 ]; then
+        # Enable support for cryptographic mechanisms through the PSA API.
+        # Note: XTS, KW are not yet supported via the PSA API in Mbed TLS.
+        scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
+        scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_NO_PADDING
+        scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_PKCS7
+        scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_ECB_NO_PADDING
+        scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_DES
+    fi
+}
+
+component_test_block_cipher_no_decrypt_aesni () {
+    # This consistently causes an llvm crash on clang 3.8, so use gcc
+    export CC=gcc
+    config_block_cipher_no_decrypt 0
+    common_block_cipher_no_decrypt
+}
+
+component_test_block_cipher_no_decrypt_aesni_use_psa () {
+    # This consistently causes an llvm crash on clang 3.8, so use gcc
+    export CC=gcc
+    config_block_cipher_no_decrypt 1
+    common_block_cipher_no_decrypt
+}
+
+support_test_block_cipher_no_decrypt_aesce_armcc () {
+    support_build_armcc
+}
+
+component_test_block_cipher_no_decrypt_aesce_armcc () {
+    scripts/config.py baremetal
+
+    # armc[56] don't support SHA-512 intrinsics
+    scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
+
+    # Stop armclang warning about feature detection for A64_CRYPTO.
+    # With this enabled, the library does build correctly under armclang,
+    # but in baremetal builds (as tested here), feature detection is
+    # unavailable, and the user is notified via a #warning. So enabling
+    # this feature would prevent us from building with -Werror on
+    # armclang. Tracked in #7198.
+    scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
+    scripts/config.py set MBEDTLS_HAVE_ASM
+
+    config_block_cipher_no_decrypt 1
+
+    # test AESCE baremetal build
+    scripts/config.py set MBEDTLS_AESCE_C
+    msg "build: default config + BLOCK_CIPHER_NO_DECRYPT with AESCE"
+    armc6_build_test "-O1 --target=aarch64-arm-none-eabi -march=armv8-a+crypto -Werror -Wall -Wextra"
+
+    # Make sure we don't have mbedtls_xxx_setkey_dec in AES/ARIA/CAMELLIA
+    not grep mbedtls_aes_setkey_dec library/aes.o
+    not grep mbedtls_aria_setkey_dec library/aria.o
+    not grep mbedtls_camellia_setkey_dec library/camellia.o
+    # Make sure we don't have mbedtls_internal_aes_decrypt in AES
+    not grep mbedtls_internal_aes_decrypt library/aes.o
+    # Make sure we don't have mbedtls_aesce_inverse_key and aesce_decrypt_block in AESCE
+    not grep mbedtls_aesce_inverse_key library/aesce.o
+    not grep aesce_decrypt_block library/aesce.o
+}
+
+component_test_ctr_drbg_aes_256_sha_256 () {
+    msg "build: full + MBEDTLS_ENTROPY_FORCE_SHA256 (ASan build)"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
+    scripts/config.py set MBEDTLS_ENTROPY_FORCE_SHA256
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: full + MBEDTLS_ENTROPY_FORCE_SHA256 (ASan build)"
+    make test
+}
+
+component_test_ctr_drbg_aes_128_sha_512 () {
+    msg "build: full + MBEDTLS_CTR_DRBG_USE_128_BIT_KEY (ASan build)"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
+    scripts/config.py set MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: full + MBEDTLS_CTR_DRBG_USE_128_BIT_KEY (ASan build)"
+    make test
+}
+
+component_test_ctr_drbg_aes_128_sha_256 () {
+    msg "build: full + MBEDTLS_CTR_DRBG_USE_128_BIT_KEY + MBEDTLS_ENTROPY_FORCE_SHA256 (ASan build)"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
+    scripts/config.py set MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
+    scripts/config.py set MBEDTLS_ENTROPY_FORCE_SHA256
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: full + MBEDTLS_CTR_DRBG_USE_128_BIT_KEY + MBEDTLS_ENTROPY_FORCE_SHA256 (ASan build)"
+    make test
+}
+
+component_test_se_default () {
+    msg "build: default config + MBEDTLS_PSA_CRYPTO_SE_C"
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_SE_C
+    make CC=clang CFLAGS="$ASAN_CFLAGS -Os" LDFLAGS="$ASAN_CFLAGS"
+
+    msg "test: default config + MBEDTLS_PSA_CRYPTO_SE_C"
+    make test
+}
+
+component_test_psa_crypto_drivers () {
+    msg "build: full + test drivers dispatching to builtins"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_CONFIG
+    loc_cflags="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST_ALL"
+    loc_cflags="${loc_cflags} '-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/user-config-for-test.h\"'"
+    loc_cflags="${loc_cflags} -I../tests/include -O2"
+
+    make CC=$ASAN_CC CFLAGS="${loc_cflags}" LDFLAGS="$ASAN_CFLAGS"
+
+    msg "test: full + test drivers dispatching to builtins"
+    make test
+}
+
+component_build_psa_config_file () {
+    msg "build: make with MBEDTLS_PSA_CRYPTO_CONFIG_FILE" # ~40s
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
+    cp "$CRYPTO_CONFIG_H" psa_test_config.h
+    echo '#error "MBEDTLS_PSA_CRYPTO_CONFIG_FILE is not working"' >"$CRYPTO_CONFIG_H"
+    make CFLAGS="-I '$PWD' -DMBEDTLS_PSA_CRYPTO_CONFIG_FILE='\"psa_test_config.h\"'"
+    # Make sure this feature is enabled. We'll disable it in the next phase.
+    programs/test/query_compile_time_config MBEDTLS_CMAC_C
+    make clean
+
+    msg "build: make with MBEDTLS_PSA_CRYPTO_CONFIG_FILE + MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE" # ~40s
+    # In the user config, disable one feature and its dependencies, which will
+    # reflect on the mbedtls configuration so we can query it with
+    # query_compile_time_config.
+    echo '#undef PSA_WANT_ALG_CMAC' >psa_user_config.h
+    echo '#undef PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128' >> psa_user_config.h
+    scripts/config.py unset MBEDTLS_CMAC_C
+    make CFLAGS="-I '$PWD' -DMBEDTLS_PSA_CRYPTO_CONFIG_FILE='\"psa_test_config.h\"' -DMBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE='\"psa_user_config.h\"'"
+    not programs/test/query_compile_time_config MBEDTLS_CMAC_C
+
+    rm -f psa_test_config.h psa_user_config.h
+}
+
+component_build_psa_alt_headers () {
+    msg "build: make with PSA alt headers" # ~20s
+
+    # Generate alternative versions of the substitutable headers with the
+    # same content except different include guards.
+    make -C tests include/alt-extra/psa/crypto_platform_alt.h include/alt-extra/psa/crypto_struct_alt.h
+
+    # Build the library and some programs.
+    # Don't build the fuzzers to avoid having to go through hoops to set
+    # a correct include path for programs/fuzz/Makefile.
+    make CFLAGS="-I ../tests/include/alt-extra -DMBEDTLS_PSA_CRYPTO_PLATFORM_FILE='\"psa/crypto_platform_alt.h\"' -DMBEDTLS_PSA_CRYPTO_STRUCT_FILE='\"psa/crypto_struct_alt.h\"'" lib
+    make -C programs -o fuzz CFLAGS="-I ../tests/include/alt-extra -DMBEDTLS_PSA_CRYPTO_PLATFORM_FILE='\"psa/crypto_platform_alt.h\"' -DMBEDTLS_PSA_CRYPTO_STRUCT_FILE='\"psa/crypto_struct_alt.h\"'"
+
+    # Check that we're getting the alternative include guards and not the
+    # original include guards.
+    programs/test/query_included_headers | grep -x PSA_CRYPTO_PLATFORM_ALT_H
+    programs/test/query_included_headers | grep -x PSA_CRYPTO_STRUCT_ALT_H
+    programs/test/query_included_headers | not grep -x PSA_CRYPTO_PLATFORM_H
+    programs/test/query_included_headers | not grep -x PSA_CRYPTO_STRUCT_H
+}
+
+component_test_min_mpi_window_size () {
+    msg "build: Default + MBEDTLS_MPI_WINDOW_SIZE=1 (ASan build)" # ~ 10s
+    scripts/config.py set MBEDTLS_MPI_WINDOW_SIZE 1
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: MBEDTLS_MPI_WINDOW_SIZE=1 - main suites (inc. selftests) (ASan build)" # ~ 10s
+    make test
+}
diff --git a/tests/scripts/components-configuration-platform.sh b/tests/scripts/components-configuration-platform.sh
new file mode 100644
index 0000000..0b96634
--- /dev/null
+++ b/tests/scripts/components-configuration-platform.sh
@@ -0,0 +1,111 @@
+# components-configuration-platform.sh
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+# This file contains test components that are executed by all.sh
+
+################################################################
+#### Configuration Testing - Platform
+################################################################
+
+component_build_no_std_function () {
+    # catch compile bugs in _uninit functions
+    msg "build: full config with NO_STD_FUNCTION, make, gcc" # ~ 30s
+    scripts/config.py full
+    scripts/config.py set MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+    scripts/config.py unset MBEDTLS_ENTROPY_NV_SEED
+    scripts/config.py unset MBEDTLS_PLATFORM_NV_SEED_ALT
+    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Check .
+    make
+}
+
+component_build_no_sockets () {
+    # Note, C99 compliance can also be tested with the sockets support disabled,
+    # as that requires a POSIX platform (which isn't the same as C99).
+    msg "build: full config except net_sockets.c, make, gcc -std=c99 -pedantic" # ~ 30s
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_NET_C # getaddrinfo() undeclared, etc.
+    scripts/config.py set MBEDTLS_NO_PLATFORM_ENTROPY # uses syscall() on GNU/Linux
+    make CC=gcc CFLAGS='-Werror -Wall -Wextra -O1 -std=c99 -pedantic' lib
+}
+
+component_test_no_date_time () {
+    msg "build: default config without MBEDTLS_HAVE_TIME_DATE"
+    scripts/config.py unset MBEDTLS_HAVE_TIME_DATE
+    cmake -D CMAKE_BUILD_TYPE:String=Check .
+    make
+
+    msg "test: !MBEDTLS_HAVE_TIME_DATE - main suites"
+    make test
+}
+
+component_test_platform_calloc_macro () {
+    msg "build: MBEDTLS_PLATFORM_{CALLOC/FREE}_MACRO enabled (ASan build)"
+    scripts/config.py set MBEDTLS_PLATFORM_MEMORY
+    scripts/config.py set MBEDTLS_PLATFORM_CALLOC_MACRO calloc
+    scripts/config.py set MBEDTLS_PLATFORM_FREE_MACRO   free
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: MBEDTLS_PLATFORM_{CALLOC/FREE}_MACRO enabled (ASan build)"
+    make test
+}
+
+component_test_have_int32 () {
+    msg "build: gcc, force 32-bit bignum limbs"
+    scripts/config.py unset MBEDTLS_HAVE_ASM
+    scripts/config.py unset MBEDTLS_AESNI_C
+    scripts/config.py unset MBEDTLS_PADLOCK_C
+    scripts/config.py unset MBEDTLS_AESCE_C
+    make CC=gcc CFLAGS='-O2 -Werror -Wall -Wextra -DMBEDTLS_HAVE_INT32'
+
+    msg "test: gcc, force 32-bit bignum limbs"
+    make test
+}
+
+component_test_have_int64 () {
+    msg "build: gcc, force 64-bit bignum limbs"
+    scripts/config.py unset MBEDTLS_HAVE_ASM
+    scripts/config.py unset MBEDTLS_AESNI_C
+    scripts/config.py unset MBEDTLS_PADLOCK_C
+    scripts/config.py unset MBEDTLS_AESCE_C
+    make CC=gcc CFLAGS='-O2 -Werror -Wall -Wextra -DMBEDTLS_HAVE_INT64'
+
+    msg "test: gcc, force 64-bit bignum limbs"
+    make test
+}
+
+component_test_have_int32_cmake_new_bignum () {
+    msg "build: gcc, force 32-bit bignum limbs, new bignum interface, test hooks (ASan build)"
+    scripts/config.py unset MBEDTLS_HAVE_ASM
+    scripts/config.py unset MBEDTLS_AESNI_C
+    scripts/config.py unset MBEDTLS_PADLOCK_C
+    scripts/config.py unset MBEDTLS_AESCE_C
+    scripts/config.py set MBEDTLS_TEST_HOOKS
+    scripts/config.py set MBEDTLS_ECP_WITH_MPI_UINT
+    make CC=gcc CFLAGS="$ASAN_CFLAGS -Werror -Wall -Wextra -DMBEDTLS_HAVE_INT32" LDFLAGS="$ASAN_CFLAGS"
+
+    msg "test: gcc, force 32-bit bignum limbs, new bignum interface, test hooks (ASan build)"
+    make test
+}
+
+component_test_no_udbl_division () {
+    msg "build: MBEDTLS_NO_UDBL_DIVISION native" # ~ 10s
+    scripts/config.py full
+    scripts/config.py set MBEDTLS_NO_UDBL_DIVISION
+    make CFLAGS='-Werror -O1'
+
+    msg "test: MBEDTLS_NO_UDBL_DIVISION native" # ~ 10s
+    make test
+}
+
+component_test_no_64bit_multiplication () {
+    msg "build: MBEDTLS_NO_64BIT_MULTIPLICATION native" # ~ 10s
+    scripts/config.py full
+    scripts/config.py set MBEDTLS_NO_64BIT_MULTIPLICATION
+    make CFLAGS='-Werror -O1'
+
+    msg "test: MBEDTLS_NO_64BIT_MULTIPLICATION native" # ~ 10s
+    make test
+}
diff --git a/tests/scripts/components-configuration-tls.sh b/tests/scripts/components-configuration-tls.sh
new file mode 100644
index 0000000..5511cc9
--- /dev/null
+++ b/tests/scripts/components-configuration-tls.sh
@@ -0,0 +1,627 @@
+# components-configuration-tls.sh
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+# This file contains test components that are executed by all.sh
+
+################################################################
+#### Configuration Testing - TLS
+################################################################
+
+component_test_no_renegotiation () {
+    msg "build: Default + !MBEDTLS_SSL_RENEGOTIATION (ASan build)" # ~ 6 min
+    scripts/config.py unset MBEDTLS_SSL_RENEGOTIATION
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: !MBEDTLS_SSL_RENEGOTIATION - main suites (inc. selftests) (ASan build)" # ~ 50s
+    make test
+
+    msg "test: !MBEDTLS_SSL_RENEGOTIATION - ssl-opt.sh (ASan build)" # ~ 6 min
+    tests/ssl-opt.sh
+}
+
+component_test_tls1_2_default_stream_cipher_only () {
+    msg "build: default with only stream cipher"
+
+    # Disable AEAD (controlled by the presence of one of GCM_C, CCM_C, CHACHAPOLY_C
+    scripts/config.py unset MBEDTLS_GCM_C
+    scripts/config.py unset MBEDTLS_CCM_C
+    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
+    #Disable TLS 1.3 (as no AEAD)
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    # Disable CBC-legacy (controlled by MBEDTLS_CIPHER_MODE_CBC plus at least one block cipher (AES, ARIA, Camellia, DES))
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
+    # Disable CBC-EtM (controlled by the same as CBC-legacy plus MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+    scripts/config.py unset MBEDTLS_SSL_ENCRYPT_THEN_MAC
+    # Enable stream (currently that's just the NULL pseudo-cipher (controlled by MBEDTLS_CIPHER_NULL_CIPHER))
+    scripts/config.py set MBEDTLS_CIPHER_NULL_CIPHER
+    # Modules that depend on AEAD
+    scripts/config.py unset MBEDTLS_SSL_CONTEXT_SERIALIZATION
+    scripts/config.py unset MBEDTLS_SSL_TICKET_C
+
+    make
+
+    msg "test: default with only stream cipher"
+    make test
+
+    # Not running ssl-opt.sh because most tests require a non-NULL ciphersuite.
+}
+
+component_test_tls1_2_default_stream_cipher_only_use_psa () {
+    msg "build: default with only stream cipher use psa"
+
+    scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
+    # Disable AEAD (controlled by the presence of one of GCM_C, CCM_C, CHACHAPOLY_C)
+    scripts/config.py unset MBEDTLS_GCM_C
+    scripts/config.py unset MBEDTLS_CCM_C
+    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
+    #Disable TLS 1.3 (as no AEAD)
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    # Disable CBC-legacy (controlled by MBEDTLS_CIPHER_MODE_CBC plus at least one block cipher (AES, ARIA, Camellia, DES))
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
+    # Disable CBC-EtM (controlled by the same as CBC-legacy plus MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+    scripts/config.py unset MBEDTLS_SSL_ENCRYPT_THEN_MAC
+    # Enable stream (currently that's just the NULL pseudo-cipher (controlled by MBEDTLS_CIPHER_NULL_CIPHER))
+    scripts/config.py set MBEDTLS_CIPHER_NULL_CIPHER
+    # Modules that depend on AEAD
+    scripts/config.py unset MBEDTLS_SSL_CONTEXT_SERIALIZATION
+    scripts/config.py unset MBEDTLS_SSL_TICKET_C
+
+    make
+
+    msg "test: default with only stream cipher use psa"
+    make test
+
+    # Not running ssl-opt.sh because most tests require a non-NULL ciphersuite.
+}
+
+component_test_tls1_2_default_cbc_legacy_cipher_only () {
+    msg "build: default with only CBC-legacy cipher"
+
+    # Disable AEAD (controlled by the presence of one of GCM_C, CCM_C, CHACHAPOLY_C)
+    scripts/config.py unset MBEDTLS_GCM_C
+    scripts/config.py unset MBEDTLS_CCM_C
+    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
+    #Disable TLS 1.3 (as no AEAD)
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    # Enable CBC-legacy (controlled by MBEDTLS_CIPHER_MODE_CBC plus at least one block cipher (AES, ARIA, Camellia, DES))
+    scripts/config.py set MBEDTLS_CIPHER_MODE_CBC
+    # Disable CBC-EtM (controlled by the same as CBC-legacy plus MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+    scripts/config.py unset MBEDTLS_SSL_ENCRYPT_THEN_MAC
+    # Disable stream (currently that's just the NULL pseudo-cipher (controlled by MBEDTLS_CIPHER_NULL_CIPHER))
+    scripts/config.py unset MBEDTLS_CIPHER_NULL_CIPHER
+    # Modules that depend on AEAD
+    scripts/config.py unset MBEDTLS_SSL_CONTEXT_SERIALIZATION
+    scripts/config.py unset MBEDTLS_SSL_TICKET_C
+
+    make
+
+    msg "test: default with only CBC-legacy cipher"
+    make test
+
+    msg "test: default with only CBC-legacy cipher - ssl-opt.sh (subset)"
+    tests/ssl-opt.sh -f "TLS 1.2"
+}
+
+component_test_tls1_2_default_cbc_legacy_cipher_only_use_psa () {
+    msg "build: default with only CBC-legacy cipher use psa"
+
+    scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
+    # Disable AEAD (controlled by the presence of one of GCM_C, CCM_C, CHACHAPOLY_C)
+    scripts/config.py unset MBEDTLS_GCM_C
+    scripts/config.py unset MBEDTLS_CCM_C
+    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
+    #Disable TLS 1.3 (as no AEAD)
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    # Enable CBC-legacy (controlled by MBEDTLS_CIPHER_MODE_CBC plus at least one block cipher (AES, ARIA, Camellia, DES))
+    scripts/config.py set MBEDTLS_CIPHER_MODE_CBC
+    # Disable CBC-EtM (controlled by the same as CBC-legacy plus MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+    scripts/config.py unset MBEDTLS_SSL_ENCRYPT_THEN_MAC
+    # Disable stream (currently that's just the NULL pseudo-cipher (controlled by MBEDTLS_CIPHER_NULL_CIPHER))
+    scripts/config.py unset MBEDTLS_CIPHER_NULL_CIPHER
+    # Modules that depend on AEAD
+    scripts/config.py unset MBEDTLS_SSL_CONTEXT_SERIALIZATION
+    scripts/config.py unset MBEDTLS_SSL_TICKET_C
+
+    make
+
+    msg "test: default with only CBC-legacy cipher use psa"
+    make test
+
+    msg "test: default with only CBC-legacy cipher use psa - ssl-opt.sh (subset)"
+    tests/ssl-opt.sh -f "TLS 1.2"
+}
+
+component_test_tls1_2_default_cbc_legacy_cbc_etm_cipher_only () {
+    msg "build: default with only CBC-legacy and CBC-EtM ciphers"
+
+    # Disable AEAD (controlled by the presence of one of GCM_C, CCM_C, CHACHAPOLY_C)
+    scripts/config.py unset MBEDTLS_GCM_C
+    scripts/config.py unset MBEDTLS_CCM_C
+    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
+    #Disable TLS 1.3 (as no AEAD)
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    # Enable CBC-legacy (controlled by MBEDTLS_CIPHER_MODE_CBC plus at least one block cipher (AES, ARIA, Camellia, DES))
+    scripts/config.py set MBEDTLS_CIPHER_MODE_CBC
+    # Enable CBC-EtM (controlled by the same as CBC-legacy plus MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+    scripts/config.py set MBEDTLS_SSL_ENCRYPT_THEN_MAC
+    # Disable stream (currently that's just the NULL pseudo-cipher (controlled by MBEDTLS_CIPHER_NULL_CIPHER))
+    scripts/config.py unset MBEDTLS_CIPHER_NULL_CIPHER
+    # Modules that depend on AEAD
+    scripts/config.py unset MBEDTLS_SSL_CONTEXT_SERIALIZATION
+    scripts/config.py unset MBEDTLS_SSL_TICKET_C
+
+    make
+
+    msg "test: default with only CBC-legacy and CBC-EtM ciphers"
+    make test
+
+    msg "test: default with only CBC-legacy and CBC-EtM ciphers - ssl-opt.sh (subset)"
+    tests/ssl-opt.sh -f "TLS 1.2"
+}
+
+component_test_tls1_2_default_cbc_legacy_cbc_etm_cipher_only_use_psa () {
+    msg "build: default with only CBC-legacy and CBC-EtM ciphers use psa"
+
+    scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
+    # Disable AEAD (controlled by the presence of one of GCM_C, CCM_C, CHACHAPOLY_C)
+    scripts/config.py unset MBEDTLS_GCM_C
+    scripts/config.py unset MBEDTLS_CCM_C
+    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
+    #Disable TLS 1.3 (as no AEAD)
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    # Enable CBC-legacy (controlled by MBEDTLS_CIPHER_MODE_CBC plus at least one block cipher (AES, ARIA, Camellia, DES))
+    scripts/config.py set MBEDTLS_CIPHER_MODE_CBC
+    # Enable CBC-EtM (controlled by the same as CBC-legacy plus MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+    scripts/config.py set MBEDTLS_SSL_ENCRYPT_THEN_MAC
+    # Disable stream (currently that's just the NULL pseudo-cipher (controlled by MBEDTLS_CIPHER_NULL_CIPHER))
+    scripts/config.py unset MBEDTLS_CIPHER_NULL_CIPHER
+    # Modules that depend on AEAD
+    scripts/config.py unset MBEDTLS_SSL_CONTEXT_SERIALIZATION
+    scripts/config.py unset MBEDTLS_SSL_TICKET_C
+
+    make
+
+    msg "test: default with only CBC-legacy and CBC-EtM ciphers use psa"
+    make test
+
+    msg "test: default with only CBC-legacy and CBC-EtM ciphers use psa - ssl-opt.sh (subset)"
+    tests/ssl-opt.sh -f "TLS 1.2"
+}
+
+# We're not aware of any other (open source) implementation of EC J-PAKE in TLS
+# that we could use for interop testing. However, we now have sort of two
+# implementations ourselves: one using PSA, the other not. At least test that
+# these two interoperate with each other.
+component_test_tls1_2_ecjpake_compatibility () {
+    msg "build: TLS1.2 server+client w/ EC-JPAKE w/o USE_PSA"
+    scripts/config.py set MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+    # Explicitly make lib first to avoid a race condition:
+    # https://github.com/Mbed-TLS/mbedtls/issues/8229
+    make lib
+    make -C programs ssl/ssl_server2 ssl/ssl_client2
+    cp programs/ssl/ssl_server2 s2_no_use_psa
+    cp programs/ssl/ssl_client2 c2_no_use_psa
+
+    msg "build: TLS1.2 server+client w/ EC-JPAKE w/ USE_PSA"
+    scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
+    make clean
+    make lib
+    make -C programs ssl/ssl_server2 ssl/ssl_client2
+    make -C programs test/udp_proxy test/query_compile_time_config
+
+    msg "test: server w/o USE_PSA - client w/ USE_PSA, text password"
+    P_SRV=../s2_no_use_psa tests/ssl-opt.sh -f "ECJPAKE: working, TLS"
+    msg "test: server w/o USE_PSA - client w/ USE_PSA, opaque password"
+    P_SRV=../s2_no_use_psa tests/ssl-opt.sh -f "ECJPAKE: opaque password client only, working, TLS"
+    msg "test: client w/o USE_PSA - server w/ USE_PSA, text password"
+    P_CLI=../c2_no_use_psa tests/ssl-opt.sh -f "ECJPAKE: working, TLS"
+    msg "test: client w/o USE_PSA - server w/ USE_PSA, opaque password"
+    P_CLI=../c2_no_use_psa tests/ssl-opt.sh -f "ECJPAKE: opaque password server only, working, TLS"
+
+    rm s2_no_use_psa c2_no_use_psa
+}
+
+component_test_small_ssl_out_content_len () {
+    msg "build: small SSL_OUT_CONTENT_LEN (ASan build)"
+    scripts/config.py set MBEDTLS_SSL_IN_CONTENT_LEN 16384
+    scripts/config.py set MBEDTLS_SSL_OUT_CONTENT_LEN 4096
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: small SSL_OUT_CONTENT_LEN - ssl-opt.sh MFL and large packet tests"
+    tests/ssl-opt.sh -f "Max fragment\|Large packet"
+}
+
+component_test_small_ssl_in_content_len () {
+    msg "build: small SSL_IN_CONTENT_LEN (ASan build)"
+    scripts/config.py set MBEDTLS_SSL_IN_CONTENT_LEN 4096
+    scripts/config.py set MBEDTLS_SSL_OUT_CONTENT_LEN 16384
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: small SSL_IN_CONTENT_LEN - ssl-opt.sh MFL tests"
+    tests/ssl-opt.sh -f "Max fragment"
+}
+
+component_test_small_ssl_dtls_max_buffering () {
+    msg "build: small MBEDTLS_SSL_DTLS_MAX_BUFFERING #0"
+    scripts/config.py set MBEDTLS_SSL_DTLS_MAX_BUFFERING 1000
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: small MBEDTLS_SSL_DTLS_MAX_BUFFERING #0 - ssl-opt.sh specific reordering test"
+    tests/ssl-opt.sh -f "DTLS reordering: Buffer out-of-order hs msg before reassembling next, free buffered msg"
+}
+
+component_test_small_mbedtls_ssl_dtls_max_buffering () {
+    msg "build: small MBEDTLS_SSL_DTLS_MAX_BUFFERING #1"
+    scripts/config.py set MBEDTLS_SSL_DTLS_MAX_BUFFERING 190
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: small MBEDTLS_SSL_DTLS_MAX_BUFFERING #1 - ssl-opt.sh specific reordering test"
+    tests/ssl-opt.sh -f "DTLS reordering: Buffer encrypted Finished message, drop for fragmented NewSessionTicket"
+}
+
+component_test_depends_py_kex () {
+    msg "test/build: depends.py kex (gcc)"
+    tests/scripts/depends.py kex --unset-use-psa
+}
+
+component_test_depends_py_kex_psa () {
+    msg "test/build: depends.py kex (gcc) with MBEDTLS_USE_PSA_CRYPTO defined"
+    tests/scripts/depends.py kex
+}
+
+# Common helper for component_full_without_ecdhe_ecdsa() and
+# component_full_without_ecdhe_ecdsa_and_tls13() which:
+# - starts from the "full" configuration minus the list of symbols passed in
+#   as 1st parameter
+# - build
+# - test only TLS (i.e. test_suite_tls and ssl-opt)
+build_full_minus_something_and_test_tls () {
+    symbols_to_disable="$1"
+
+    msg "build: full minus something, test TLS"
+
+    scripts/config.py full
+    for sym in $symbols_to_disable; do
+        echo "Disabling $sym"
+        scripts/config.py unset $sym
+    done
+
+    make
+
+    msg "test: full minus something, test TLS"
+    ( cd tests; ./test_suite_ssl )
+
+    msg "ssl-opt: full minus something, test TLS"
+    tests/ssl-opt.sh
+}
+
+component_full_without_ecdhe_ecdsa () {
+    build_full_minus_something_and_test_tls "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED"
+}
+
+component_full_without_ecdhe_ecdsa_and_tls13 () {
+    build_full_minus_something_and_test_tls "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+                                             MBEDTLS_SSL_PROTO_TLS1_3"
+}
+
+component_build_no_ssl_srv () {
+    msg "build: full config except SSL server, make, gcc" # ~ 30s
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_SSL_SRV_C
+    make CC=gcc CFLAGS='-Werror -Wall -Wextra -O1'
+}
+
+component_build_no_ssl_cli () {
+    msg "build: full config except SSL client, make, gcc" # ~ 30s
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_SSL_CLI_C
+    make CC=gcc CFLAGS='-Werror -Wall -Wextra -O1'
+}
+
+component_test_no_max_fragment_length () {
+    # Run max fragment length tests with MFL disabled
+    msg "build: default config except MFL extension (ASan build)" # ~ 30s
+    scripts/config.py unset MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: ssl-opt.sh, MFL-related tests"
+    tests/ssl-opt.sh -f "Max fragment length"
+}
+
+component_test_asan_remove_peer_certificate () {
+    msg "build: default config with MBEDTLS_SSL_KEEP_PEER_CERTIFICATE disabled (ASan build)"
+    scripts/config.py unset MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE"
+    make test
+
+    msg "test: ssl-opt.sh, !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE"
+    tests/ssl-opt.sh
+
+    msg "test: compat.sh, !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE"
+    tests/compat.sh
+
+    msg "test: context-info.sh, !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE"
+    tests/context-info.sh
+}
+
+component_test_no_max_fragment_length_small_ssl_out_content_len () {
+    msg "build: no MFL extension, small SSL_OUT_CONTENT_LEN (ASan build)"
+    scripts/config.py unset MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+    scripts/config.py set MBEDTLS_SSL_IN_CONTENT_LEN 16384
+    scripts/config.py set MBEDTLS_SSL_OUT_CONTENT_LEN 4096
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: MFL tests (disabled MFL extension case) & large packet tests"
+    tests/ssl-opt.sh -f "Max fragment length\|Large buffer"
+
+    msg "test: context-info.sh (disabled MFL extension case)"
+    tests/context-info.sh
+}
+
+component_test_variable_ssl_in_out_buffer_len () {
+    msg "build: MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH enabled (ASan build)"
+    scripts/config.py set MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH enabled"
+    make test
+
+    msg "test: ssl-opt.sh, MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH enabled"
+    tests/ssl-opt.sh
+
+    msg "test: compat.sh, MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH enabled"
+    tests/compat.sh
+}
+
+component_test_dtls_cid_legacy () {
+    msg "build: MBEDTLS_SSL_DTLS_CONNECTION_ID (legacy) enabled (ASan build)"
+    scripts/config.py set MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT 1
+
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: MBEDTLS_SSL_DTLS_CONNECTION_ID (legacy)"
+    make test
+
+    msg "test: ssl-opt.sh, MBEDTLS_SSL_DTLS_CONNECTION_ID (legacy) enabled"
+    tests/ssl-opt.sh
+
+    msg "test: compat.sh, MBEDTLS_SSL_DTLS_CONNECTION_ID (legacy) enabled"
+    tests/compat.sh
+}
+
+component_test_ssl_alloc_buffer_and_mfl () {
+    msg "build: default config with memory buffer allocator and MFL extension"
+    scripts/config.py set MBEDTLS_MEMORY_BUFFER_ALLOC_C
+    scripts/config.py set MBEDTLS_PLATFORM_MEMORY
+    scripts/config.py set MBEDTLS_MEMORY_DEBUG
+    scripts/config.py set MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+    scripts/config.py set MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
+    cmake -DCMAKE_BUILD_TYPE:String=Release .
+    make
+
+    msg "test: MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH, MBEDTLS_MEMORY_BUFFER_ALLOC_C, MBEDTLS_MEMORY_DEBUG and MBEDTLS_SSL_MAX_FRAGMENT_LENGTH"
+    make test
+
+    msg "test: MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH, MBEDTLS_MEMORY_BUFFER_ALLOC_C, MBEDTLS_MEMORY_DEBUG and MBEDTLS_SSL_MAX_FRAGMENT_LENGTH"
+    tests/ssl-opt.sh -f "Handshake memory usage"
+}
+
+component_test_when_no_ciphersuites_have_mac () {
+    msg "build: when no ciphersuites have MAC"
+    scripts/config.py unset MBEDTLS_CIPHER_NULL_CIPHER
+    scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
+    scripts/config.py unset MBEDTLS_CMAC_C
+    make
+
+    msg "test: !MBEDTLS_SSL_SOME_SUITES_USE_MAC"
+    make test
+
+    msg "test ssl-opt.sh: !MBEDTLS_SSL_SOME_SUITES_USE_MAC"
+    tests/ssl-opt.sh -f 'Default\|EtM' -e 'without EtM'
+}
+
+component_test_tls12_only () {
+    msg "build: default config without MBEDTLS_SSL_PROTO_TLS1_3, cmake, gcc, ASan"
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: main suites (inc. selftests) (ASan build)"
+    make test
+
+    msg "test: ssl-opt.sh (ASan build)"
+    tests/ssl-opt.sh
+
+    msg "test: compat.sh (ASan build)"
+    tests/compat.sh
+}
+
+component_test_tls13_only () {
+    msg "build: default config without MBEDTLS_SSL_PROTO_TLS1_2"
+    scripts/config.py set MBEDTLS_SSL_EARLY_DATA
+    scripts/config.py set MBEDTLS_SSL_RECORD_SIZE_LIMIT
+    make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
+
+    msg "test: TLS 1.3 only, all key exchange modes enabled"
+    make test
+
+    msg "ssl-opt.sh: TLS 1.3 only, all key exchange modes enabled"
+    tests/ssl-opt.sh
+}
+
+component_test_tls13_only_psk () {
+    msg "build: TLS 1.3 only from default, only PSK key exchange mode"
+    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+    scripts/config.py unset MBEDTLS_ECDH_C
+    scripts/config.py unset MBEDTLS_DHM_C
+    scripts/config.py unset MBEDTLS_X509_CRT_PARSE_C
+    scripts/config.py unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
+    scripts/config.py unset MBEDTLS_SSL_SERVER_NAME_INDICATION
+    scripts/config.py unset MBEDTLS_ECDSA_C
+    scripts/config.py unset MBEDTLS_PKCS1_V21
+    scripts/config.py unset MBEDTLS_PKCS7_C
+    scripts/config.py set   MBEDTLS_SSL_EARLY_DATA
+    make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
+
+    msg "test_suite_ssl: TLS 1.3 only, only PSK key exchange mode enabled"
+    cd tests; ./test_suite_ssl; cd ..
+
+    msg "ssl-opt.sh: TLS 1.3 only, only PSK key exchange mode enabled"
+    tests/ssl-opt.sh
+}
+
+component_test_tls13_only_ephemeral () {
+    msg "build: TLS 1.3 only from default, only ephemeral key exchange mode"
+    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+    scripts/config.py unset MBEDTLS_SSL_EARLY_DATA
+    make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
+
+    msg "test_suite_ssl: TLS 1.3 only, only ephemeral key exchange mode"
+    cd tests; ./test_suite_ssl; cd ..
+
+    msg "ssl-opt.sh: TLS 1.3 only, only ephemeral key exchange mode"
+    tests/ssl-opt.sh
+}
+
+component_test_tls13_only_ephemeral_ffdh () {
+    msg "build: TLS 1.3 only from default, only ephemeral ffdh key exchange mode"
+    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+    scripts/config.py unset MBEDTLS_SSL_EARLY_DATA
+    scripts/config.py unset MBEDTLS_ECDH_C
+
+    make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
+
+    msg "test_suite_ssl: TLS 1.3 only, only ephemeral ffdh key exchange mode"
+    cd tests; ./test_suite_ssl; cd ..
+
+    msg "ssl-opt.sh: TLS 1.3 only, only ephemeral ffdh key exchange mode"
+    tests/ssl-opt.sh
+}
+
+component_test_tls13_only_psk_ephemeral () {
+    msg "build: TLS 1.3 only from default, only PSK ephemeral key exchange mode"
+    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+    scripts/config.py unset MBEDTLS_X509_CRT_PARSE_C
+    scripts/config.py unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
+    scripts/config.py unset MBEDTLS_SSL_SERVER_NAME_INDICATION
+    scripts/config.py unset MBEDTLS_ECDSA_C
+    scripts/config.py unset MBEDTLS_PKCS1_V21
+    scripts/config.py unset MBEDTLS_PKCS7_C
+    scripts/config.py set   MBEDTLS_SSL_EARLY_DATA
+    make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
+
+    msg "test_suite_ssl: TLS 1.3 only, only PSK ephemeral key exchange mode"
+    cd tests; ./test_suite_ssl; cd ..
+
+    msg "ssl-opt.sh: TLS 1.3 only, only PSK ephemeral key exchange mode"
+    tests/ssl-opt.sh
+}
+
+component_test_tls13_only_psk_ephemeral_ffdh () {
+    msg "build: TLS 1.3 only from default, only PSK ephemeral ffdh key exchange mode"
+    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+    scripts/config.py unset MBEDTLS_X509_CRT_PARSE_C
+    scripts/config.py unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
+    scripts/config.py unset MBEDTLS_SSL_SERVER_NAME_INDICATION
+    scripts/config.py unset MBEDTLS_ECDSA_C
+    scripts/config.py unset MBEDTLS_PKCS1_V21
+    scripts/config.py unset MBEDTLS_PKCS7_C
+    scripts/config.py set   MBEDTLS_SSL_EARLY_DATA
+    scripts/config.py unset MBEDTLS_ECDH_C
+    make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
+
+    msg "test_suite_ssl: TLS 1.3 only, only PSK ephemeral ffdh key exchange mode"
+    cd tests; ./test_suite_ssl; cd ..
+
+    msg "ssl-opt.sh: TLS 1.3 only, only PSK ephemeral ffdh key exchange mode"
+    tests/ssl-opt.sh
+}
+
+component_test_tls13_only_psk_all () {
+    msg "build: TLS 1.3 only from default, without ephemeral key exchange mode"
+    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+    scripts/config.py unset MBEDTLS_X509_CRT_PARSE_C
+    scripts/config.py unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
+    scripts/config.py unset MBEDTLS_SSL_SERVER_NAME_INDICATION
+    scripts/config.py unset MBEDTLS_ECDSA_C
+    scripts/config.py unset MBEDTLS_PKCS1_V21
+    scripts/config.py unset MBEDTLS_PKCS7_C
+    scripts/config.py set   MBEDTLS_SSL_EARLY_DATA
+    make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
+
+    msg "test_suite_ssl: TLS 1.3 only, PSK and PSK ephemeral key exchange modes"
+    cd tests; ./test_suite_ssl; cd ..
+
+    msg "ssl-opt.sh: TLS 1.3 only, PSK and PSK ephemeral key exchange modes"
+    tests/ssl-opt.sh
+}
+
+component_test_tls13_only_ephemeral_all () {
+    msg "build: TLS 1.3 only from default, without PSK key exchange mode"
+    scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+    scripts/config.py set   MBEDTLS_SSL_EARLY_DATA
+    make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
+
+    msg "test_suite_ssl: TLS 1.3 only, ephemeral and PSK ephemeral key exchange modes"
+    cd tests; ./test_suite_ssl; cd ..
+
+    msg "ssl-opt.sh: TLS 1.3 only, ephemeral and PSK ephemeral key exchange modes"
+    tests/ssl-opt.sh
+}
+
+component_test_tls13_no_padding () {
+    msg "build: default config plus early data minus padding"
+    scripts/config.py set MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY 1
+    scripts/config.py set MBEDTLS_SSL_EARLY_DATA
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+    msg "test: default config plus early data minus padding"
+    make test
+    msg "ssl-opt.sh (TLS 1.3 no padding)"
+    tests/ssl-opt.sh
+}
+
+component_test_tls13_no_compatibility_mode () {
+    msg "build: default config plus early data minus middlebox compatibility mode"
+    scripts/config.py unset MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
+    scripts/config.py set   MBEDTLS_SSL_EARLY_DATA
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+    msg "test: default config plus early data minus middlebox compatibility mode"
+    make test
+    msg "ssl-opt.sh (TLS 1.3 no compatibility mode)"
+    tests/ssl-opt.sh
+}
+
+component_test_full_minus_session_tickets () {
+    msg "build: full config without session tickets"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_SSL_SESSION_TICKETS
+    scripts/config.py unset MBEDTLS_SSL_EARLY_DATA
+    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+    msg "test: full config without session tickets"
+    make test
+    msg "ssl-opt.sh (full config without session tickets)"
+    tests/ssl-opt.sh
+}
diff --git a/tests/scripts/components-configuration-x509.sh b/tests/scripts/components-configuration-x509.sh
new file mode 100644
index 0000000..e8ef283
--- /dev/null
+++ b/tests/scripts/components-configuration-x509.sh
@@ -0,0 +1,35 @@
+# components-configuration-x509.sh
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+# This file contains test components that are executed by all.sh
+
+################################################################
+#### Configuration Testing - X509
+################################################################
+
+component_test_no_x509_info () {
+    msg "build: full + MBEDTLS_X509_REMOVE_INFO" # ~ 10s
+    scripts/config.pl full
+    scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
+    scripts/config.pl set MBEDTLS_X509_REMOVE_INFO
+    make CFLAGS='-Werror -O2'
+
+    msg "test: full + MBEDTLS_X509_REMOVE_INFO" # ~ 10s
+    make test
+
+    msg "test: ssl-opt.sh, full + MBEDTLS_X509_REMOVE_INFO" # ~ 1 min
+    tests/ssl-opt.sh
+}
+
+component_test_sw_inet_pton () {
+    msg "build: default plus MBEDTLS_TEST_SW_INET_PTON"
+
+    # MBEDTLS_TEST_HOOKS required for x509_crt_parse_cn_inet_pton
+    scripts/config.py set MBEDTLS_TEST_HOOKS
+    make CFLAGS="-DMBEDTLS_TEST_SW_INET_PTON"
+
+    msg "test: default plus MBEDTLS_TEST_SW_INET_PTON"
+    make test
+}
diff --git a/tests/scripts/components-configuration.sh b/tests/scripts/components-configuration.sh
new file mode 100644
index 0000000..3a75c4c
--- /dev/null
+++ b/tests/scripts/components-configuration.sh
@@ -0,0 +1,397 @@
+# components-configuration.sh
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+# This file contains test components that are executed by all.sh
+
+################################################################
+#### Configuration Testing
+################################################################
+
+component_test_default_out_of_box () {
+    msg "build: make, default config (out-of-box)" # ~1min
+    make
+    # Disable fancy stuff
+    unset MBEDTLS_TEST_OUTCOME_FILE
+
+    msg "test: main suites make, default config (out-of-box)" # ~10s
+    make test
+
+    msg "selftest: make, default config (out-of-box)" # ~10s
+    programs/test/selftest
+
+    msg "program demos: make, default config (out-of-box)" # ~10s
+    tests/scripts/run_demos.py
+}
+
+component_test_default_cmake_gcc_asan () {
+    msg "build: cmake, gcc, ASan" # ~ 1 min 50s
+    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: main suites (inc. selftests) (ASan build)" # ~ 50s
+    make test
+
+    msg "program demos (ASan build)" # ~10s
+    tests/scripts/run_demos.py
+
+    msg "test: selftest (ASan build)" # ~ 10s
+    programs/test/selftest
+
+    msg "test: metatests (GCC, ASan build)"
+    tests/scripts/run-metatests.sh any asan poison
+
+    msg "test: ssl-opt.sh (ASan build)" # ~ 1 min
+    tests/ssl-opt.sh
+
+    msg "test: compat.sh (ASan build)" # ~ 6 min
+    tests/compat.sh
+
+    msg "test: context-info.sh (ASan build)" # ~ 15 sec
+    tests/context-info.sh
+}
+
+component_test_default_cmake_gcc_asan_new_bignum () {
+    msg "build: cmake, gcc, ASan" # ~ 1 min 50s
+    scripts/config.py set MBEDTLS_ECP_WITH_MPI_UINT
+    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: main suites (inc. selftests) (ASan build)" # ~ 50s
+    make test
+
+    msg "test: selftest (ASan build)" # ~ 10s
+    programs/test/selftest
+
+    msg "test: ssl-opt.sh (ASan build)" # ~ 1 min
+    tests/ssl-opt.sh
+
+    msg "test: compat.sh (ASan build)" # ~ 6 min
+    tests/compat.sh
+
+    msg "test: context-info.sh (ASan build)" # ~ 15 sec
+    tests/context-info.sh
+}
+
+component_test_full_cmake_gcc_asan () {
+    msg "build: full config, cmake, gcc, ASan"
+    scripts/config.py full
+    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: main suites (inc. selftests) (full config, ASan build)"
+    make test
+
+    msg "test: selftest (full config, ASan build)" # ~ 10s
+    programs/test/selftest
+
+    msg "test: ssl-opt.sh (full config, ASan build)"
+    tests/ssl-opt.sh
+
+    # Note: the next two invocations cover all compat.sh test cases.
+    # We should use the same here and in basic-build-test.sh.
+    msg "test: compat.sh: default version (full config, ASan build)"
+    tests/compat.sh -e 'ARIA\|CHACHA'
+
+    msg "test: compat.sh: next: ARIA, Chacha (full config, ASan build)"
+    env OPENSSL="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA'
+
+    msg "test: context-info.sh (full config, ASan build)" # ~ 15 sec
+    tests/context-info.sh
+}
+
+component_test_full_cmake_gcc_asan_new_bignum () {
+    msg "build: full config, cmake, gcc, ASan"
+    scripts/config.py full
+    scripts/config.py set MBEDTLS_ECP_WITH_MPI_UINT
+    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: main suites (inc. selftests) (full config, new bignum, ASan)"
+    make test
+
+    msg "test: selftest (full config, new bignum, ASan)" # ~ 10s
+    programs/test/selftest
+
+    msg "test: ssl-opt.sh (full config, new bignum, ASan)"
+    tests/ssl-opt.sh
+
+    # Note: the next two invocations cover all compat.sh test cases.
+    # We should use the same here and in basic-build-test.sh.
+    msg "test: compat.sh: default version (full config, new bignum, ASan)"
+    tests/compat.sh -e 'ARIA\|CHACHA'
+
+    msg "test: compat.sh: next: ARIA, Chacha (full config, new bignum, ASan)"
+    env OPENSSL="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA'
+
+    msg "test: context-info.sh (full config, new bignum, ASan)" # ~ 15 sec
+    tests/context-info.sh
+}
+
+component_test_ref_configs () {
+    msg "test/build: ref-configs (ASan build)" # ~ 6 min 20s
+    # test-ref-configs works by overwriting mbedtls_config.h; this makes cmake
+    # want to re-generate generated files that depend on it, quite correctly.
+    # However this doesn't work as the generation script expects a specific
+    # format for mbedtls_config.h, which the other files don't follow. Also,
+    # cmake can't know this, but re-generation is actually not necessary as
+    # the generated files only depend on the list of available options, not
+    # whether they're on or off. So, disable cmake's (over-sensitive here)
+    # dependency resolution for generated files and just rely on them being
+    # present (thanks to pre_generate_files) by turning GEN_FILES off.
+    CC=$ASAN_CC cmake -D GEN_FILES=Off -D CMAKE_BUILD_TYPE:String=Asan .
+    tests/scripts/test-ref-configs.pl
+}
+
+component_test_full_cmake_clang () {
+    msg "build: cmake, full config, clang" # ~ 50s
+    scripts/config.py full
+    CC=clang CXX=clang cmake -D CMAKE_BUILD_TYPE:String=Release -D ENABLE_TESTING=On -D TEST_CPP=1 .
+    make
+
+    msg "test: main suites (full config, clang)" # ~ 5s
+    make test
+
+    msg "test: cpp_dummy_build (full config, clang)" # ~ 1s
+    programs/test/cpp_dummy_build
+
+    msg "test: metatests (clang)"
+    tests/scripts/run-metatests.sh any pthread
+
+    msg "program demos (full config, clang)" # ~10s
+    tests/scripts/run_demos.py
+
+    msg "test: psa_constant_names (full config, clang)" # ~ 1s
+    tests/scripts/test_psa_constant_names.py
+
+    msg "test: ssl-opt.sh default, ECJPAKE, SSL async (full config)" # ~ 1s
+    tests/ssl-opt.sh -f 'Default\|ECJPAKE\|SSL async private'
+}
+
+component_test_default_no_deprecated () {
+    # Test that removing the deprecated features from the default
+    # configuration leaves something consistent.
+    msg "build: make, default + MBEDTLS_DEPRECATED_REMOVED" # ~ 30s
+    scripts/config.py set MBEDTLS_DEPRECATED_REMOVED
+    make CFLAGS='-O -Werror -Wall -Wextra'
+
+    msg "test: make, default + MBEDTLS_DEPRECATED_REMOVED" # ~ 5s
+    make test
+}
+
+component_test_full_no_deprecated () {
+    msg "build: make, full_no_deprecated config" # ~ 30s
+    scripts/config.py full_no_deprecated
+    make CFLAGS='-O -Werror -Wall -Wextra'
+
+    msg "test: make, full_no_deprecated config" # ~ 5s
+    make test
+
+    msg "test: ensure that X509 has no direct dependency on BIGNUM_C"
+    not grep mbedtls_mpi library/libmbedx509.a
+}
+
+component_test_full_no_deprecated_deprecated_warning () {
+    # Test that there is nothing deprecated in "full_no_deprecated".
+    # A deprecated feature would trigger a warning (made fatal) from
+    # MBEDTLS_DEPRECATED_WARNING.
+    msg "build: make, full_no_deprecated config, MBEDTLS_DEPRECATED_WARNING" # ~ 30s
+    scripts/config.py full_no_deprecated
+    scripts/config.py unset MBEDTLS_DEPRECATED_REMOVED
+    scripts/config.py set MBEDTLS_DEPRECATED_WARNING
+    make CFLAGS='-O -Werror -Wall -Wextra'
+
+    msg "test: make, full_no_deprecated config, MBEDTLS_DEPRECATED_WARNING" # ~ 5s
+    make test
+}
+
+component_test_full_deprecated_warning () {
+    # Test that when MBEDTLS_DEPRECATED_WARNING is enabled, the build passes
+    # with only certain whitelisted types of warnings.
+    msg "build: make, full config + MBEDTLS_DEPRECATED_WARNING, expect warnings" # ~ 30s
+    scripts/config.py full
+    scripts/config.py set MBEDTLS_DEPRECATED_WARNING
+    # Expect warnings from '#warning' directives in check_config.h.
+    # Note that gcc is required to allow the use of -Wno-error=cpp, which allows us to
+    # display #warning messages without them being treated as errors.
+    make CC=gcc CFLAGS='-O -Werror -Wall -Wextra -Wno-error=cpp' lib programs
+
+    msg "build: make tests, full config + MBEDTLS_DEPRECATED_WARNING, expect warnings" # ~ 30s
+    # Set MBEDTLS_TEST_DEPRECATED to enable tests for deprecated features.
+    # By default those are disabled when MBEDTLS_DEPRECATED_WARNING is set.
+    # Expect warnings from '#warning' directives in check_config.h and
+    # from the use of deprecated functions in test suites.
+    make CC=gcc CFLAGS='-O -Werror -Wall -Wextra -Wno-error=deprecated-declarations -Wno-error=cpp -DMBEDTLS_TEST_DEPRECATED' tests
+
+    msg "test: full config + MBEDTLS_TEST_DEPRECATED" # ~ 30s
+    make test
+
+    msg "program demos: full config + MBEDTLS_TEST_DEPRECATED" # ~10s
+    tests/scripts/run_demos.py
+}
+
+component_build_baremetal () {
+  msg "build: make, baremetal config"
+  scripts/config.py baremetal
+  make CFLAGS="-O1 -Werror -I$PWD/tests/include/baremetal-override/"
+}
+
+support_build_baremetal () {
+    # Older Glibc versions include time.h from other headers such as stdlib.h,
+    # which makes the no-time.h-in-baremetal check fail. Ubuntu 16.04 has this
+    # problem, Ubuntu 18.04 is ok.
+    ! grep -q -F time.h /usr/include/x86_64-linux-gnu/sys/types.h
+}
+
+component_test_no_psa_crypto_full_cmake_asan () {
+    # full minus MBEDTLS_PSA_CRYPTO_C: run the same set of tests as basic-build-test.sh
+    msg "build: cmake, full config minus PSA crypto, ASan"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_C
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_CLIENT
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
+    scripts/config.py unset MBEDTLS_PSA_ITS_FILE_C
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C
+    scripts/config.py unset MBEDTLS_LMS_C
+    scripts/config.py unset MBEDTLS_LMS_PRIVATE
+    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
+    make
+
+    msg "test: main suites (full minus PSA crypto)"
+    make test
+
+    # Note: ssl-opt.sh has some test cases that depend on
+    # MBEDTLS_ECP_RESTARTABLE && !MBEDTLS_USE_PSA_CRYPTO
+    # This is the only component where those tests are not skipped.
+    msg "test: ssl-opt.sh (full minus PSA crypto)"
+    tests/ssl-opt.sh
+
+    # Note: the next two invocations cover all compat.sh test cases.
+    # We should use the same here and in basic-build-test.sh.
+    msg "test: compat.sh: default version (full minus PSA crypto)"
+    tests/compat.sh -e 'ARIA\|CHACHA'
+
+    msg "test: compat.sh: next: ARIA, Chacha (full minus PSA crypto)"
+    env OPENSSL="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA'
+}
+
+component_build_tfm () {
+    # Check that the TF-M configuration can build cleanly with various
+    # warning flags enabled. We don't build or run tests, since the
+    # TF-M configuration needs a TF-M platform. A tweaked version of
+    # the configuration that works on mainstream platforms is in
+    # configs/config-tfm.h, tested via test-ref-configs.pl.
+    cp configs/config-tfm.h "$CONFIG_H"
+
+    msg "build: TF-M config, clang, armv7-m thumb2"
+    make lib CC="clang" CFLAGS="--target=arm-linux-gnueabihf -march=armv7-m -mthumb -Os -std=c99 -Werror -Wall -Wextra -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow -Wvla -Wformat=2 -Wno-format-nonliteral -Wshadow -Wasm-operand-widths -Wunused -I../tests/include/spe"
+
+    msg "build: TF-M config, gcc native build"
+    make clean
+    make lib CC="gcc" CFLAGS="-Os -std=c99 -Werror -Wall -Wextra -Wwrite-strings -Wpointer-arith -Wshadow -Wvla -Wformat=2 -Wno-format-nonliteral -Wshadow -Wformat-signedness -Wlogical-op -I../tests/include/spe"
+}
+
+component_test_no_platform () {
+    # Full configuration build, without platform support, file IO and net sockets.
+    # This should catch missing mbedtls_printf definitions, and by disabling file
+    # IO, it should catch missing '#include <stdio.h>'
+    msg "build: full config except platform/fsio/net, make, gcc, C99" # ~ 30s
+    scripts/config.py full_no_platform
+    scripts/config.py unset MBEDTLS_PLATFORM_C
+    scripts/config.py unset MBEDTLS_NET_C
+    scripts/config.py unset MBEDTLS_FS_IO
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C
+    scripts/config.py unset MBEDTLS_PSA_ITS_FILE_C
+    scripts/config.py unset MBEDTLS_ENTROPY_NV_SEED
+    # Note, _DEFAULT_SOURCE needs to be defined for platforms using glibc version >2.19,
+    # to re-enable platform integration features otherwise disabled in C99 builds
+    make CC=gcc CFLAGS='-Werror -Wall -Wextra -std=c99 -pedantic -Os -D_DEFAULT_SOURCE' lib programs
+    make CC=gcc CFLAGS='-Werror -Wall -Wextra -Os' test
+}
+
+component_test_memory_buffer_allocator_backtrace () {
+    msg "build: default config with memory buffer allocator and backtrace enabled"
+    scripts/config.py set MBEDTLS_MEMORY_BUFFER_ALLOC_C
+    scripts/config.py set MBEDTLS_PLATFORM_MEMORY
+    scripts/config.py set MBEDTLS_MEMORY_BACKTRACE
+    scripts/config.py set MBEDTLS_MEMORY_DEBUG
+    cmake -DCMAKE_BUILD_TYPE:String=Release .
+    make
+
+    msg "test: MBEDTLS_MEMORY_BUFFER_ALLOC_C and MBEDTLS_MEMORY_BACKTRACE"
+    make test
+}
+
+component_test_memory_buffer_allocator () {
+    msg "build: default config with memory buffer allocator"
+    scripts/config.py set MBEDTLS_MEMORY_BUFFER_ALLOC_C
+    scripts/config.py set MBEDTLS_PLATFORM_MEMORY
+    cmake -DCMAKE_BUILD_TYPE:String=Release .
+    make
+
+    msg "test: MBEDTLS_MEMORY_BUFFER_ALLOC_C"
+    make test
+
+    msg "test: ssl-opt.sh, MBEDTLS_MEMORY_BUFFER_ALLOC_C"
+    # MBEDTLS_MEMORY_BUFFER_ALLOC is slow. Skip tests that tend to time out.
+    tests/ssl-opt.sh -e '^DTLS proxy'
+}
+
+component_test_malloc_0_null () {
+    msg "build: malloc(0) returns NULL (ASan+UBSan build)"
+    scripts/config.py full
+    make CC=$ASAN_CC CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"$PWD/tests/configs/user-config-malloc-0-null.h\"' $ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
+
+    msg "test: malloc(0) returns NULL (ASan+UBSan build)"
+    make test
+
+    msg "selftest: malloc(0) returns NULL (ASan+UBSan build)"
+    # Just the calloc selftest. "make test" ran the others as part of the
+    # test suites.
+    programs/test/selftest calloc
+
+    msg "test ssl-opt.sh: malloc(0) returns NULL (ASan+UBSan build)"
+    # Run a subset of the tests. The choice is a balance between coverage
+    # and time (including time indirectly wasted due to flaky tests).
+    # The current choice is to skip tests whose description includes
+    # "proxy", which is an approximation of skipping tests that use the
+    # UDP proxy, which tend to be slower and flakier.
+    tests/ssl-opt.sh -e 'proxy'
+}
+
+component_build_mbedtls_config_file () {
+    msg "build: make with MBEDTLS_CONFIG_FILE" # ~40s
+    scripts/config.py -w full_config.h full
+    echo '#error "MBEDTLS_CONFIG_FILE is not working"' >"$CONFIG_H"
+    make CFLAGS="-I '$PWD' -DMBEDTLS_CONFIG_FILE='\"full_config.h\"'"
+    # Make sure this feature is enabled. We'll disable it in the next phase.
+    programs/test/query_compile_time_config MBEDTLS_NIST_KW_C
+    make clean
+
+    msg "build: make with MBEDTLS_CONFIG_FILE + MBEDTLS_USER_CONFIG_FILE"
+    # In the user config, disable one feature (for simplicity, pick a feature
+    # that nothing else depends on).
+    echo '#undef MBEDTLS_NIST_KW_C' >user_config.h
+    make CFLAGS="-I '$PWD' -DMBEDTLS_CONFIG_FILE='\"full_config.h\"' -DMBEDTLS_USER_CONFIG_FILE='\"user_config.h\"'"
+    not programs/test/query_compile_time_config MBEDTLS_NIST_KW_C
+
+    rm -f user_config.h full_config.h
+}
+
+component_test_no_strings () {
+    msg "build: no strings" # ~10s
+    scripts/config.py full
+    # Disable options that activate a large amount of string constants.
+    scripts/config.py unset MBEDTLS_DEBUG_C
+    scripts/config.py unset MBEDTLS_ERROR_C
+    scripts/config.py set MBEDTLS_ERROR_STRERROR_DUMMY
+    scripts/config.py unset MBEDTLS_VERSION_FEATURES
+    make CFLAGS='-Werror -Os'
+
+    msg "test: no strings" # ~ 10s
+    make test
+}
diff --git a/tests/scripts/components-platform.sh b/tests/scripts/components-platform.sh
new file mode 100644
index 0000000..b104428
--- /dev/null
+++ b/tests/scripts/components-platform.sh
@@ -0,0 +1,514 @@
+# components-platform.sh
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+# This file contains test components that are executed by all.sh
+
+################################################################
+#### Platform Testing
+################################################################
+
+support_test_aesni () {
+    # Check that gcc targets x86_64 (we can build AESNI), and check for
+    # AESNI support on the host (we can run AESNI).
+    #
+    # The name of this function is possibly slightly misleading, but needs to align
+    # with the name of the corresponding test, component_test_aesni.
+    #
+    # In principle 32-bit x86 can support AESNI, but our implementation does not
+    # support 32-bit x86, so we check for x86-64.
+    # We can only grep /proc/cpuinfo on Linux, so this also checks for Linux
+    (gcc -v 2>&1 | grep Target | grep -q x86_64) &&
+        [[ "$HOSTTYPE" == "x86_64" && "$OSTYPE" == "linux-gnu" ]] &&
+        (lscpu | grep -qw aes)
+}
+
+component_test_aesni () { # ~ 60s
+    # This tests the two AESNI implementations (intrinsics and assembly), and also the plain C
+    # fallback. It also tests the logic that is used to select which implementation(s) to build.
+    #
+    # This test does not require the host to have support for AESNI (if it doesn't, the run-time
+    # AESNI detection will fallback to the plain C implementation, so the tests will instead
+    # exercise the plain C impl).
+
+    msg "build: default config with different AES implementations"
+    scripts/config.py set MBEDTLS_AESNI_C
+    scripts/config.py unset MBEDTLS_AES_USE_HARDWARE_ONLY
+    scripts/config.py set MBEDTLS_HAVE_ASM
+
+    # test the intrinsics implementation
+    msg "AES tests, test intrinsics"
+    make clean
+    make CC=gcc CFLAGS='-Werror -Wall -Wextra -mpclmul -msse2 -maes'
+    # check that we built intrinsics - this should be used by default when supported by the compiler
+    ./programs/test/selftest aes | grep "AESNI code" | grep -q "intrinsics"
+
+    # test the asm implementation
+    msg "AES tests, test assembly"
+    make clean
+    make CC=gcc CFLAGS='-Werror -Wall -Wextra -mno-pclmul -mno-sse2 -mno-aes'
+    # check that we built assembly - this should be built if the compiler does not support intrinsics
+    ./programs/test/selftest aes | grep "AESNI code" | grep -q "assembly"
+
+    # test the plain C implementation
+    scripts/config.py unset MBEDTLS_AESNI_C
+    scripts/config.py unset MBEDTLS_AES_USE_HARDWARE_ONLY
+    msg "AES tests, plain C"
+    make clean
+    make CC=gcc CFLAGS='-O2 -Werror'
+    # check that there is no AESNI code present
+    ./programs/test/selftest aes | not grep -q "AESNI code"
+    not grep -q "AES note: using AESNI" ./programs/test/selftest
+    grep -q "AES note: built-in implementation." ./programs/test/selftest
+
+    # test the intrinsics implementation
+    scripts/config.py set MBEDTLS_AESNI_C
+    scripts/config.py set MBEDTLS_AES_USE_HARDWARE_ONLY
+    msg "AES tests, test AESNI only"
+    make clean
+    make CC=gcc CFLAGS='-Werror -Wall -Wextra -mpclmul -msse2 -maes'
+    ./programs/test/selftest aes | grep -q "AES note: using AESNI"
+    ./programs/test/selftest aes | not grep -q "AES note: built-in implementation."
+    grep -q "AES note: using AESNI" ./programs/test/selftest
+    not grep -q "AES note: built-in implementation." ./programs/test/selftest
+}
+
+support_test_aesni_m32 () {
+    support_test_m32_no_asm && (lscpu | grep -qw aes)
+}
+
+component_test_aesni_m32 () { # ~ 60s
+    # This tests are duplicated from component_test_aesni for i386 target
+    #
+    # AESNI intrinsic code supports i386 and assembly code does not support it.
+
+    msg "build: default config with different AES implementations"
+    scripts/config.py set MBEDTLS_AESNI_C
+    scripts/config.py set MBEDTLS_PADLOCK_C
+    scripts/config.py unset MBEDTLS_AES_USE_HARDWARE_ONLY
+    scripts/config.py set MBEDTLS_HAVE_ASM
+
+    # test the intrinsics implementation with gcc
+    msg "AES tests, test intrinsics (gcc)"
+    make clean
+    make CC=gcc CFLAGS='-m32 -Werror -Wall -Wextra' LDFLAGS='-m32'
+    # check that we built intrinsics - this should be used by default when supported by the compiler
+    ./programs/test/selftest aes | grep "AESNI code" | grep -q "intrinsics"
+    grep -q "AES note: using AESNI" ./programs/test/selftest
+    grep -q "AES note: built-in implementation." ./programs/test/selftest
+    grep -q "AES note: using VIA Padlock" ./programs/test/selftest
+    grep -q mbedtls_aesni_has_support ./programs/test/selftest
+
+    scripts/config.py set MBEDTLS_AESNI_C
+    scripts/config.py unset MBEDTLS_PADLOCK_C
+    scripts/config.py set MBEDTLS_AES_USE_HARDWARE_ONLY
+    msg "AES tests, test AESNI only"
+    make clean
+    make CC=gcc CFLAGS='-m32 -Werror -Wall -Wextra -mpclmul -msse2 -maes' LDFLAGS='-m32'
+    ./programs/test/selftest aes | grep -q "AES note: using AESNI"
+    ./programs/test/selftest aes | not grep -q "AES note: built-in implementation."
+    grep -q "AES note: using AESNI" ./programs/test/selftest
+    not grep -q "AES note: built-in implementation." ./programs/test/selftest
+    not grep -q "AES note: using VIA Padlock" ./programs/test/selftest
+    not grep -q mbedtls_aesni_has_support ./programs/test/selftest
+}
+
+support_test_aesni_m32_clang () {
+    # clang >= 4 is required to build with target attributes
+    support_test_aesni_m32 && [[ $(clang_version) -ge 4 ]]
+}
+
+component_test_aesni_m32_clang () {
+
+    scripts/config.py set MBEDTLS_AESNI_C
+    scripts/config.py set MBEDTLS_PADLOCK_C
+    scripts/config.py unset MBEDTLS_AES_USE_HARDWARE_ONLY
+    scripts/config.py set MBEDTLS_HAVE_ASM
+
+    # test the intrinsics implementation with clang
+    msg "AES tests, test intrinsics (clang)"
+    make clean
+    make CC=clang CFLAGS='-m32 -Werror -Wall -Wextra' LDFLAGS='-m32'
+    # check that we built intrinsics - this should be used by default when supported by the compiler
+    ./programs/test/selftest aes | grep "AESNI code" | grep -q "intrinsics"
+    grep -q "AES note: using AESNI" ./programs/test/selftest
+    grep -q "AES note: built-in implementation." ./programs/test/selftest
+    grep -q "AES note: using VIA Padlock" ./programs/test/selftest
+    grep -q mbedtls_aesni_has_support ./programs/test/selftest
+}
+
+support_build_aes_armce () {
+    # clang >= 11 is required to build with AES extensions
+    [[ $(clang_version) -ge 11 ]]
+}
+
+component_build_aes_armce () {
+    # Test variations of AES with Armv8 crypto extensions
+    scripts/config.py set MBEDTLS_AESCE_C
+    scripts/config.py set MBEDTLS_AES_USE_HARDWARE_ONLY
+
+    msg "MBEDTLS_AES_USE_HARDWARE_ONLY, clang, aarch64"
+    make -B library/aesce.o CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a+crypto"
+
+    msg "MBEDTLS_AES_USE_HARDWARE_ONLY, clang, arm"
+    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a72+crypto -marm"
+
+    msg "MBEDTLS_AES_USE_HARDWARE_ONLY, clang, thumb"
+    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a32+crypto -mthumb"
+
+    scripts/config.py unset MBEDTLS_AES_USE_HARDWARE_ONLY
+
+    msg "no MBEDTLS_AES_USE_HARDWARE_ONLY, clang, aarch64"
+    make -B library/aesce.o CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a+crypto"
+
+    msg "no MBEDTLS_AES_USE_HARDWARE_ONLY, clang, arm"
+    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a72+crypto -marm"
+
+    msg "no MBEDTLS_AES_USE_HARDWARE_ONLY, clang, thumb"
+    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a32+crypto -mthumb"
+
+    # test for presence of AES instructions
+    scripts/config.py set MBEDTLS_AES_USE_HARDWARE_ONLY
+    msg "clang, test A32 crypto instructions built"
+    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a72+crypto -marm -S"
+    grep -E 'aes[0-9a-z]+.[0-9]\s*[qv]' library/aesce.o
+    msg "clang, test T32 crypto instructions built"
+    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a32+crypto -mthumb -S"
+    grep -E 'aes[0-9a-z]+.[0-9]\s*[qv]' library/aesce.o
+    msg "clang, test aarch64 crypto instructions built"
+    make -B library/aesce.o CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a -S"
+    grep -E 'aes[a-z]+\s*[qv]' library/aesce.o
+
+    # test for absence of AES instructions
+    scripts/config.py unset MBEDTLS_AES_USE_HARDWARE_ONLY
+    scripts/config.py unset MBEDTLS_AESCE_C
+    msg "clang, test A32 crypto instructions not built"
+    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a72+crypto -marm -S"
+    not grep -E 'aes[0-9a-z]+.[0-9]\s*[qv]' library/aesce.o
+    msg "clang, test T32 crypto instructions not built"
+    make -B library/aesce.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a32+crypto -mthumb -S"
+    not grep -E 'aes[0-9a-z]+.[0-9]\s*[qv]' library/aesce.o
+    msg "clang, test aarch64 crypto instructions not built"
+    make -B library/aesce.o CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a -S"
+    not grep -E 'aes[a-z]+\s*[qv]' library/aesce.o
+}
+
+support_build_sha_armce () {
+    # clang >= 4 is required to build with SHA extensions
+    [[ $(clang_version) -ge 4 ]]
+}
+
+component_build_sha_armce () {
+    scripts/config.py unset MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
+
+
+    # Test variations of SHA256 Armv8 crypto extensions
+    scripts/config.py set MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
+        msg "MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY clang, aarch64"
+        make -B library/sha256.o CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a"
+        msg "MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY clang, arm"
+        make -B library/sha256.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a72+crypto -marm"
+    scripts/config.py unset MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
+
+
+    # test the deprecated form of the config option
+    scripts/config.py set MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
+        msg "MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY clang, thumb"
+        make -B library/sha256.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a32+crypto -mthumb"
+    scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
+
+    scripts/config.py set MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
+        msg "MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT clang, aarch64"
+        make -B library/sha256.o CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a"
+    scripts/config.py unset MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
+
+
+    # test the deprecated form of the config option
+    scripts/config.py set MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
+        msg "MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT clang, arm"
+        make -B library/sha256.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a72+crypto -marm -std=c99"
+        msg "MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT clang, thumb"
+        make -B library/sha256.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a32+crypto -mthumb"
+    scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
+
+
+    # examine the disassembly for presence of SHA instructions
+    for opt in MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT; do
+        scripts/config.py set ${opt}
+            msg "${opt} clang, test A32 crypto instructions built"
+            make -B library/sha256.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a72+crypto -marm -S"
+            grep -E 'sha256[a-z0-9]+.32\s+[qv]' library/sha256.o
+
+            msg "${opt} clang, test T32 crypto instructions built"
+            make -B library/sha256.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a32+crypto -mthumb -S"
+            grep -E 'sha256[a-z0-9]+.32\s+[qv]' library/sha256.o
+
+            msg "${opt} clang, test aarch64 crypto instructions built"
+            make -B library/sha256.o CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a -S"
+            grep -E 'sha256[a-z0-9]+\s+[qv]' library/sha256.o
+        scripts/config.py unset ${opt}
+    done
+
+
+    # examine the disassembly for absence of SHA instructions
+    msg "clang, test A32 crypto instructions not built"
+    make -B library/sha256.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a72+crypto -marm -S"
+    not grep -E 'sha256[a-z0-9]+.32\s+[qv]' library/sha256.o
+
+    msg "clang, test T32 crypto instructions not built"
+    make -B library/sha256.o CC=clang CFLAGS="--target=arm-linux-gnueabihf -mcpu=cortex-a32+crypto -mthumb -S"
+    not grep -E 'sha256[a-z0-9]+.32\s+[qv]' library/sha256.o
+
+    msg "clang, test aarch64 crypto instructions not built"
+    make -B library/sha256.o CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a -S"
+    not grep -E 'sha256[a-z0-9]+\s+[qv]' library/sha256.o
+}
+
+component_test_m32_no_asm () {
+    # Build without assembly, so as to use portable C code (in a 32-bit
+    # build) and not the i386-specific inline assembly.
+    #
+    # Note that we require gcc, because clang Asan builds fail to link for
+    # this target (cannot find libclang_rt.lsan-i386.a - this is a known clang issue).
+    msg "build: i386, make, gcc, no asm (ASan build)" # ~ 30s
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_HAVE_ASM
+    scripts/config.py unset MBEDTLS_PADLOCK_C
+    scripts/config.py unset MBEDTLS_AESNI_C # AESNI for 32-bit is tested in test_aesni_m32
+    make CC=gcc CFLAGS="$ASAN_CFLAGS -m32" LDFLAGS="-m32 $ASAN_CFLAGS"
+
+    msg "test: i386, make, gcc, no asm (ASan build)"
+    make test
+}
+
+support_test_m32_no_asm () {
+    case $(uname -m) in
+        amd64|x86_64) true;;
+        *) false;;
+    esac
+}
+
+component_test_m32_o2 () {
+    # Build with optimization, to use the i386 specific inline assembly
+    # and go faster for tests.
+    msg "build: i386, make, gcc -O2 (ASan build)" # ~ 30s
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_AESNI_C # AESNI for 32-bit is tested in test_aesni_m32
+    make CC=gcc CFLAGS="$ASAN_CFLAGS -m32" LDFLAGS="-m32 $ASAN_CFLAGS"
+
+    msg "test: i386, make, gcc -O2 (ASan build)"
+    make test
+
+    msg "test ssl-opt.sh, i386, make, gcc-O2"
+    tests/ssl-opt.sh
+}
+
+support_test_m32_o2 () {
+    support_test_m32_no_asm "$@"
+}
+
+component_test_m32_everest () {
+    msg "build: i386, Everest ECDH context (ASan build)" # ~ 6 min
+    scripts/config.py set MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED
+    scripts/config.py unset MBEDTLS_AESNI_C # AESNI for 32-bit is tested in test_aesni_m32
+    make CC=gcc CFLAGS="$ASAN_CFLAGS -m32" LDFLAGS="-m32 $ASAN_CFLAGS"
+
+    msg "test: i386, Everest ECDH context - main suites (inc. selftests) (ASan build)" # ~ 50s
+    make test
+
+    msg "test: i386, Everest ECDH context - ECDH-related part of ssl-opt.sh (ASan build)" # ~ 5s
+    tests/ssl-opt.sh -f ECDH
+
+    msg "test: i386, Everest ECDH context - compat.sh with some ECDH ciphersuites (ASan build)" # ~ 3 min
+    # Exclude some symmetric ciphers that are redundant here to gain time.
+    tests/compat.sh -f ECDH -V NO -e 'ARIA\|CAMELLIA\|CHACHA'
+}
+
+support_test_m32_everest () {
+    support_test_m32_no_asm "$@"
+}
+
+component_test_mx32 () {
+    msg "build: 64-bit ILP32, make, gcc" # ~ 30s
+    scripts/config.py full
+    make CC=gcc CFLAGS='-O2 -Werror -Wall -Wextra -mx32' LDFLAGS='-mx32'
+
+    msg "test: 64-bit ILP32, make, gcc"
+    make test
+}
+
+support_test_mx32 () {
+    case $(uname -m) in
+        amd64|x86_64) true;;
+        *) false;;
+    esac
+}
+
+component_build_arm_none_eabi_gcc () {
+    msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -O1, baremetal+debug" # ~ 10s
+    scripts/config.py baremetal
+    make CC="${ARM_NONE_EABI_GCC_PREFIX}gcc" AR="${ARM_NONE_EABI_GCC_PREFIX}ar" LD="${ARM_NONE_EABI_GCC_PREFIX}ld" CFLAGS='-std=c99 -Werror -Wall -Wextra -O1' lib
+
+    msg "size: ${ARM_NONE_EABI_GCC_PREFIX}gcc -O1, baremetal+debug"
+    ${ARM_NONE_EABI_GCC_PREFIX}size -t library/*.o
+}
+
+component_build_arm_linux_gnueabi_gcc_arm5vte () {
+    msg "build: ${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc -march=arm5vte, baremetal+debug" # ~ 10s
+    scripts/config.py baremetal
+    # Build for a target platform that's close to what Debian uses
+    # for its "armel" distribution (https://wiki.debian.org/ArmEabiPort).
+    # See https://github.com/Mbed-TLS/mbedtls/pull/2169 and comments.
+    # Build everything including programs, see for example
+    # https://github.com/Mbed-TLS/mbedtls/pull/3449#issuecomment-675313720
+    make CC="${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc" AR="${ARM_LINUX_GNUEABI_GCC_PREFIX}ar" CFLAGS='-Werror -Wall -Wextra -march=armv5te -O1' LDFLAGS='-march=armv5te'
+
+    msg "size: ${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc -march=armv5te -O1, baremetal+debug"
+    ${ARM_LINUX_GNUEABI_GCC_PREFIX}size -t library/*.o
+}
+
+support_build_arm_linux_gnueabi_gcc_arm5vte () {
+    type ${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc >/dev/null 2>&1
+}
+
+component_build_arm_none_eabi_gcc_arm5vte () {
+    msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -march=arm5vte, baremetal+debug" # ~ 10s
+    scripts/config.py baremetal
+    # This is an imperfect substitute for
+    # component_build_arm_linux_gnueabi_gcc_arm5vte
+    # in case the gcc-arm-linux-gnueabi toolchain is not available
+    make CC="${ARM_NONE_EABI_GCC_PREFIX}gcc" AR="${ARM_NONE_EABI_GCC_PREFIX}ar" CFLAGS='-std=c99 -Werror -Wall -Wextra -march=armv5te -O1' LDFLAGS='-march=armv5te' SHELL='sh -x' lib
+
+    msg "size: ${ARM_NONE_EABI_GCC_PREFIX}gcc -march=armv5te -O1, baremetal+debug"
+    ${ARM_NONE_EABI_GCC_PREFIX}size -t library/*.o
+}
+
+component_build_arm_none_eabi_gcc_m0plus () {
+    msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -mthumb -mcpu=cortex-m0plus, baremetal_size" # ~ 10s
+    scripts/config.py baremetal_size
+    make CC="${ARM_NONE_EABI_GCC_PREFIX}gcc" AR="${ARM_NONE_EABI_GCC_PREFIX}ar" LD="${ARM_NONE_EABI_GCC_PREFIX}ld" CFLAGS='-std=c99 -Werror -Wall -Wextra -mthumb -mcpu=cortex-m0plus -Os' lib
+
+    msg "size: ${ARM_NONE_EABI_GCC_PREFIX}gcc -mthumb -mcpu=cortex-m0plus -Os, baremetal_size"
+    ${ARM_NONE_EABI_GCC_PREFIX}size -t library/*.o
+    for lib in library/*.a; do
+        echo "$lib:"
+        ${ARM_NONE_EABI_GCC_PREFIX}size -t $lib | grep TOTALS
+    done
+}
+
+component_build_arm_none_eabi_gcc_no_udbl_division () {
+    msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -DMBEDTLS_NO_UDBL_DIVISION, make" # ~ 10s
+    scripts/config.py baremetal
+    scripts/config.py set MBEDTLS_NO_UDBL_DIVISION
+    make CC="${ARM_NONE_EABI_GCC_PREFIX}gcc" AR="${ARM_NONE_EABI_GCC_PREFIX}ar" LD="${ARM_NONE_EABI_GCC_PREFIX}ld" CFLAGS='-std=c99 -Werror -Wall -Wextra' lib
+    echo "Checking that software 64-bit division is not required"
+    not grep __aeabi_uldiv library/*.o
+}
+
+component_build_arm_none_eabi_gcc_no_64bit_multiplication () {
+    msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc MBEDTLS_NO_64BIT_MULTIPLICATION, make" # ~ 10s
+    scripts/config.py baremetal
+    scripts/config.py set MBEDTLS_NO_64BIT_MULTIPLICATION
+    make CC="${ARM_NONE_EABI_GCC_PREFIX}gcc" AR="${ARM_NONE_EABI_GCC_PREFIX}ar" LD="${ARM_NONE_EABI_GCC_PREFIX}ld" CFLAGS='-std=c99 -Werror -O1 -march=armv6-m -mthumb' lib
+    echo "Checking that software 64-bit multiplication is not required"
+    not grep __aeabi_lmul library/*.o
+}
+
+component_build_arm_clang_thumb () {
+    # ~ 30s
+
+    scripts/config.py baremetal
+
+    msg "build: clang thumb 2, make"
+    make clean
+    make CC="clang" CFLAGS='-std=c99 -Werror -Os --target=arm-linux-gnueabihf -march=armv7-m -mthumb' lib
+
+    # Some Thumb 1 asm is sensitive to optimisation level, so test both -O0 and -Os
+    msg "build: clang thumb 1 -O0, make"
+    make clean
+    make CC="clang" CFLAGS='-std=c99 -Werror -O0 --target=arm-linux-gnueabihf -mcpu=arm1136j-s -mthumb' lib
+
+    msg "build: clang thumb 1 -Os, make"
+    make clean
+    make CC="clang" CFLAGS='-std=c99 -Werror -Os --target=arm-linux-gnueabihf -mcpu=arm1136j-s -mthumb' lib
+}
+
+component_build_armcc () {
+    msg "build: ARM Compiler 5"
+    scripts/config.py baremetal
+    # armc[56] don't support SHA-512 intrinsics
+    scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
+
+    # older versions of armcc/armclang don't support AESCE_C on 32-bit Arm
+    scripts/config.py unset MBEDTLS_AESCE_C
+
+    # Stop armclang warning about feature detection for A64_CRYPTO.
+    # With this enabled, the library does build correctly under armclang,
+    # but in baremetal builds (as tested here), feature detection is
+    # unavailable, and the user is notified via a #warning. So enabling
+    # this feature would prevent us from building with -Werror on
+    # armclang. Tracked in #7198.
+    scripts/config.py unset MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
+
+    scripts/config.py set MBEDTLS_HAVE_ASM
+
+    make CC="$ARMC5_CC" AR="$ARMC5_AR" WARNING_CFLAGS='--strict --c99' lib
+
+    msg "size: ARM Compiler 5"
+    "$ARMC5_FROMELF" -z library/*.o
+
+    # Compile mostly with -O1 since some Arm inline assembly is disabled for -O0.
+
+    # ARM Compiler 6 - Target ARMv7-A
+    armc6_build_test "-O1 --target=arm-arm-none-eabi -march=armv7-a"
+
+    # ARM Compiler 6 - Target ARMv7-M
+    armc6_build_test "-O1 --target=arm-arm-none-eabi -march=armv7-m"
+
+    # ARM Compiler 6 - Target ARMv7-M+DSP
+    armc6_build_test "-O1 --target=arm-arm-none-eabi -march=armv7-m+dsp"
+
+    # ARM Compiler 6 - Target ARMv8-A - AArch32
+    armc6_build_test "-O1 --target=arm-arm-none-eabi -march=armv8.2-a"
+
+    # ARM Compiler 6 - Target ARMv8-M
+    armc6_build_test "-O1 --target=arm-arm-none-eabi -march=armv8-m.main"
+
+    # ARM Compiler 6 - Target Cortex-M0 - no optimisation
+    armc6_build_test "-O0 --target=arm-arm-none-eabi -mcpu=cortex-m0"
+
+    # ARM Compiler 6 - Target Cortex-M0
+    armc6_build_test "-Os --target=arm-arm-none-eabi -mcpu=cortex-m0"
+
+    # ARM Compiler 6 - Target ARMv8.2-A - AArch64
+    #
+    # Re-enable MBEDTLS_AESCE_C as this should be supported by the version of armclang
+    # that we have in our CI
+    scripts/config.py set MBEDTLS_AESCE_C
+    armc6_build_test "-O1 --target=aarch64-arm-none-eabi -march=armv8.2-a+crypto"
+}
+
+support_build_armcc () {
+    armc5_cc="$ARMC5_BIN_DIR/armcc"
+    armc6_cc="$ARMC6_BIN_DIR/armclang"
+    (check_tools "$armc5_cc" "$armc6_cc" > /dev/null 2>&1)
+}
+
+# For timebeing, no VIA Padlock platform available.
+component_build_aes_via_padlock () {
+
+    msg "AES:VIA PadLock, build with default configuration."
+    scripts/config.py unset MBEDTLS_AESNI_C
+    scripts/config.py set MBEDTLS_PADLOCK_C
+    scripts/config.py unset MBEDTLS_AES_USE_HARDWARE_ONLY
+    make CC=gcc CFLAGS="$ASAN_CFLAGS -m32" LDFLAGS="-m32 $ASAN_CFLAGS"
+    grep -q mbedtls_padlock_has_support ./programs/test/selftest
+
+}
+
+support_build_aes_via_padlock_only () {
+    ( [ "$MBEDTLS_TEST_PLATFORM" == "Linux-x86_64" ] || \
+        [ "$MBEDTLS_TEST_PLATFORM" == "Linux-amd64" ] ) && \
+    [ "`dpkg --print-foreign-architectures`" == "i386" ]
+}
diff --git a/tests/scripts/components-sanitizers.sh b/tests/scripts/components-sanitizers.sh
new file mode 100644
index 0000000..5b79d2b
--- /dev/null
+++ b/tests/scripts/components-sanitizers.sh
@@ -0,0 +1,208 @@
+# components-sanitizers.sh
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+# This file contains test components that are executed by all.sh
+
+################################################################
+#### Sanitizer Testing
+################################################################
+
+skip_suites_without_constant_flow () {
+    # Skip the test suites that don't have any constant-flow annotations.
+    # This will need to be adjusted if we ever start declaring things as
+    # secret from macros or functions inside tests/include or tests/src.
+    SKIP_TEST_SUITES=$(
+        git -C tests/suites grep -L TEST_CF_ 'test_suite_*.function' |
+            sed 's/test_suite_//; s/\.function$//' |
+            tr '\n' ,)
+    export SKIP_TEST_SUITES
+}
+
+skip_all_except_given_suite () {
+    # Skip all but the given test suite
+    SKIP_TEST_SUITES=$(
+        ls -1 tests/suites/test_suite_*.function |
+        grep -v $1.function |
+         sed 's/tests.suites.test_suite_//; s/\.function$//' |
+        tr '\n' ,)
+    export SKIP_TEST_SUITES
+}
+
+component_test_memsan_constant_flow () {
+    # This tests both (1) accesses to undefined memory, and (2) branches or
+    # memory access depending on secret values. To distinguish between those:
+    # - unset MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN - does the failure persist?
+    # - or alternatively, change the build type to MemSanDbg, which enables
+    # origin tracking and nicer stack traces (which are useful for debugging
+    # anyway), and check if the origin was TEST_CF_SECRET() or something else.
+    msg "build: cmake MSan (clang), full config minus MBEDTLS_USE_PSA_CRYPTO with constant flow testing"
+    scripts/config.py full
+    scripts/config.py set MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_AESNI_C # memsan doesn't grok asm
+    CC=clang cmake -D CMAKE_BUILD_TYPE:String=MemSan .
+    make
+
+    msg "test: main suites (full minus MBEDTLS_USE_PSA_CRYPTO, Msan + constant flow)"
+    make test
+}
+
+component_test_memsan_constant_flow_psa () {
+    # This tests both (1) accesses to undefined memory, and (2) branches or
+    # memory access depending on secret values. To distinguish between those:
+    # - unset MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN - does the failure persist?
+    # - or alternatively, change the build type to MemSanDbg, which enables
+    # origin tracking and nicer stack traces (which are useful for debugging
+    # anyway), and check if the origin was TEST_CF_SECRET() or something else.
+    msg "build: cmake MSan (clang), full config with constant flow testing"
+    scripts/config.py full
+    scripts/config.py set MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN
+    scripts/config.py unset MBEDTLS_AESNI_C # memsan doesn't grok asm
+    CC=clang cmake -D CMAKE_BUILD_TYPE:String=MemSan .
+    make
+
+    msg "test: main suites (Msan + constant flow)"
+    make test
+}
+
+component_release_test_valgrind_constant_flow () {
+    # This tests both (1) everything that valgrind's memcheck usually checks
+    # (heap buffer overflows, use of uninitialized memory, use-after-free,
+    # etc.) and (2) branches or memory access depending on secret values,
+    # which will be reported as uninitialized memory. To distinguish between
+    # secret and actually uninitialized:
+    # - unset MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND - does the failure persist?
+    # - or alternatively, build with debug info and manually run the offending
+    # test suite with valgrind --track-origins=yes, then check if the origin
+    # was TEST_CF_SECRET() or something else.
+    msg "build: cmake release GCC, full config minus MBEDTLS_USE_PSA_CRYPTO with constant flow testing"
+    scripts/config.py full
+    scripts/config.py set MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    skip_suites_without_constant_flow
+    cmake -D CMAKE_BUILD_TYPE:String=Release .
+    make
+
+    # this only shows a summary of the results (how many of each type)
+    # details are left in Testing/<date>/DynamicAnalysis.xml
+    msg "test: some suites (full minus MBEDTLS_USE_PSA_CRYPTO, valgrind + constant flow)"
+    make memcheck
+
+    # Test asm path in constant time module - by default, it will test the plain C
+    # path under Valgrind or Memsan. Running only the constant_time tests is fast (<1s)
+    msg "test: valgrind asm constant_time"
+    scripts/config.py --force set MBEDTLS_TEST_CONSTANT_FLOW_ASM
+    skip_all_except_given_suite test_suite_constant_time
+    cmake -D CMAKE_BUILD_TYPE:String=Release .
+    make clean
+    make
+    make memcheck
+}
+
+component_release_test_valgrind_constant_flow_psa () {
+    # This tests both (1) everything that valgrind's memcheck usually checks
+    # (heap buffer overflows, use of uninitialized memory, use-after-free,
+    # etc.) and (2) branches or memory access depending on secret values,
+    # which will be reported as uninitialized memory. To distinguish between
+    # secret and actually uninitialized:
+    # - unset MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND - does the failure persist?
+    # - or alternatively, build with debug info and manually run the offending
+    # test suite with valgrind --track-origins=yes, then check if the origin
+    # was TEST_CF_SECRET() or something else.
+    msg "build: cmake release GCC, full config with constant flow testing"
+    scripts/config.py full
+    scripts/config.py set MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND
+    skip_suites_without_constant_flow
+    cmake -D CMAKE_BUILD_TYPE:String=Release .
+    make
+
+    # this only shows a summary of the results (how many of each type)
+    # details are left in Testing/<date>/DynamicAnalysis.xml
+    msg "test: some suites (valgrind + constant flow)"
+    make memcheck
+}
+
+component_test_tsan () {
+    msg "build: TSan (clang)"
+    scripts/config.py full
+    scripts/config.py set MBEDTLS_THREADING_C
+    scripts/config.py set MBEDTLS_THREADING_PTHREAD
+    # Self-tests do not currently use multiple threads.
+    scripts/config.py unset MBEDTLS_SELF_TEST
+
+    # The deprecated MBEDTLS_PSA_CRYPTO_SE_C interface is not thread safe.
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
+
+    CC=clang cmake -D CMAKE_BUILD_TYPE:String=TSan .
+    make
+
+    msg "test: main suites (TSan)"
+    make test
+}
+
+component_test_memsan () {
+    msg "build: MSan (clang)" # ~ 1 min 20s
+    scripts/config.py unset MBEDTLS_AESNI_C # memsan doesn't grok asm
+    CC=clang cmake -D CMAKE_BUILD_TYPE:String=MemSan .
+    make
+
+    msg "test: main suites (MSan)" # ~ 10s
+    make test
+
+    msg "test: metatests (MSan)"
+    tests/scripts/run-metatests.sh any msan
+
+    msg "program demos (MSan)" # ~20s
+    tests/scripts/run_demos.py
+
+    msg "test: ssl-opt.sh (MSan)" # ~ 1 min
+    tests/ssl-opt.sh
+
+    # Optional part(s)
+
+    if [ "$MEMORY" -gt 0 ]; then
+        msg "test: compat.sh (MSan)" # ~ 6 min 20s
+        tests/compat.sh
+    fi
+}
+
+component_release_test_valgrind () {
+    msg "build: Release (clang)"
+    # default config, in particular without MBEDTLS_USE_PSA_CRYPTO
+    CC=clang cmake -D CMAKE_BUILD_TYPE:String=Release .
+    make
+
+    msg "test: main suites, Valgrind (default config)"
+    make memcheck
+
+    # Optional parts (slow; currently broken on OS X because programs don't
+    # seem to receive signals under valgrind on OS X).
+    # These optional parts don't run on the CI.
+    if [ "$MEMORY" -gt 0 ]; then
+        msg "test: ssl-opt.sh --memcheck (default config)"
+        tests/ssl-opt.sh --memcheck
+    fi
+
+    if [ "$MEMORY" -gt 1 ]; then
+        msg "test: compat.sh --memcheck (default config)"
+        tests/compat.sh --memcheck
+    fi
+
+    if [ "$MEMORY" -gt 0 ]; then
+        msg "test: context-info.sh --memcheck (default config)"
+        tests/context-info.sh --memcheck
+    fi
+}
+
+component_release_test_valgrind_psa () {
+    msg "build: Release, full (clang)"
+    # full config, in particular with MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py full
+    CC=clang cmake -D CMAKE_BUILD_TYPE:String=Release .
+    make
+
+    msg "test: main suites, Valgrind (full config)"
+    make memcheck
+}
diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c
index 7415e29..eceb40b 100644
--- a/tests/src/psa_test_wrappers.c
+++ b/tests/src/psa_test_wrappers.c
@@ -604,6 +604,24 @@
     return status;
 }
 
+/* Wrapper for psa_generate_key_custom */
+psa_status_t mbedtls_test_wrap_psa_generate_key_custom(
+    const psa_key_attributes_t *arg0_attributes,
+    const psa_custom_key_parameters_t *arg1_custom,
+    const uint8_t *arg2_custom_data,
+    size_t arg3_custom_data_length,
+    mbedtls_svc_key_id_t *arg4_key)
+{
+#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
+    MBEDTLS_TEST_MEMORY_POISON(arg2_custom_data, arg3_custom_data_length);
+#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */
+    psa_status_t status = (psa_generate_key_custom)(arg0_attributes, arg1_custom, arg2_custom_data, arg3_custom_data_length, arg4_key);
+#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
+    MBEDTLS_TEST_MEMORY_UNPOISON(arg2_custom_data, arg3_custom_data_length);
+#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */
+    return status;
+}
+
 /* Wrapper for psa_generate_key_ext */
 psa_status_t mbedtls_test_wrap_psa_generate_key_ext(
     const psa_key_attributes_t *arg0_attributes,
@@ -870,6 +888,25 @@
     return status;
 }
 
+/* Wrapper for psa_key_derivation_output_key_custom */
+psa_status_t mbedtls_test_wrap_psa_key_derivation_output_key_custom(
+    const psa_key_attributes_t *arg0_attributes,
+    psa_key_derivation_operation_t *arg1_operation,
+    const psa_custom_key_parameters_t *arg2_custom,
+    const uint8_t *arg3_custom_data,
+    size_t arg4_custom_data_length,
+    mbedtls_svc_key_id_t *arg5_key)
+{
+#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
+    MBEDTLS_TEST_MEMORY_POISON(arg3_custom_data, arg4_custom_data_length);
+#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */
+    psa_status_t status = (psa_key_derivation_output_key_custom)(arg0_attributes, arg1_operation, arg2_custom, arg3_custom_data, arg4_custom_data_length, arg5_key);
+#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
+    MBEDTLS_TEST_MEMORY_UNPOISON(arg3_custom_data, arg4_custom_data_length);
+#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */
+    return status;
+}
+
 /* Wrapper for psa_key_derivation_output_key_ext */
 psa_status_t mbedtls_test_wrap_psa_key_derivation_output_key_ext(
     const psa_key_attributes_t *arg0_attributes,
diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c
index 255849f..16fa38a 100644
--- a/tests/src/test_helpers/ssl_helpers.c
+++ b/tests/src/test_helpers/ssl_helpers.c
@@ -551,7 +551,10 @@
              * happen in test environment, unless forced manually. */
         }
     }
-    mbedtls_test_ssl_message_queue_pop_info(queue, buf_len);
+    ret = mbedtls_test_ssl_message_queue_pop_info(queue, buf_len);
+    if (ret < 0) {
+        return ret;
+    }
 
     return (msg_len > INT_MAX) ? INT_MAX : (int) msg_len;
 }
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 32c7274..4149fdb 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -6935,6 +6935,18 @@
 depends_on:PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
 derive_key_type:PSA_ALG_PBKDF2_AES_CMAC_PRF_128:"706173737764":"01":"73616c74":PSA_KEY_TYPE_AES:256:"28e288c6345bb5ecf7ca70274208a3ba0f1148b5868537d5e09d3ee6813b1f52"
 
+PSA key derivation custom: default -> AES-128
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_AES
+derive_key_custom:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_AES:128:0:"":PSA_SUCCESS:"3cb25f25faacd57a90434f64d0362f2a"
+
+PSA key derivation custom: flags=1 -> AES-128
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_AES
+derive_key_custom:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_AES:128:1:"":PSA_ERROR_INVALID_ARGUMENT:""
+
+PSA key derivation custom: data non-empty -> AES-128
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_AES
+derive_key_custom:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_AES:128:0:"2a":PSA_ERROR_INVALID_ARGUMENT:""
+
 PSA key derivation: default params -> AES-128
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_AES
 derive_key_ext:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_AES:128:0:"":PSA_SUCCESS:"3cb25f25faacd57a90434f64d0362f2a"
@@ -7520,6 +7532,83 @@
 depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE
 generate_key:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):1024:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_ERROR_NOT_SUPPORTED:0
 
+PSA generate key custom: RSA, flags=1
+depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE
+generate_key_custom:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:1:"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA generate key custom: RSA, empty e
+depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
+generate_key_custom:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"":PSA_SUCCESS
+
+PSA generate key custom: RSA, e=3
+depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
+generate_key_custom:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"03":PSA_SUCCESS
+
+PSA generate key custom: RSA, e=3 with leading zeros
+depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
+generate_key_custom:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"000003":PSA_SUCCESS
+
+# TODO: currently errors with NOT_SUPPORTED because e is converted to an int
+# and the conversion errors out if there are too many digits without checking
+# for leading zeros. This is a very minor bug. Re-enable this test when this
+# bug is fixed.
+#PSA generate key custom: RSA, e=3 with many leading zeros
+#depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
+#generate_key_custom:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"0000000000000000000000000000000003":PSA_SUCCESS
+
+PSA generate key custom: RSA, e=513
+depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
+generate_key_custom:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"0201":PSA_SUCCESS
+
+PSA generate key custom: RSA, e=65537
+depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
+generate_key_custom:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"010001":PSA_SUCCESS
+
+PSA generate key custom: RSA, e=2^31-1
+depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:INT_MAX>=0x7fffffff
+generate_key_custom:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"7fffffff":PSA_SUCCESS
+
+PSA generate key custom: RSA, e=2^31+3 (too large for built-in RSA)
+depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:!MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE:INT_MAX<=0x7fffffff
+generate_key_custom:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"80000003":PSA_ERROR_NOT_SUPPORTED
+
+PSA generate key custom: RSA, e=2^64+3 (too large for built-in RSA)
+depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:!MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE:INT_MAX<=0xffffffffffffffff
+generate_key_custom:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"010000000000000003":PSA_ERROR_NOT_SUPPORTED
+
+PSA generate key custom: RSA, e=1
+depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE
+generate_key_custom:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"01":PSA_ERROR_INVALID_ARGUMENT
+
+PSA generate key custom: RSA, e=0
+depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE
+generate_key_custom:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"00":PSA_ERROR_INVALID_ARGUMENT
+
+PSA generate key custom: RSA, e=2
+depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE
+generate_key_custom:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"02":PSA_ERROR_INVALID_ARGUMENT
+
+# Check that with a driver, we reject a custom e as unsupported,
+# as opposed to silently using the default e.
+# When we add proper driver support, remove this test case and remove
+# the dependency on MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE from
+# the positive/invalid_argument test cases.
+PSA generate key custom: RSA, e=3 with driver and no fallback (not yet supported)
+depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:!MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE
+generate_key_custom:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"03":PSA_ERROR_NOT_SUPPORTED
+
+PSA generate key custom: ECC, flags=0
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_ECDH
+generate_key_custom:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:0:"":PSA_SUCCESS
+
+PSA generate key custom: ECC, flags=1
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_ECDH
+generate_key_custom:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:1:"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA generate key custom: ECC, data non-empty
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_ECDH
+generate_key_custom:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:0:"2a":PSA_ERROR_INVALID_ARGUMENT
+
 PSA generate key ext: RSA, params.flags=1
 depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE
 generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:1:"":PSA_ERROR_INVALID_ARGUMENT
@@ -7528,63 +7617,10 @@
 depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
 generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"":PSA_SUCCESS
 
-PSA generate key ext: RSA, e=3
-depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
-generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"03":PSA_SUCCESS
-
-PSA generate key ext: RSA, e=3 with leading zeros
-depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
-generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"000003":PSA_SUCCESS
-
-# TODO: currently errors with NOT_SUPPORTED because e is converted to an int
-# and the conversion errors out if there are too many digits without checking
-# for leading zeros. This is a very minor bug. Re-enable this test when this
-# bug is fixed.
-#PSA generate key ext: RSA, e=3 with many leading zeros
-#depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
-#generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"0000000000000000000000000000000003":PSA_SUCCESS
-
 PSA generate key ext: RSA, e=513
 depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
 generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"0201":PSA_SUCCESS
 
-PSA generate key ext: RSA, e=65537
-depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT
-generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"010001":PSA_SUCCESS
-
-PSA generate key ext: RSA, e=2^31-1
-depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:INT_MAX>=0x7fffffff
-generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"7fffffff":PSA_SUCCESS
-
-PSA generate key ext: RSA, e=2^31+3 (too large for built-in RSA)
-depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:!MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE:INT_MAX<=0x7fffffff
-generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"80000003":PSA_ERROR_NOT_SUPPORTED
-
-PSA generate key ext: RSA, e=2^64+3 (too large for built-in RSA)
-depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:!MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE:INT_MAX<=0xffffffffffffffff
-generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"010000000000000003":PSA_ERROR_NOT_SUPPORTED
-
-PSA generate key ext: RSA, e=1
-depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE
-generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"01":PSA_ERROR_INVALID_ARGUMENT
-
-PSA generate key ext: RSA, e=0
-depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE
-generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"00":PSA_ERROR_INVALID_ARGUMENT
-
-PSA generate key ext: RSA, e=2
-depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE
-generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"02":PSA_ERROR_INVALID_ARGUMENT
-
-# Check that with a driver, we reject a custom e as unsupported,
-# as opposed to silently using the default e.
-# When we add proper driver support, remove this test case and remove
-# the dependency on MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE from
-# the positive/invalid_argument test cases.
-PSA generate key ext: RSA, e=3 with driver and no fallback (not yet supported)
-depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:!MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE
-generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"03":PSA_ERROR_NOT_SUPPORTED
-
 PSA generate key ext: ECC, flags=0
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_ECDH
 generate_key_ext:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:0:"":PSA_SUCCESS
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 0c8552b..7f47f27 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -9592,6 +9592,77 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void derive_key_custom(int alg_arg,
+                       data_t *key_data,
+                       data_t *input1,
+                       data_t *input2,
+                       int key_type_arg, int bits_arg,
+                       int flags_arg,
+                       data_t *custom_data,
+                       psa_status_t expected_status,
+                       data_t *expected_export)
+{
+    mbedtls_svc_key_id_t base_key = MBEDTLS_SVC_KEY_ID_INIT;
+    mbedtls_svc_key_id_t derived_key = MBEDTLS_SVC_KEY_ID_INIT;
+    const psa_algorithm_t alg = alg_arg;
+    const psa_key_type_t key_type = key_type_arg;
+    const size_t bits = bits_arg;
+    psa_custom_key_parameters_t custom = PSA_CUSTOM_KEY_PARAMETERS_INIT;
+    custom.flags = flags_arg;
+    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    const size_t export_buffer_size =
+        PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, bits);
+    uint8_t *export_buffer = NULL;
+    psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
+    size_t export_length;
+
+    TEST_CALLOC(export_buffer, export_buffer_size);
+    PSA_ASSERT(psa_crypto_init());
+
+    psa_set_key_usage_flags(&base_attributes, PSA_KEY_USAGE_DERIVE);
+    psa_set_key_algorithm(&base_attributes, alg);
+    psa_set_key_type(&base_attributes, PSA_KEY_TYPE_DERIVE);
+    PSA_ASSERT(psa_import_key(&base_attributes, key_data->x, key_data->len,
+                              &base_key));
+
+    if (mbedtls_test_psa_setup_key_derivation_wrap(
+            &operation, base_key, alg,
+            input1->x, input1->len,
+            input2->x, input2->len,
+            PSA_KEY_DERIVATION_UNLIMITED_CAPACITY, 0) == 0) {
+        goto exit;
+    }
+
+    psa_set_key_usage_flags(&derived_attributes, PSA_KEY_USAGE_EXPORT);
+    psa_set_key_algorithm(&derived_attributes, 0);
+    psa_set_key_type(&derived_attributes, key_type);
+    psa_set_key_bits(&derived_attributes, bits);
+
+    TEST_EQUAL(psa_key_derivation_output_key_custom(
+                   &derived_attributes, &operation,
+                   &custom, custom_data->x, custom_data->len,
+                   &derived_key),
+               expected_status);
+
+    if (expected_status == PSA_SUCCESS) {
+        PSA_ASSERT(psa_export_key(derived_key,
+                                  export_buffer, export_buffer_size,
+                                  &export_length));
+        TEST_MEMORY_COMPARE(export_buffer, export_length,
+                            expected_export->x, expected_export->len);
+    }
+
+exit:
+    mbedtls_free(export_buffer);
+    psa_key_derivation_abort(&operation);
+    psa_destroy_key(base_key);
+    psa_destroy_key(derived_key);
+    PSA_DONE();
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void derive_key_ext(int alg_arg,
                     data_t *key_data,
                     data_t *input1,
@@ -10153,6 +10224,71 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void generate_key_custom(int type_arg,
+                         int bits_arg,
+                         int usage_arg,
+                         int alg_arg,
+                         int flags_arg,
+                         data_t *custom_data,
+                         int expected_status_arg)
+{
+    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_key_type_t type = type_arg;
+    psa_key_usage_t usage = usage_arg;
+    size_t bits = bits_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_status_t expected_status = expected_status_arg;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_custom_key_parameters_t custom = PSA_CUSTOM_KEY_PARAMETERS_INIT;
+    custom.flags = flags_arg;
+    psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+    PSA_ASSERT(psa_crypto_init());
+
+    psa_set_key_usage_flags(&attributes, usage);
+    psa_set_key_algorithm(&attributes, alg);
+    psa_set_key_type(&attributes, type);
+    psa_set_key_bits(&attributes, bits);
+
+    /* Generate a key */
+    psa_status_t status =
+        psa_generate_key_custom(&attributes,
+                                &custom, custom_data->x, custom_data->len,
+                                &key);
+
+    TEST_EQUAL(status, expected_status);
+    if (expected_status != PSA_SUCCESS) {
+        goto exit;
+    }
+
+    /* Test the key information */
+    PSA_ASSERT(psa_get_key_attributes(key, &got_attributes));
+    TEST_EQUAL(psa_get_key_type(&got_attributes), type);
+    TEST_EQUAL(psa_get_key_bits(&got_attributes), bits);
+
+#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
+    if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
+        TEST_ASSERT(rsa_test_e(key, bits, custom_data));
+    }
+#endif
+
+    /* Do something with the key according to its type and permitted usage. */
+    if (!mbedtls_test_psa_exercise_key(key, usage, alg, 0)) {
+        goto exit;
+    }
+
+exit:
+    /*
+     * Key attributes may have been returned by psa_get_key_attributes()
+     * thus reset them as required.
+     */
+    psa_reset_key_attributes(&got_attributes);
+    psa_destroy_key(key);
+    PSA_DONE();
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void generate_key_ext(int type_arg,
                       int bits_arg,
                       int usage_arg,