Merge pull request #5132 from openluopworld/origin/development_2.x

Backport 2.x: Fix GCM calculation with very long IV
diff --git a/.gitignore b/.gitignore
index 5a58609..9b185c6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -49,6 +49,9 @@
 # Generated documentation:
 /apidoc
 
+# PSA Crypto compliance test repo, cloned by test_psa_compliance.py
+/psa-arch-tests
+
 # Editor navigation files:
 /GPATH
 /GRTAGS
diff --git a/ChangeLog.d/base64-ranges.txt b/ChangeLog.d/base64-ranges.txt
new file mode 100644
index 0000000..e3f3862
--- /dev/null
+++ b/ChangeLog.d/base64-ranges.txt
@@ -0,0 +1,4 @@
+Changes
+   * Improve the performance of base64 constant-flow code. The result is still
+     slower than the original non-constant-flow implementation, but much faster
+     than the previous constant-flow implementation. Fixes #4814.
diff --git a/ChangeLog.d/chacha20-poly1305-invalid-nonce.txt b/ChangeLog.d/chacha20-poly1305-invalid-nonce.txt
new file mode 100644
index 0000000..ca3f9ac
--- /dev/null
+++ b/ChangeLog.d/chacha20-poly1305-invalid-nonce.txt
@@ -0,0 +1,3 @@
+Changes
+   * Indicate in the error returned if the nonce length used with
+     ChaCha20-Poly1305 is invalid, and not just unsupported.
diff --git a/ChangeLog.d/check-return.txt b/ChangeLog.d/check-return.txt
new file mode 100644
index 0000000..045b180
--- /dev/null
+++ b/ChangeLog.d/check-return.txt
@@ -0,0 +1,17 @@
+Bugfix
+   * Failures of alternative implementations of AES or DES single-block
+     functions enabled with MBEDTLS_AES_ENCRYPT_ALT, MBEDTLS_AES_DECRYPT_ALT,
+     MBEDTLS_DES_CRYPT_ECB_ALT or MBEDTLS_DES3_CRYPT_ECB_ALT were ignored.
+     This does not concern the implementation provided with Mbed TLS,
+     where this function cannot fail, or full-module replacements with
+     MBEDTLS_AES_ALT or MBEDTLS_DES_ALT. Reported by Armelle Duboc in #1092.
+
+Features
+   * Warn if errors from certain functions are ignored. This is currently
+     supported on GCC-like compilers and on MSVC and can be configured through
+     the macro MBEDTLS_CHECK_RETURN. The warnings are always enabled
+     (where supported) for critical functions where ignoring the return
+     value is almost always a bug. Enable the new configuration option
+     MBEDTLS_CHECK_RETURN_WARNING to get warnings for other functions. This
+     is currently implemented in the AES and DES modules, and will be extended
+     to other modules in the future.
diff --git a/ChangeLog.d/do-not-use-obsolete-header.txt b/ChangeLog.d/do-not-use-obsolete-header.txt
new file mode 100644
index 0000000..9a57ef1
--- /dev/null
+++ b/ChangeLog.d/do-not-use-obsolete-header.txt
@@ -0,0 +1,5 @@
+Bugfix
+   * Don't use the obsolete header path sys/fcntl.h in unit tests.
+     These header files cause compilation errors in musl.
+     Fixes #4969.
+
diff --git a/ChangeLog.d/fix-mbedtls_cipher_crypt-aes-ecb.txt b/ChangeLog.d/fix-mbedtls_cipher_crypt-aes-ecb.txt
new file mode 100644
index 0000000..6dc4724
--- /dev/null
+++ b/ChangeLog.d/fix-mbedtls_cipher_crypt-aes-ecb.txt
@@ -0,0 +1,2 @@
+Bugfix
+   * Fix mbedtls_cipher_crypt: AES-ECB when MBEDTLS_USE_PSA_CRYPTO is enabled.
diff --git a/ChangeLog.d/fix-needed-shared-libraries-linux.txt b/ChangeLog.d/fix-needed-shared-libraries-linux.txt
new file mode 100644
index 0000000..74ad3bc
--- /dev/null
+++ b/ChangeLog.d/fix-needed-shared-libraries-linux.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Fix issue in Makefile on Linux with SHARED=1, that caused shared libraries
+     not to list other shared libraries they need.
diff --git a/ChangeLog.d/fix-psa_gen_key-status.txt b/ChangeLog.d/fix-psa_gen_key-status.txt
new file mode 100644
index 0000000..7860988
--- /dev/null
+++ b/ChangeLog.d/fix-psa_gen_key-status.txt
@@ -0,0 +1,2 @@
+Bugfix
+   * Fix the error returned by psa_generate_key() for a public key. Fixes #4551.
diff --git a/ChangeLog.d/muladdc-memory.txt b/ChangeLog.d/muladdc-memory.txt
new file mode 100644
index 0000000..218be5a
--- /dev/null
+++ b/ChangeLog.d/muladdc-memory.txt
@@ -0,0 +1,5 @@
+Bugfix
+   * Fix missing constraints on x86_64 and aarch64 assembly code
+     for bignum multiplication that broke some bignum operations with
+     (at least) Clang 12.
+     Fixes #4116, #4786, #4917, #4962.
diff --git a/ChangeLog.d/no-strerror.txt b/ChangeLog.d/no-strerror.txt
new file mode 100644
index 0000000..69743a8
--- /dev/null
+++ b/ChangeLog.d/no-strerror.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Fix the build of sample programs when neither MBEDTLS_ERROR_C nor
+     MBEDTLS_ERROR_STRERROR_DUMMY is enabled.
diff --git a/ChangeLog.d/psa_alg_rsa_pss.txt b/ChangeLog.d/psa_alg_rsa_pss.txt
new file mode 100644
index 0000000..5c6048f
--- /dev/null
+++ b/ChangeLog.d/psa_alg_rsa_pss.txt
@@ -0,0 +1,5 @@
+Bugfix
+   * Fix PSA_ALG_RSA_PSS verification accepting an arbitrary salt length.
+     This algorithm now accepts only the same salt length for verification
+     that it produces when signing, as documented. Use the new algorithm
+     PSA_ALG_RSA_PSS_ANY_SALT to accept any salt length. Fixes #4946.
diff --git a/ChangeLog.d/psa_crypto_api_macros.txt b/ChangeLog.d/psa_crypto_api_macros.txt
new file mode 100644
index 0000000..ff53e33
--- /dev/null
+++ b/ChangeLog.d/psa_crypto_api_macros.txt
@@ -0,0 +1,11 @@
+Features
+   * Add missing PSA macros declared by PSA Crypto API 1.0.0:
+     PSA_ALG_IS_SIGN_HASH, PSA_ALG_NONE, PSA_HASH_BLOCK_LENGTH, PSA_KEY_ID_NULL.
+
+Bugfix
+   * The existing predicate macro name PSA_ALG_IS_HASH_AND_SIGN is now reserved
+     for algorithm values that fully encode the hashing step, as per the PSA
+     Crypto API specification. This excludes PSA_ALG_RSA_PKCS1V15_SIGN_RAW and
+     PSA_ALG_ECDSA_ANY. The new predicate macro PSA_ALG_IS_SIGN_HASH covers
+     all algorithms that can be used with psa_{sign,verify}_hash(), including
+     these two.
diff --git a/ChangeLog.d/remove-greentea-support.txt b/ChangeLog.d/remove-greentea-support.txt
new file mode 100644
index 0000000..af4df4b
--- /dev/null
+++ b/ChangeLog.d/remove-greentea-support.txt
@@ -0,0 +1,3 @@
+Removals
+   * Remove the partial support for running unit tests via Greentea on Mbed OS,
+     which had been unmaintained since 2018.
diff --git a/README.md b/README.md
index 759ffb5..4d50a61 100644
--- a/README.md
+++ b/README.md
@@ -38,7 +38,7 @@
 
 The main systems used for development are CMake and GNU Make. Those systems are always complete and up-to-date. The others should reflect all changes present in the CMake and Make build system, although features may not be ported there automatically.
 
-The Make and CMake build systems create three libraries: libmbedcrypto, libmbedx509, and libmbedtls. Note that libmbedtls depends on libmbedx509 and libmbedcrypto, and libmbedx509 depends on libmbedcrypto. As a result, some linkers will expect flags to be in a specific order, for example the GNU linker wants `-lmbedtls -lmbedx509 -lmbedcrypto`. Also, when loading shared libraries using dlopen(), you'll need to load libmbedcrypto first, then libmbedx509, before you can load libmbedtls.
+The Make and CMake build systems create three libraries: libmbedcrypto, libmbedx509, and libmbedtls. Note that libmbedtls depends on libmbedx509 and libmbedcrypto, and libmbedx509 depends on libmbedcrypto. As a result, some linkers will expect flags to be in a specific order, for example the GNU linker wants `-lmbedtls -lmbedx509 -lmbedcrypto`.
 
 ### Tool versions
 
@@ -247,3 +247,10 @@
 ------------
 
 We gratefully accept bug reports and contributions from the community. Please see the [contributing guidelines](CONTRIBUTING.md) for details on how to do this.
+
+Contact
+-------
+
+* To report a security vulnerability in Mbed TLS, please email <mbed-tls-security@lists.trustedfirmware.org>. For more information, see [`SECURITY.md`](SECURITY.md).
+* To report a bug or request a feature in Mbed TLS, please [file an issue on GitHub](https://github.com/ARMmbed/mbedtls/issues/new/choose).
+* Please see [`SUPPORT.md`](SUPPORT.md) for other channels for discussion and support about Mbed TLS.
diff --git a/docs/.gitignore b/docs/.gitignore
index 33ae5ac..23f832b 100644
--- a/docs/.gitignore
+++ b/docs/.gitignore
@@ -1,3 +1,2 @@
 *.html
 *.pdf
-!PSACryptoDriverModelSpec.pdf
diff --git a/docs/PSACryptoDriverModelSpec.pdf b/docs/PSACryptoDriverModelSpec.pdf
deleted file mode 100644
index cf11380..0000000
--- a/docs/PSACryptoDriverModelSpec.pdf
+++ /dev/null
Binary files differ
diff --git a/docs/use-psa-crypto.md b/docs/use-psa-crypto.md
new file mode 100644
index 0000000..6ec2dca
--- /dev/null
+++ b/docs/use-psa-crypto.md
@@ -0,0 +1,204 @@
+This document describes the compile-time configuration option
+`MBEDTLS_USE_PSA_CRYPTO` from a user's perspective, more specifically its
+current effects as well as the parts that aren't covered yet.
+
+Current effects
+===============
+
+General limitations
+-------------------
+
+Compile-time: enabling `MBEDTLS_USE_PSA_CRYPTO` requires
+`MBEDTLS_ECP_RESTARTABLE` and
+`MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER` to be disabled.
+
+Effect: `MBEDTLS_USE_PSA_CRYPTO` currently has no effect on TLS 1.3 (which is
+itself experimental and only partially supported so far): TLS 1.3 always uses
+the legacy APIs even when this option is set.
+
+Stability: any API that's only available when `MBEDTLS_USE_PSA_CRYPTO` is
+defined is considered experimental and may change in incompatible ways at any
+time. Said otherwise, these APIs are explicitly excluded from the usual API
+stability promises.
+
+New APIs / API extensions
+-------------------------
+
+Some of these APIs are meant for the application to use in place of
+pre-existing APIs, in order to get access to the benefits; in the sub-sections
+below these are indicated by "Use in (X.509 and) TLS: opt-in", meaning that
+this requires changes to the application code for the (X.509 and) TLS layers
+to pick up the improvements.
+
+Some of these APIs are mostly meant for internal use by the TLS (and X.509)
+layers; they are indicated below by "Use in (X.509 and) TLS: automatic",
+meaning that no changes to the application code are required for the TLS (and
+X.509) layers to pick up the improvements.
+
+### PSA-held (opaque) keys in the PK layer
+
+There is a new API function `mbedtls_pk_setup_opaque()` that can be used to
+wrap a PSA keypair into a PK context. The key can be used for private-key
+operations and its public part can be exported.
+
+Benefits: isolation of long-term secrets, use of PSA Crypto drivers.
+
+Limitations: only for private keys, only ECC. (That is, only ECDSA signature
+generation. Note: currently this will use randomized ECDSA while Mbed TLS uses
+deterministic ECDSA by default.) The following operations are not supported
+with a context set this way, while they would be available with a normal
+`ECKEY` context: `mbedtls_pk_verify()`, `mbedtls_pk_check_pair()`,
+`mbedtls_pk_debug()`.
+
+Use in X.509 and TLS: opt-in. The application needs to construct the PK context
+using the new API in order to get the benefits; it can then pass the
+resulting context to the following existing APIs:
+
+- `mbedtls_ssl_conf_own_cert()` or `mbedtls_ssl_set_hs_own_cert()` to use the
+  key together with a certificate for ECDSA-based key exchanges (note: while
+this is supported on both sides, it's currently only tested client-side);
+- `mbedtls_x509write_csr_set_key()` to generate a CSR (certificate signature
+  request).
+
+In the TLS and X.509 API, there are two other functions which accept a key or
+keypair as a PK context: `mbedtls_x509write_crt_set_subject_key()` and
+`mbedtls_x509write_crt_set_issuer_key()`. Use of opaque contexts here probably
+works but is so far untested.
+
+### PSA-held (opaque) keys for TLS pre-shared keys (PSK)
+
+There are two new API functions `mbedtls_ssl_conf_psk_opaque()` and
+`mbedtls_ssl_set_hs_psk_opaque()`. Call one of these from an application to
+register a PSA key for use with a PSK key exchange.
+
+Benefits: isolation of long-term secrets.
+
+Limitations: the key can only be used with "pure"
+PSK key exchanges (ciphersuites starting with `TLS_PSK_WITH_`), to the
+exclusion of RSA-PSK, DHE-PSK and ECDHE-PSK key exchanges. It is the responsibility of
+the user to make sure that when provisioning an opaque pre-shared key, the
+only PSK ciphersuites that can be negotiated are "pure" PSK; other XXX-PSK key
+exchanges will result in a handshake failure with the handshake function
+returning `MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE`.
+
+Use in TLS: opt-in. The application needs to register the key using the new
+APIs to get the benefits.
+
+### PSA-based operations in the Cipher layer
+
+There is a new API function `mbedtls_cipher_setup_psa()` to set up a context
+that will call PSA to store the key and perform the operations.
+
+Benefits: use of PSA Crypto drivers; partial isolation of short-term secrets
+(still generated outside of PSA, but then held by PSA).
+
+Limitations: the key is still passed in the clear by the application. The
+multi-part APIs are not supported, only the one-shot APIs. The only modes
+supported are ECB, CBC without padding, GCM and CCM (this excludes stream
+ciphers and ChachaPoly); the only cipher supported is AES (this excludes Aria,
+Camellia, and ChachaPoly). (Note: ECB is currently not tested.) (Note: it is
+possible to perform multiple one-shot operations with the same context;
+however this is not unit-tested, only tested via usage in TLS.)
+
+Use in TLS: automatic. Used when the cipher and mode is supported (with
+gracious fallback to the legacy API otherwise) in all places where a cipher is
+used. There are two such places: in `ssl_tls.c` for record protection, and in
+`ssl_ticket.c` for protecting tickets we issue.
+
+Internal changes
+----------------
+
+All of these internal changes are active as soon as `MBEDTLS_USE_PSA_CRYPTO`
+is enabled, no change required on the application side.
+
+### TLS: cipher operations based on PSA
+
+See "PSA-based operations in the Cipher layer" above.
+
+### PK layer: ECDSA verification based on PSA
+
+Scope: `mbedtls_pk_verify()` will call to PSA for ECDSA signature
+verification.
+
+Benefits: use of PSA Crypto drivers.
+
+Use in TLS and X.509: in all places where an ECDSA signature is verified.
+
+### TLS: ECDHE computation based on PSA
+
+Scope: Client-side, for ECDHE-RSA and ECDHE-ECDSA key exchanges, the
+computation of the ECDHE key exchange is done by PSA.
+
+Limitations: client-side only, ECDHE-PSK not covered
+
+Benefits: use of PSA Crypto drivers.
+
+### TLS: handshake hashes and PRF computed with PSA
+
+Scope: with TLS 1.2, the following are computed with PSA:
+- the running handshake hashes;
+- the hash of the ServerKeyExchange part that is signed;
+- the `verify_data` part of the Finished message;
+- the TLS PRF.
+
+Benefits: use of PSA Crypto drivers.
+
+### X.509: some hashes computed with PSA
+
+Scope: the following hashes are computed with PSA:
+- when verifying a certificate chain, hash of the child for verifying the
+  parent's signature;
+- when writing a CSR, hash of the request for self-signing the request.
+
+Benefits: use of PSA Crypto drivers.
+
+Parts that are not covered yet
+==============================
+
+This is only a high-level overview, grouped by theme
+
+TLS: 1.3 experimental support
+-----------------------------
+
+No part of the experimental support for TLS 1.3 is covered at the moment.
+
+TLS: key exchanges / asymmetric crypto
+--------------------------------------
+
+The following key exchanges are not covered at all:
+
+- RSA
+- DHE-RSA
+- DHE-PSK
+- RSA-PSK
+- ECDHE-PSK
+- ECDH-RSA
+- ECDH-ECDSA
+- ECJPAKE
+
+The following key exchanges are only partially covered:
+
+- ECDHE-RSA: RSA operations are not covered and, server-side, the ECDHE
+  operation isn't either
+- ECDHE-ECDSA: server-side, the ECDHE operation isn't covered. (ECDSA
+  signature generation is only covered if using `mbedtls_pk_setup_opaque()`.)
+
+PSK if covered when the application uses `mbedtls_ssl_conf_psk_opaque()` or
+`mbedtls_ssl_set_hs_psk_opaque()`.
+
+TLS: symmetric crypto
+---------------------
+
+- some ciphers not supported via PSA yet: ARIA, Camellia, ChachaPoly (silent
+  fallback to the legacy APIs)
+- the HMAC part of the CBC and NULL ciphersuites
+- the HMAC computation in `ssl_cookie.c`
+
+X.509
+-----
+
+- most hash operations are still done via the legacy API, except the few that
+  are documented above as using PSA
+- RSA PKCS#1 v1.5 signature generation (from PSA-held keys)
+- RSA PKCS#1 v1.5 signature verification
+- RSA-PSS signature verification
diff --git a/include/mbedtls/aes.h b/include/mbedtls/aes.h
index ab8793c..e280dbb 100644
--- a/include/mbedtls/aes.h
+++ b/include/mbedtls/aes.h
@@ -45,6 +45,7 @@
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
+#include "mbedtls/platform_util.h"
 
 #include <stddef.h>
 #include <stdint.h>
@@ -174,6 +175,7 @@
  * \return         \c 0 on success.
  * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
                     unsigned int keybits );
 
@@ -192,6 +194,7 @@
  * \return         \c 0 on success.
  * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
                     unsigned int keybits );
 
@@ -212,6 +215,7 @@
  * \return         \c 0 on success.
  * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
                                 const unsigned char *key,
                                 unsigned int keybits );
@@ -232,6 +236,7 @@
  * \return         \c 0 on success.
  * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
                                 const unsigned char *key,
                                 unsigned int keybits );
@@ -260,6 +265,7 @@
 
  * \return         \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
                     int mode,
                     const unsigned char input[16],
@@ -307,6 +313,7 @@
  * \return         #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
  *                 on failure.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
                     int mode,
                     size_t length,
@@ -351,6 +358,7 @@
  *                     smaller than an AES block in size (16 Bytes) or if \p
  *                     length is larger than 2^20 blocks (16 MiB).
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
                            int mode,
                            size_t length,
@@ -399,6 +407,7 @@
  *
  * \return         \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
                        int mode,
                        size_t length,
@@ -443,6 +452,7 @@
  *
  * \return         \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
                     int mode,
                     size_t length,
@@ -497,6 +507,7 @@
  *
  * \return         \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
                        size_t length,
                        size_t *iv_off,
@@ -511,10 +522,6 @@
  * \brief      This function performs an AES-CTR encryption or decryption
  *             operation.
  *
- *             This function performs the operation defined in the \p mode
- *             parameter (encrypt/decrypt), on the input data buffer
- *             defined in the \p input parameter.
- *
  *             Due to the nature of CTR, you must use the same key schedule
  *             for both encryption and decryption operations. Therefore, you
  *             must use the context initialized with mbedtls_aes_setkey_enc()
@@ -583,6 +590,7 @@
  *
  * \return                 \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
                        size_t length,
                        size_t *nc_off,
@@ -603,6 +611,7 @@
  *
  * \return          \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
                                   const unsigned char input[16],
                                   unsigned char output[16] );
@@ -618,6 +627,7 @@
  *
  * \return          \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
                                   const unsigned char input[16],
                                   unsigned char output[16] );
@@ -667,6 +677,7 @@
  * \return         \c 0 on success.
  * \return         \c 1 on failure.
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 int mbedtls_aes_self_test( int verbose );
 
 #endif /* MBEDTLS_SELF_TEST */
diff --git a/include/mbedtls/bn_mul.h b/include/mbedtls/bn_mul.h
index a0fa677..31137cd 100644
--- a/include/mbedtls/bn_mul.h
+++ b/include/mbedtls/bn_mul.h
@@ -229,9 +229,9 @@
         "addq   $8, %%rdi\n"
 
 #define MULADDC_STOP                        \
-        : "+c" (c), "+D" (d), "+S" (s)      \
-        : "b" (b)                           \
-        : "rax", "rdx", "r8"                \
+        : "+c" (c), "+D" (d), "+S" (s), "+m" (*(uint64_t (*)[16]) d) \
+        : "b" (b), "m" (*(const uint64_t (*)[16]) s)                 \
+        : "rax", "rdx", "r8"                                         \
     );
 
 #endif /* AMD64 */
@@ -244,18 +244,18 @@
 #define MULADDC_CORE                \
         "ldr x4, [%2], #8   \n\t"   \
         "ldr x5, [%1]       \n\t"   \
-        "mul x6, x4, %3     \n\t"   \
-        "umulh x7, x4, %3   \n\t"   \
+        "mul x6, x4, %4     \n\t"   \
+        "umulh x7, x4, %4   \n\t"   \
         "adds x5, x5, x6    \n\t"   \
         "adc x7, x7, xzr    \n\t"   \
         "adds x5, x5, %0    \n\t"   \
         "adc %0, x7, xzr    \n\t"   \
         "str x5, [%1], #8   \n\t"
 
-#define MULADDC_STOP                        \
-         : "+r" (c),  "+r" (d), "+r" (s)    \
-         : "r" (b)                          \
-         : "x4", "x5", "x6", "x7", "cc"     \
+#define MULADDC_STOP                                                    \
+         : "+r" (c),  "+r" (d), "+r" (s), "+m" (*(uint64_t (*)[16]) d)  \
+         : "r" (b), "m" (*(const uint64_t (*)[16]) s)                   \
+         : "x4", "x5", "x6", "x7", "cc"                                 \
     );
 
 #endif /* Aarch64 */
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 2c7bed2..87b4e91 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -617,6 +617,29 @@
 //#define MBEDTLS_CAMELLIA_SMALL_MEMORY
 
 /**
+ * \def MBEDTLS_CHECK_RETURN_WARNING
+ *
+ * If this macro is defined, emit a compile-time warning if application code
+ * calls a function without checking its return value, but the return value
+ * should generally be checked in portable applications.
+ *
+ * This is only supported on platforms where #MBEDTLS_CHECK_RETURN is
+ * implemented. Otherwise this option has no effect.
+ *
+ * Uncomment to get warnings on using fallible functions without checking
+ * their return value.
+ *
+ * \note  This feature is a work in progress.
+ *        Warnings will be added to more functions in the future.
+ *
+ * \note  A few functions are considered critical, and ignoring the return
+ *        value of these functions will trigger a warning even if this
+ *        macro is not defined. To completely disable return value check
+ *        warnings, define #MBEDTLS_CHECK_RETURN with an empty expansion.
+ */
+//#define MBEDTLS_CHECK_RETURN_WARNING
+
+/**
  * \def MBEDTLS_CIPHER_MODE_CBC
  *
  * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers.
@@ -2119,15 +2142,13 @@
  * will still continue to work as usual, so enabling this option should not
  * break backwards compatibility.
  *
- * \warning The PSA Crypto API is in beta stage. While you're welcome to
- * experiment using it, incompatible API changes are still possible, and some
- * parts may not have reached the same quality as the rest of Mbed TLS yet.
+ * \note See docs/use-psa-crypto.md for a complete description of what this
+ * option currently does, and of parts that are not affected by it so far.
  *
- * \warning This option enables new Mbed TLS APIs that are dependent on the
- * PSA Crypto API, so can't come with the same stability guarantees as the
- * rest of the Mbed TLS APIs. You're welcome to experiment with them, but for
- * now, access to these APIs is opt-in (via enabling the present option), in
- * order to clearly differentiate them from the stable Mbed TLS APIs.
+ * \warning This option enables new Mbed TLS APIs which are currently
+ * considered experimental and may change in incompatible ways at any time.
+ * That is, the APIs enabled by this option are not covered by the usual
+ * promises of API stability.
  *
  * Requires: MBEDTLS_PSA_CRYPTO_C.
  *
@@ -3199,10 +3220,6 @@
  *
  * Enable the Platform Security Architecture cryptography API.
  *
- * \warning The PSA Crypto API is still beta status. While you're welcome to
- * experiment using it, incompatible API changes are still possible, and some
- * parts may not have reached the same quality as the rest of Mbed TLS yet.
- *
  * Module:  library/psa_crypto.c
  *
  * Requires: either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C,
@@ -3695,6 +3712,29 @@
  */
 //#define MBEDTLS_PARAM_FAILED( cond )               assert( cond )
 
+/** \def MBEDTLS_CHECK_RETURN
+ *
+ * This macro is used at the beginning of the declaration of a function
+ * to indicate that its return value should be checked. It should
+ * instruct the compiler to emit a warning or an error if the function
+ * is called without checking its return value.
+ *
+ * There is a default implementation for popular compilers in platform_util.h.
+ * You can override the default implementation by defining your own here.
+ *
+ * If the implementation here is empty, this will effectively disable the
+ * checking of functions' return values.
+ */
+//#define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__))
+
+/** \def MBEDTLS_IGNORE_RETURN
+ *
+ * This macro requires one argument, which should be a C function call.
+ * If that function call would cause a #MBEDTLS_CHECK_RETURN warning, this
+ * warning is suppressed.
+ */
+//#define MBEDTLS_IGNORE_RETURN( result ) ((void) !(result))
+
 /* PSA options */
 /**
  * Use HMAC_DRBG with the specified hash algorithm for HMAC_DRBG for the
@@ -3852,7 +3892,7 @@
  * Maximum number of heap-allocated bytes for the purpose of
  * DTLS handshake message reassembly and future message buffering.
  *
- * This should be at least 9/8 * MBEDTLSSL_IN_CONTENT_LEN
+ * This should be at least 9/8 * MBEDTLS_SSL_IN_CONTENT_LEN
  * to account for a reassembled handshake message of maximum size,
  * together with its reassembly bitmap.
  *
diff --git a/include/mbedtls/config_psa.h b/include/mbedtls/config_psa.h
index c2a4422..976b4d3 100644
--- a/include/mbedtls/config_psa.h
+++ b/include/mbedtls/config_psa.h
@@ -56,6 +56,12 @@
 #define PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW PSA_WANT_ALG_RSA_PKCS1V15_SIGN
 #endif
 
+#if defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT) && !defined(PSA_WANT_ALG_RSA_PSS)
+#define PSA_WANT_ALG_RSA_PSS PSA_WANT_ALG_RSA_PSS_ANY_SALT
+#elif !defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT) && defined(PSA_WANT_ALG_RSA_PSS)
+#define PSA_WANT_ALG_RSA_PSS_ANY_SALT PSA_WANT_ALG_RSA_PSS
+#endif
+
 
 
 /****************************************************************/
@@ -284,6 +290,18 @@
 #endif /*!MBEDTLS_PSA_ACCEL_KEY_TYPE_ARC4 */
 #endif /* PSA_WANT_KEY_TYPE_ARC4 */
 
+#if defined(PSA_WANT_KEY_TYPE_ARIA)
+#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ARIA)
+#define PSA_HAVE_SOFT_KEY_TYPE_ARIA 1
+#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_ARIA */
+#if defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \
+    defined(PSA_HAVE_SOFT_BLOCK_MODE) || \
+    defined(PSA_HAVE_SOFT_BLOCK_AEAD)
+#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA 1
+#define MBEDTLS_ARIA_C
+#endif /* PSA_HAVE_SOFT_KEY_TYPE_ARIA || PSA_HAVE_SOFT_BLOCK_MODE */
+#endif /* PSA_WANT_KEY_TYPE_ARIA */
+
 #if defined(PSA_WANT_KEY_TYPE_CAMELLIA)
 #if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA)
 #define PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA 1
@@ -318,6 +336,7 @@
  * PSA_HAVE_SOFT_BLOCK_CIPHER, which can be used in any of these
  * situations. */
 #if defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \
+    defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \
     defined(PSA_HAVE_SOFT_KEY_TYPE_DES) || \
     defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA)
 #define PSA_HAVE_SOFT_BLOCK_CIPHER 1
@@ -398,6 +417,7 @@
 #if defined(PSA_WANT_ALG_CCM)
 #if !defined(MBEDTLS_PSA_ACCEL_ALG_CCM) || \
     defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \
+    defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \
     defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA)
 #define MBEDTLS_PSA_BUILTIN_ALG_CCM 1
 #define MBEDTLS_CCM_C
@@ -407,6 +427,7 @@
 #if defined(PSA_WANT_ALG_GCM)
 #if !defined(MBEDTLS_PSA_ACCEL_ALG_GCM) || \
     defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \
+    defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \
     defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA)
 #define MBEDTLS_PSA_BUILTIN_ALG_GCM 1
 #define MBEDTLS_GCM_C
@@ -618,7 +639,7 @@
 #define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN 1
 #define PSA_WANT_ALG_RSA_PKCS1V15_SIGN 1
 #define PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW 1
-#endif /* MBEDTLSS_PKCS1_V15 */
+#endif /* MBEDTLS_PKCS1_V15 */
 #if defined(MBEDTLS_PKCS1_V21)
 #define MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP 1
 #define PSA_WANT_ALG_RSA_OAEP 1
@@ -664,6 +685,11 @@
 #define MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER 1
 #endif
 
+#if defined(MBEDTLS_ARIA_C)
+#define PSA_WANT_KEY_TYPE_ARIA 1
+#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA 1
+#endif
+
 #if defined(MBEDTLS_CAMELLIA_C)
 #define PSA_WANT_KEY_TYPE_CAMELLIA 1
 #define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA 1
@@ -695,7 +721,7 @@
 #endif
 
 #if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) || \
-    defined(MBEDTLS_CAMELLIA_C)
+    defined(MBEDTLS_ARIA_C) || defined(MBEDTLS_CAMELLIA_C)
 #define MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING 1
 #define PSA_WANT_ALG_ECB_NO_PADDING 1
 #endif
diff --git a/include/mbedtls/des.h b/include/mbedtls/des.h
index 6bfe654..325aab5 100644
--- a/include/mbedtls/des.h
+++ b/include/mbedtls/des.h
@@ -32,6 +32,7 @@
 #else
 #include MBEDTLS_CONFIG_FILE
 #endif
+#include "mbedtls/platform_util.h"
 
 #include <stddef.h>
 #include <stdint.h>
@@ -146,6 +147,7 @@
  *                 security risk. We recommend considering stronger ciphers
  *                 instead.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
 
 /**
@@ -159,6 +161,7 @@
  *                 security risk. We recommend considering stronger ciphers
  *                 instead.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
 
 /**
@@ -173,6 +176,7 @@
  *                 security risk. We recommend considering stronger ciphers
  *                 instead.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
 
 /**
@@ -187,6 +191,7 @@
  *                 security risk. We recommend considering stronger ciphers
  *                 instead.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
 
 /**
@@ -197,6 +202,7 @@
  *
  * \return         0
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
                       const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
 
@@ -208,6 +214,7 @@
  *
  * \return         0
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
                       const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
 
@@ -219,6 +226,7 @@
  *
  * \return         0
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
                       const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
 
@@ -230,6 +238,7 @@
  *
  * \return         0
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
                       const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
 
@@ -246,6 +255,7 @@
  *                 security risk. We recommend considering stronger ciphers
  *                 instead.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
                     const unsigned char input[8],
                     unsigned char output[8] );
@@ -273,6 +283,7 @@
  *                 security risk. We recommend considering stronger ciphers
  *                 instead.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
                     int mode,
                     size_t length,
@@ -290,6 +301,7 @@
  *
  * \return         0 if successful
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
                      const unsigned char input[8],
                      unsigned char output[8] );
@@ -315,6 +327,7 @@
  *
  * \return         0 if successful, or MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
                      int mode,
                      size_t length,
@@ -345,6 +358,7 @@
  *
  * \return         0 if successful, or 1 if the test failed
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 int mbedtls_des_self_test( int verbose );
 
 #endif /* MBEDTLS_SELF_TEST */
diff --git a/include/mbedtls/platform_util.h b/include/mbedtls/platform_util.h
index fbc2a0d..f982db8 100644
--- a/include/mbedtls/platform_util.h
+++ b/include/mbedtls/platform_util.h
@@ -132,6 +132,95 @@
 #endif /* MBEDTLS_DEPRECATED_WARNING */
 #endif /* MBEDTLS_DEPRECATED_REMOVED */
 
+/* Implementation of the check-return facility.
+ * See the user documentation in config.h.
+ *
+ * Do not use this macro directly to annotate function: instead,
+ * use one of MBEDTLS_CHECK_RETURN_CRITICAL or MBEDTLS_CHECK_RETURN_TYPICAL
+ * depending on how important it is to check the return value.
+ */
+#if !defined(MBEDTLS_CHECK_RETURN)
+#if defined(__GNUC__)
+#define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__))
+#elif defined(_MSC_VER) && _MSC_VER >= 1700
+#include <sal.h>
+#define MBEDTLS_CHECK_RETURN _Check_return_
+#else
+#define MBEDTLS_CHECK_RETURN
+#endif
+#endif
+
+/** Critical-failure function
+ *
+ * This macro appearing at the beginning of the declaration of a function
+ * indicates that its return value should be checked in all applications.
+ * Omitting the check is very likely to indicate a bug in the application
+ * and will result in a compile-time warning if #MBEDTLS_CHECK_RETURN
+ * is implemented for the compiler in use.
+ *
+ * \note  The use of this macro is a work in progress.
+ *        This macro may be added to more functions in the future.
+ *        Such an extension is not considered an API break, provided that
+ *        there are near-unavoidable circumstances under which the function
+ *        can fail. For example, signature/MAC/AEAD verification functions,
+ *        and functions that require a random generator, are considered
+ *        return-check-critical.
+ */
+#define MBEDTLS_CHECK_RETURN_CRITICAL MBEDTLS_CHECK_RETURN
+
+/** Ordinary-failure function
+ *
+ * This macro appearing at the beginning of the declaration of a function
+ * indicates that its return value should be generally be checked in portable
+ * applications. Omitting the check will result in a compile-time warning if
+ * #MBEDTLS_CHECK_RETURN is implemented for the compiler in use and
+ * #MBEDTLS_CHECK_RETURN_WARNING is enabled in the compile-time configuration.
+ *
+ * You can use #MBEDTLS_IGNORE_RETURN to explicitly ignore the return value
+ * of a function that is annotated with #MBEDTLS_CHECK_RETURN.
+ *
+ * \note  The use of this macro is a work in progress.
+ *        This macro will be added to more functions in the future.
+ *        Eventually this should appear before most functions returning
+ *        an error code (as \c int in the \c mbedtls_xxx API or
+ *        as ::psa_status_t in the \c psa_xxx API).
+ */
+#if defined(MBEDTLS_CHECK_RETURN_WARNING)
+#define MBEDTLS_CHECK_RETURN_TYPICAL MBEDTLS_CHECK_RETURN
+#else
+#define MBEDTLS_CHECK_RETURN_TYPICAL
+#endif
+
+/** Benign-failure function
+ *
+ * This macro appearing at the beginning of the declaration of a function
+ * indicates that it is rarely useful to check its return value.
+ *
+ * This macro has an empty expansion. It exists for documentation purposes:
+ * a #MBEDTLS_CHECK_RETURN_OPTIONAL annotation indicates that the function
+ * has been analyzed for return-check usefuless, whereas the lack of
+ * an annotation indicates that the function has not been analyzed and its
+ * return-check usefulness is unknown.
+ */
+#define MBEDTLS_CHECK_RETURN_OPTIONAL
+
+/** \def MBEDTLS_IGNORE_RETURN
+ *
+ * Call this macro with one argument, a function call, to suppress a warning
+ * from #MBEDTLS_CHECK_RETURN due to that function call.
+ */
+#if !defined(MBEDTLS_IGNORE_RETURN)
+/* GCC doesn't silence the warning with just (void)(result).
+ * (void)!(result) is known to work up at least up to GCC 10, as well
+ * as with Clang and MSVC.
+ *
+ * https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Non_002dbugs.html
+ * https://stackoverflow.com/questions/40576003/ignoring-warning-wunused-result
+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425#c34
+ */
+#define MBEDTLS_IGNORE_RETURN(result) ( (void) !( result ) )
+#endif
+
 /**
  * \brief       Securely zeroize a buffer
  *
diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h
index 691ff3c..af7a809 100644
--- a/include/mbedtls/psa_util.h
+++ b/include/mbedtls/psa_util.h
@@ -59,6 +59,9 @@
         case MBEDTLS_CIPHER_AES_128_CBC:
         case MBEDTLS_CIPHER_AES_192_CBC:
         case MBEDTLS_CIPHER_AES_256_CBC:
+        case MBEDTLS_CIPHER_AES_128_ECB:
+        case MBEDTLS_CIPHER_AES_192_ECB:
+        case MBEDTLS_CIPHER_AES_256_ECB:
             return( PSA_KEY_TYPE_AES );
 
         /* ARIA not yet supported in PSA. */
diff --git a/include/mbedtls/sha256.h b/include/mbedtls/sha256.h
index cccd5c4..5b54be2 100644
--- a/include/mbedtls/sha256.h
+++ b/include/mbedtls/sha256.h
@@ -237,6 +237,9 @@
  *                 be a writable buffer of length \c 32 Bytes.
  * \param is224    Determines which function to use. This must be
  *                 either \c 0 for SHA-256, or \c 1 for SHA-224.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_sha256_ret( const unsigned char *input,
                         size_t ilen,
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 17bebf3..877c19b 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -3019,7 +3019,9 @@
  * \param key                   Identifier of the key to use for the operation.
  *                              It must be an asymmetric key pair. The key must
  *                              allow the usage #PSA_KEY_USAGE_SIGN_HASH.
- * \param alg                   A signature algorithm that is compatible with
+ * \param alg                   A signature algorithm (PSA_ALG_XXX
+ *                              value such that #PSA_ALG_IS_SIGN_HASH(\p alg)
+ *                              is true), that is compatible with
  *                              the type of \p key.
  * \param[in] hash              The hash or message to sign.
  * \param hash_length           Size of the \p hash buffer in bytes.
@@ -3072,7 +3074,9 @@
  *                          must be a public key or an asymmetric key pair. The
  *                          key must allow the usage
  *                          #PSA_KEY_USAGE_VERIFY_HASH.
- * \param alg               A signature algorithm that is compatible with
+ * \param alg               A signature algorithm (PSA_ALG_XXX
+ *                          value such that #PSA_ALG_IS_SIGN_HASH(\p alg)
+ *                          is true), that is compatible with
  *                          the type of \p key.
  * \param[in] hash          The hash or message whose signature is to be
  *                          verified.
@@ -3654,6 +3658,7 @@
  *
  *     - #PSA_KEY_TYPE_AES;
  *     - #PSA_KEY_TYPE_ARC4;
+ *     - #PSA_KEY_TYPE_ARIA;
  *     - #PSA_KEY_TYPE_CAMELLIA;
  *     - #PSA_KEY_TYPE_DERIVE;
  *     - #PSA_KEY_TYPE_HMAC.
diff --git a/include/psa/crypto_config.h b/include/psa/crypto_config.h
index 246e894..e2446cb 100644
--- a/include/psa/crypto_config.h
+++ b/include/psa/crypto_config.h
@@ -116,6 +116,7 @@
 #define PSA_WANT_KEY_TYPE_HMAC                  1
 #define PSA_WANT_KEY_TYPE_AES                   1
 #define PSA_WANT_KEY_TYPE_ARC4                  1
+#define PSA_WANT_KEY_TYPE_ARIA                  1
 #define PSA_WANT_KEY_TYPE_CAMELLIA              1
 #define PSA_WANT_KEY_TYPE_CHACHA20              1
 #define PSA_WANT_KEY_TYPE_DES                   1
diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h
index f51ec87..2df315c 100644
--- a/include/psa/crypto_sizes.h
+++ b/include/psa/crypto_sizes.h
@@ -85,6 +85,40 @@
         PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 64 :       \
         0)
 
+/** The input block size of a hash algorithm, in bytes.
+ *
+ * Hash algorithms process their input data in blocks. Hash operations will
+ * retain any partial blocks until they have enough input to fill the block or
+ * until the operation is finished.
+ * This affects the output from psa_hash_suspend().
+ *
+ * \param alg   A hash algorithm (\c PSA_ALG_XXX value such that
+ *              PSA_ALG_IS_HASH(\p alg) is true).
+ *
+ * \return      The block size in bytes for the specified hash algorithm.
+ *              If the hash algorithm is not recognized, return 0.
+ *              An implementation can return either 0 or the correct size for a
+ *              hash algorithm that it recognizes, but does not support.
+ */
+#define PSA_HASH_BLOCK_LENGTH(alg)                                  \
+    (                                                               \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD2 ? 16 :            \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD4 ? 64 :            \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD5 ? 64 :            \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_RIPEMD160 ? 64 :      \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_1 ? 64 :          \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_224 ? 64 :        \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_256 ? 64 :        \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_384 ? 128 :       \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512 ? 128 :       \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_224 ? 128 :   \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_256 ? 128 :   \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_224 ? 144 :      \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_256 ? 136 :      \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_384 ? 104 :      \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 72 :       \
+        0)
+
 /** \def PSA_HASH_MAX_SIZE
  *
  * Maximum size of a hash.
diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h
index 3c82f2a..fafe93c 100644
--- a/include/psa/crypto_values.h
+++ b/include/psa/crypto_values.h
@@ -421,6 +421,10 @@
  */
 #define PSA_KEY_TYPE_AES                            ((psa_key_type_t)0x2400)
 
+/** Key for a cipher, AEAD or MAC algorithm based on the
+ * ARIA block cipher. */
+#define PSA_KEY_TYPE_ARIA                           ((psa_key_type_t)0x2406)
+
 /** Key for a cipher or MAC algorithm based on DES or 3DES (Triple-DES).
  *
  * The size of the key can be 64 bits (single DES), 128 bits (2-key 3DES) or
@@ -786,6 +790,9 @@
 #define PSA_ALG_IS_KEY_DERIVATION(alg)                                  \
     (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_DERIVATION)
 
+/** An invalid algorithm identifier value. */
+#define PSA_ALG_NONE                            ((psa_algorithm_t)0)
+
 #define PSA_ALG_HASH_MASK                       ((psa_algorithm_t)0x000000ff)
 /** MD2 */
 #define PSA_ALG_MD2                             ((psa_algorithm_t)0x02000001)
@@ -833,7 +840,7 @@
  * algorithm parametrized with any supported hash.
  *
  * That is, suppose that `PSA_xxx_SIGNATURE` is one of the following macros:
- * - #PSA_ALG_RSA_PKCS1V15_SIGN, #PSA_ALG_RSA_PSS,
+ * - #PSA_ALG_RSA_PKCS1V15_SIGN, #PSA_ALG_RSA_PSS, #PSA_ALG_RSA_PSS_ANY_SALT,
  * - #PSA_ALG_ECDSA, #PSA_ALG_DETERMINISTIC_ECDSA.
  * Then you may create and use a key as follows:
  * - Set the key usage field using #PSA_ALG_ANY_HASH, for example:
@@ -1289,6 +1296,7 @@
     (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PKCS1V15_SIGN_BASE)
 
 #define PSA_ALG_RSA_PSS_BASE               ((psa_algorithm_t)0x06000300)
+#define PSA_ALG_RSA_PSS_ANY_SALT_BASE      ((psa_algorithm_t)0x06001300)
 /** RSA PSS signature with hashing.
  *
  * This is the signature scheme defined by RFC 8017
@@ -1309,9 +1317,72 @@
  */
 #define PSA_ALG_RSA_PSS(hash_alg)                               \
     (PSA_ALG_RSA_PSS_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
-#define PSA_ALG_IS_RSA_PSS(alg)                                 \
+
+/** RSA PSS signature with hashing with relaxed verification.
+ *
+ * This algorithm has the same behavior as #PSA_ALG_RSA_PSS when signing,
+ * but allows an arbitrary salt length (including \c 0) when verifying a
+ * signature.
+ *
+ * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
+ *                      #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *                      This includes #PSA_ALG_ANY_HASH
+ *                      when specifying the algorithm in a usage policy.
+ *
+ * \return              The corresponding RSA PSS signature algorithm.
+ * \return              Unspecified if \p hash_alg is not a supported
+ *                      hash algorithm.
+ */
+#define PSA_ALG_RSA_PSS_ANY_SALT(hash_alg)                      \
+    (PSA_ALG_RSA_PSS_ANY_SALT_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+
+/** Whether the specified algorithm is RSA PSS with standard salt.
+ *
+ * \param alg           An algorithm value or an algorithm policy wildcard.
+ *
+ * \return              1 if \p alg is of the form
+ *                      #PSA_ALG_RSA_PSS(\c hash_alg),
+ *                      where \c hash_alg is a hash algorithm or
+ *                      #PSA_ALG_ANY_HASH. 0 otherwise.
+ *                      This macro may return either 0 or 1 if \p alg is not
+ *                      a supported algorithm identifier or policy.
+ */
+#define PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg)                   \
     (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_BASE)
 
+/** Whether the specified algorithm is RSA PSS with any salt.
+ *
+ * \param alg           An algorithm value or an algorithm policy wildcard.
+ *
+ * \return              1 if \p alg is of the form
+ *                      #PSA_ALG_RSA_PSS_ANY_SALT_BASE(\c hash_alg),
+ *                      where \c hash_alg is a hash algorithm or
+ *                      #PSA_ALG_ANY_HASH. 0 otherwise.
+ *                      This macro may return either 0 or 1 if \p alg is not
+ *                      a supported algorithm identifier or policy.
+ */
+#define PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)                                \
+    (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_ANY_SALT_BASE)
+
+/** Whether the specified algorithm is RSA PSS.
+ *
+ * This includes any of the RSA PSS algorithm variants, regardless of the
+ * constraints on salt length.
+ *
+ * \param alg           An algorithm value or an algorithm policy wildcard.
+ *
+ * \return              1 if \p alg is of the form
+ *                      #PSA_ALG_RSA_PSS(\c hash_alg) or
+ *                      #PSA_ALG_RSA_PSS_ANY_SALT_BASE(\c hash_alg),
+ *                      where \c hash_alg is a hash algorithm or
+ *                      #PSA_ALG_ANY_HASH. 0 otherwise.
+ *                      This macro may return either 0 or 1 if \p alg is not
+ *                      a supported algorithm identifier or policy.
+ */
+#define PSA_ALG_IS_RSA_PSS(alg)                                 \
+    (PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg) ||                   \
+     PSA_ALG_IS_RSA_PSS_ANY_SALT(alg))
+
 #define PSA_ALG_ECDSA_BASE                      ((psa_algorithm_t)0x06000600)
 /** ECDSA signature with hashing.
  *
@@ -1469,20 +1540,24 @@
  * file. */
 #define PSA_ALG_IS_VENDOR_HASH_AND_SIGN(alg) 0
 
-/** Whether the specified algorithm is a hash-and-sign algorithm.
+/** Whether the specified algorithm is a signature algorithm that can be used
+ * with psa_sign_hash() and psa_verify_hash().
  *
- * Hash-and-sign algorithms are asymmetric (public-key) signature algorithms
- * structured in two parts: first the calculation of a hash in a way that
- * does not depend on the key, then the calculation of a signature from the
- * hash value and the key.
+ * This encompasses all strict hash-and-sign algorithms categorized by
+ * PSA_ALG_IS_HASH_AND_SIGN(), as well as algorithms that follow the
+ * paradigm more loosely:
+ * - #PSA_ALG_RSA_PKCS1V15_SIGN_RAW (expects its input to be an encoded hash)
+ * - #PSA_ALG_ECDSA_ANY (doesn't specify what kind of hash the input is)
  *
- * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ * \param alg An algorithm identifier (value of type psa_algorithm_t).
  *
- * \return 1 if \p alg is a hash-and-sign algorithm, 0 otherwise.
- *         This macro may return either 0 or 1 if \p alg is not a supported
- *         algorithm identifier.
+ * \return 1 if alg is a signature algorithm that can be used to sign a
+ *         hash. 0 if alg is a signature algorithm that can only be used
+ *         to sign a message. 0 if alg is not a signature algorithm.
+ *         This macro can return either 0 or 1 if alg is not a
+ *         supported algorithm identifier.
  */
-#define PSA_ALG_IS_HASH_AND_SIGN(alg)                                   \
+#define PSA_ALG_IS_SIGN_HASH(alg)                                       \
     (PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||    \
      PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_HASH_EDDSA(alg) ||             \
      PSA_ALG_IS_VENDOR_HASH_AND_SIGN(alg))
@@ -1499,7 +1574,37 @@
  *         supported algorithm identifier.
  */
 #define PSA_ALG_IS_SIGN_MESSAGE(alg)                                    \
-    (PSA_ALG_IS_HASH_AND_SIGN(alg) || (alg) == PSA_ALG_PURE_EDDSA )
+    (PSA_ALG_IS_SIGN_HASH(alg) || (alg) == PSA_ALG_PURE_EDDSA )
+
+/** Whether the specified algorithm is a hash-and-sign algorithm.
+ *
+ * Hash-and-sign algorithms are asymmetric (public-key) signature algorithms
+ * structured in two parts: first the calculation of a hash in a way that
+ * does not depend on the key, then the calculation of a signature from the
+ * hash value and the key. Hash-and-sign algorithms encode the hash
+ * used for the hashing step, and you can call #PSA_ALG_SIGN_GET_HASH
+ * to extract this algorithm.
+ *
+ * Thus, for a hash-and-sign algorithm,
+ * `psa_sign_message(key, alg, input, ...)` is equivalent to
+ * ```
+ * psa_hash_compute(PSA_ALG_SIGN_GET_HASH(alg), input, ..., hash, ...);
+ * psa_sign_hash(key, alg, hash, ..., signature, ...);
+ * ```
+ * Most usefully, separating the hash from the signature allows the hash
+ * to be calculated in multiple steps with psa_hash_setup(), psa_hash_update()
+ * and psa_hash_finish(). Likewise psa_verify_message() is equivalent to
+ * calculating the hash and then calling psa_verify_hash().
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a hash-and-sign algorithm, 0 otherwise.
+ *         This macro may return either 0 or 1 if \p alg is not a supported
+ *         algorithm identifier.
+ */
+#define PSA_ALG_IS_HASH_AND_SIGN(alg)                                   \
+    (PSA_ALG_IS_SIGN_HASH(alg) &&                                       \
+     ((alg) & PSA_ALG_HASH_MASK) != 0)
 
 /** Get the hash used by a hash-and-sign signature algorithm.
  *
@@ -1521,7 +1626,6 @@
  */
 #define PSA_ALG_SIGN_GET_HASH(alg)                                     \
     (PSA_ALG_IS_HASH_AND_SIGN(alg) ?                                   \
-     ((alg) & PSA_ALG_HASH_MASK) == 0 ? /*"raw" algorithm*/ 0 :        \
      ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH :             \
      0)
 
@@ -1939,6 +2043,9 @@
 
 #define PSA_KEY_LOCATION_VENDOR_FLAG            ((psa_key_location_t)0x800000)
 
+/** The null key identifier.
+ */
+#define PSA_KEY_ID_NULL                         ((psa_key_id_t)0)
 /** The minimum value for a key identifier chosen by the application.
  */
 #define PSA_KEY_ID_USER_MIN                     ((psa_key_id_t)0x00000001)
diff --git a/library/Makefile b/library/Makefile
index 6fdc927..ecdf93b 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -189,6 +189,14 @@
 
 shared: libmbedcrypto.$(DLEXT) libmbedx509.$(DLEXT) libmbedtls.$(DLEXT)
 
+# Windows builds under Mingw can fail if make tries to create archives in the same
+# directory at the same time - see https://bugs.launchpad.net/gcc-arm-embedded/+bug/1848002.
+# This forces builds of the .a files to be serialised.
+ifdef WINDOWS
+libmbedtls.a: | libmbedx509.a
+libmbedx509.a: | libmbedcrypto.a
+endif
+
 # tls
 libmbedtls.a: $(OBJS_TLS)
 	echo "  AR    $@"
@@ -202,7 +210,7 @@
 
 libmbedtls.$(SOEXT_TLS): $(OBJS_TLS) libmbedx509.so
 	echo "  LD    $@"
-	$(CC) -shared -Wl,-soname,$@ -L. -lmbedcrypto -lmbedx509 $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ $(OBJS_TLS)
+	$(CC) -shared -Wl,-soname,$@ -o $@ $(OBJS_TLS) -L. -lmbedx509 -lmbedcrypto $(LOCAL_LDFLAGS) $(LDFLAGS)
 
 libmbedtls.so: libmbedtls.$(SOEXT_TLS)
 	echo "  LN    $@ -> $<"
@@ -210,11 +218,11 @@
 
 libmbedtls.dylib: $(OBJS_TLS) libmbedx509.dylib
 	echo "  LD    $@"
-	$(CC) -dynamiclib -L. -lmbedcrypto -lmbedx509 $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ $(OBJS_TLS)
+	$(CC) -dynamiclib -o $@ $(OBJS_TLS) -L. -lmbedx509 -lmbedcrypto $(LOCAL_LDFLAGS) $(LDFLAGS)
 
 libmbedtls.dll: $(OBJS_TLS) libmbedx509.dll
 	echo "  LD    $@"
-	$(CC) -shared -Wl,-soname,$@ -Wl,--out-implib,$@.a -o $@ $(OBJS_TLS) -lws2_32 -lwinmm -lgdi32 -L. -lmbedcrypto -lmbedx509 -static-libgcc $(LOCAL_LDFLAGS) $(LDFLAGS)
+	$(CC) -shared -Wl,-soname,$@ -Wl,--out-implib,$@.a -o $@ $(OBJS_TLS) -lws2_32 -lwinmm -lgdi32 -L. -lmbedx509 -lmbedcrypto -static-libgcc $(LOCAL_LDFLAGS) $(LDFLAGS)
 
 # x509
 libmbedx509.a: $(OBJS_X509)
@@ -229,7 +237,7 @@
 
 libmbedx509.$(SOEXT_X509): $(OBJS_X509) libmbedcrypto.so
 	echo "  LD    $@"
-	$(CC) -shared -Wl,-soname,$@ -L. -lmbedcrypto $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ $(OBJS_X509)
+	$(CC) -shared -Wl,-soname,$@ -o $@ $(OBJS_X509) -L. -lmbedcrypto $(LOCAL_LDFLAGS) $(LDFLAGS)
 
 libmbedx509.so: libmbedx509.$(SOEXT_X509)
 	echo "  LN    $@ -> $<"
@@ -237,7 +245,7 @@
 
 libmbedx509.dylib: $(OBJS_X509) libmbedcrypto.dylib
 	echo "  LD    $@"
-	$(CC) -dynamiclib -L. -lmbedcrypto  $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ $(OBJS_X509)
+	$(CC) -dynamiclib -o $@ $(OBJS_X509) -L. -lmbedcrypto  $(LOCAL_LDFLAGS) $(LDFLAGS)
 
 libmbedx509.dll: $(OBJS_X509) libmbedcrypto.dll
 	echo "  LD    $@"
@@ -256,7 +264,7 @@
 
 libmbedcrypto.$(SOEXT_CRYPTO): $(OBJS_CRYPTO)
 	echo "  LD    $@"
-	$(CC) -shared -Wl,-soname,$@ $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ $(OBJS_CRYPTO)
+	$(CC) -shared -Wl,-soname,$@ -o $@ $(OBJS_CRYPTO) $(LOCAL_LDFLAGS) $(LDFLAGS)
 
 libmbedcrypto.so: libmbedcrypto.$(SOEXT_CRYPTO)
 	echo "  LN    $@ -> $<"
@@ -264,7 +272,7 @@
 
 libmbedcrypto.dylib: $(OBJS_CRYPTO)
 	echo "  LD    $@"
-	$(CC) -dynamiclib $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ $(OBJS_CRYPTO)
+	$(CC) -dynamiclib -o $@ $(OBJS_CRYPTO) $(LOCAL_LDFLAGS) $(LDFLAGS)
 
 libmbedcrypto.dll: $(OBJS_CRYPTO)
 	echo "  LD    $@"
diff --git a/library/aes.c b/library/aes.c
index 544b583..31824e7 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -903,7 +903,7 @@
                           const unsigned char input[16],
                           unsigned char output[16] )
 {
-    mbedtls_internal_aes_encrypt( ctx, input, output );
+    MBEDTLS_IGNORE_RETURN( mbedtls_internal_aes_encrypt( ctx, input, output ) );
 }
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
@@ -976,7 +976,7 @@
                           const unsigned char input[16],
                           unsigned char output[16] )
 {
-    mbedtls_internal_aes_decrypt( ctx, input, output );
+    MBEDTLS_IGNORE_RETURN( mbedtls_internal_aes_decrypt( ctx, input, output ) );
 }
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
@@ -1029,6 +1029,7 @@
                     unsigned char *output )
 {
     int i;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char temp[16];
 
     AES_VALIDATE_RET( ctx != NULL );
@@ -1058,7 +1059,9 @@
         while( length > 0 )
         {
             memcpy( temp, input, 16 );
-            mbedtls_aes_crypt_ecb( ctx, mode, input, output );
+            ret = mbedtls_aes_crypt_ecb( ctx, mode, input, output );
+            if( ret != 0 )
+                goto exit;
 
             for( i = 0; i < 16; i++ )
                 output[i] = (unsigned char)( output[i] ^ iv[i] );
@@ -1077,7 +1080,9 @@
             for( i = 0; i < 16; i++ )
                 output[i] = (unsigned char)( input[i] ^ iv[i] );
 
-            mbedtls_aes_crypt_ecb( ctx, mode, output, output );
+            ret = mbedtls_aes_crypt_ecb( ctx, mode, output, output );
+            if( ret != 0 )
+                goto exit;
             memcpy( iv, output, 16 );
 
             input  += 16;
@@ -1085,8 +1090,10 @@
             length -= 16;
         }
     }
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
 
@@ -1240,6 +1247,7 @@
                        unsigned char *output )
 {
     int c;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t n;
 
     AES_VALIDATE_RET( ctx != NULL );
@@ -1260,7 +1268,11 @@
         while( length-- )
         {
             if( n == 0 )
-                mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+            {
+                ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+                if( ret != 0 )
+                    goto exit;
+            }
 
             c = *input++;
             *output++ = (unsigned char)( c ^ iv[n] );
@@ -1274,7 +1286,11 @@
         while( length-- )
         {
             if( n == 0 )
-                mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+            {
+                ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+                if( ret != 0 )
+                    goto exit;
+            }
 
             iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
 
@@ -1283,8 +1299,10 @@
     }
 
     *iv_off = n;
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 
 /*
@@ -1297,6 +1315,7 @@
                             const unsigned char *input,
                             unsigned char *output )
 {
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char c;
     unsigned char ov[17];
 
@@ -1309,7 +1328,9 @@
     while( length-- )
     {
         memcpy( ov, iv, 16 );
-        mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+        ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+        if( ret != 0 )
+            goto exit;
 
         if( mode == MBEDTLS_AES_DECRYPT )
             ov[16] = *input;
@@ -1321,8 +1342,10 @@
 
         memcpy( iv, ov + 1, 16 );
     }
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 #endif /* MBEDTLS_CIPHER_MODE_CFB */
 
@@ -1384,6 +1407,7 @@
                        unsigned char *output )
 {
     int c, i;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t n;
 
     AES_VALIDATE_RET( ctx != NULL );
@@ -1401,7 +1425,9 @@
     while( length-- )
     {
         if( n == 0 ) {
-            mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
+            ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
+            if( ret != 0 )
+                goto exit;
 
             for( i = 16; i > 0; i-- )
                 if( ++nonce_counter[i - 1] != 0 )
@@ -1414,8 +1440,10 @@
     }
 
     *nc_off = n;
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 #endif /* MBEDTLS_CIPHER_MODE_CTR */
 
diff --git a/library/base64.c b/library/base64.c
index 9cf5dd4..a516c1d 100644
--- a/library/base64.c
+++ b/library/base64.c
@@ -22,6 +22,7 @@
 #if defined(MBEDTLS_BASE64_C)
 
 #include "mbedtls/base64.h"
+#include "base64_invasive.h"
 
 #include <stdint.h>
 
@@ -35,127 +36,41 @@
 #endif /* MBEDTLS_PLATFORM_C */
 #endif /* MBEDTLS_SELF_TEST */
 
-static const unsigned char base64_enc_map[64] =
-{
-    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
-    'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
-    'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
-    'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
-    'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
-    'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
-    '8', '9', '+', '/'
-};
-
-static const unsigned char base64_dec_map[128] =
-{
-    127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
-    127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
-    127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
-    127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
-    127, 127, 127,  62, 127, 127, 127,  63,  52,  53,
-     54,  55,  56,  57,  58,  59,  60,  61, 127, 127,
-    127,  64, 127, 127, 127,   0,   1,   2,   3,   4,
-      5,   6,   7,   8,   9,  10,  11,  12,  13,  14,
-     15,  16,  17,  18,  19,  20,  21,  22,  23,  24,
-     25, 127, 127, 127, 127, 127, 127,  26,  27,  28,
-     29,  30,  31,  32,  33,  34,  35,  36,  37,  38,
-     39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
-     49,  50,  51, 127, 127, 127, 127, 127
-};
-
 #define BASE64_SIZE_T_MAX   ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
 
-/*
- * Constant flow conditional assignment to unsigned char
+/* Return 0xff if low <= c <= high, 0 otherwise.
+ *
+ * Constant flow with respect to c.
  */
-static void mbedtls_base64_cond_assign_uchar( unsigned char * dest, const unsigned char * const src,
-                                       unsigned char condition )
+MBEDTLS_STATIC_TESTABLE
+unsigned char mbedtls_base64_mask_of_range( unsigned char low,
+                                            unsigned char high,
+                                            unsigned char c )
 {
-    /* MSVC has a warning about unary minus on unsigned integer types,
-     * but this is well-defined and precisely what we want to do here. */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-
-    /* Generate bitmask from condition, mask will either be 0xFF or 0 */
-    unsigned char mask = ( condition | -condition );
-    mask >>= 7;
-    mask = -mask;
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
-    *dest = ( ( *src ) & mask ) | ( ( *dest ) & ~mask );
+    /* low_mask is: 0 if low <= c, 0x...ff if low > c */
+    unsigned low_mask = ( (unsigned) c - low ) >> 8;
+    /* high_mask is: 0 if c <= high, 0x...ff if c > high */
+    unsigned high_mask = ( (unsigned) high - c ) >> 8;
+    return( ~( low_mask | high_mask ) & 0xff );
 }
 
-/*
- * Constant flow conditional assignment to uint_32
+/* Given a value in the range 0..63, return the corresponding Base64 digit.
+ * The implementation assumes that letters are consecutive (e.g. ASCII
+ * but not EBCDIC).
  */
-static void mbedtls_base64_cond_assign_uint32( uint32_t * dest, const uint32_t src,
-                                       uint32_t condition )
+MBEDTLS_STATIC_TESTABLE
+unsigned char mbedtls_base64_enc_char( unsigned char val )
 {
-    /* MSVC has a warning about unary minus on unsigned integer types,
-     * but this is well-defined and precisely what we want to do here. */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-
-    /* Generate bitmask from condition, mask will either be 0xFFFFFFFF or 0 */
-    uint32_t mask = ( condition | -condition );
-    mask >>= 31;
-    mask = -mask;
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
-    *dest = ( src & mask ) | ( ( *dest ) & ~mask );
-}
-
-/*
- * Constant flow check for equality
- */
-static unsigned char mbedtls_base64_eq( size_t in_a, size_t in_b )
-{
-    size_t difference = in_a ^ in_b;
-
-    /* MSVC has a warning about unary minus on unsigned integer types,
-     * but this is well-defined and precisely what we want to do here. */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-
-    difference |= -difference;
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
-    /* cope with the varying size of size_t per platform */
-    difference >>= ( sizeof( difference ) * 8 - 1 );
-
-    return (unsigned char) ( 1 ^ difference );
-}
-
-/*
- * Constant flow lookup into table.
- */
-static unsigned char mbedtls_base64_table_lookup( const unsigned char * const table,
-                                                 const size_t table_size, const size_t table_index )
-{
-    size_t i;
-    unsigned char result = 0;
-
-    for( i = 0; i < table_size; ++i )
-    {
-        mbedtls_base64_cond_assign_uchar( &result, &table[i], mbedtls_base64_eq( i, table_index ) );
-    }
-
-    return result;
+    unsigned char digit = 0;
+    /* For each range of values, if val is in that range, mask digit with
+     * the corresponding value. Since val can only be in a single range,
+     * only at most one masking will change digit. */
+    digit |= mbedtls_base64_mask_of_range(  0, 25, val ) & ( 'A' + val );
+    digit |= mbedtls_base64_mask_of_range( 26, 51, val ) & ( 'a' + val - 26 );
+    digit |= mbedtls_base64_mask_of_range( 52, 61, val ) & ( '0' + val - 52 );
+    digit |= mbedtls_base64_mask_of_range( 62, 62, val ) & '+';
+    digit |= mbedtls_base64_mask_of_range( 63, 63, val ) & '/';
+    return( digit );
 }
 
 /*
@@ -198,17 +113,12 @@
         C2 = *src++;
         C3 = *src++;
 
-        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
-                                            ( ( C1 >> 2 ) & 0x3F ) );
-
-        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
-                                            ( ( ( ( C1 &  3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ) );
-
-        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
-                                            ( ( ( ( C2 & 15 ) << 2 ) + ( C3 >> 6 ) ) & 0x3F ) );
-
-        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
-                                            ( C3 & 0x3F ) );
+        *p++ = mbedtls_base64_enc_char( ( C1 >> 2 ) & 0x3F );
+        *p++ = mbedtls_base64_enc_char( ( ( ( C1 &  3 ) << 4 ) + ( C2 >> 4 ) )
+                                        & 0x3F );
+        *p++ = mbedtls_base64_enc_char( ( ( ( C2 & 15 ) << 2 ) + ( C3 >> 6 ) )
+                                        & 0x3F );
+        *p++ = mbedtls_base64_enc_char( C3 & 0x3F );
     }
 
     if( i < slen )
@@ -216,15 +126,12 @@
         C1 = *src++;
         C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
 
-        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
-                                            ( ( C1 >> 2 ) & 0x3F ) );
-
-        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
-                                            ( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ) );
+        *p++ = mbedtls_base64_enc_char( ( C1 >> 2 ) & 0x3F );
+        *p++ = mbedtls_base64_enc_char( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) )
+                                        & 0x3F );
 
         if( ( i + 1 ) < slen )
-             *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
-                                                 ( ( ( C2 & 15 ) << 2 ) & 0x3F ) );
+             *p++ = mbedtls_base64_enc_char( ( ( C2 & 15 ) << 2 ) & 0x3F );
         else *p++ = '=';
 
         *p++ = '=';
@@ -236,26 +143,58 @@
     return( 0 );
 }
 
+/* Given a Base64 digit, return its value.
+ * If c is not a Base64 digit ('A'..'Z', 'a'..'z', '0'..'9', '+' or '/'),
+ * return -1.
+ *
+ * The implementation assumes that letters are consecutive (e.g. ASCII
+ * but not EBCDIC).
+ *
+ * The implementation is constant-flow (no branch or memory access depending
+ * on the value of c) unless the compiler inlines and optimizes a specific
+ * access.
+ */
+MBEDTLS_STATIC_TESTABLE
+signed char mbedtls_base64_dec_value( unsigned char c )
+{
+    unsigned char val = 0;
+    /* For each range of digits, if c is in that range, mask val with
+     * the corresponding value. Since c can only be in a single range,
+     * only at most one masking will change val. Set val to one plus
+     * the desired value so that it stays 0 if c is in none of the ranges. */
+    val |= mbedtls_base64_mask_of_range( 'A', 'Z', c ) & ( c - 'A' +  0 + 1 );
+    val |= mbedtls_base64_mask_of_range( 'a', 'z', c ) & ( c - 'a' + 26 + 1 );
+    val |= mbedtls_base64_mask_of_range( '0', '9', c ) & ( c - '0' + 52 + 1 );
+    val |= mbedtls_base64_mask_of_range( '+', '+', c ) & ( c - '+' + 62 + 1 );
+    val |= mbedtls_base64_mask_of_range( '/', '/', c ) & ( c - '/' + 63 + 1 );
+    /* At this point, val is 0 if c is an invalid digit and v+1 if c is
+     * a digit with the value v. */
+    return( val - 1 );
+}
+
 /*
  * Decode a base64-formatted buffer
  */
 int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
                    const unsigned char *src, size_t slen )
 {
-    size_t i, n;
-    uint32_t j, x;
+    size_t i; /* index in source */
+    size_t n; /* number of digits or trailing = in source */
+    uint32_t x; /* value accumulator */
+    unsigned accumulated_digits = 0;
+    unsigned equals = 0;
+    int spaces_present = 0;
     unsigned char *p;
-    unsigned char dec_map_lookup;
 
     /* First pass: check for validity and get output length */
-    for( i = n = j = 0; i < slen; i++ )
+    for( i = n = 0; i < slen; i++ )
     {
         /* Skip spaces before checking for EOL */
-        x = 0;
+        spaces_present = 0;
         while( i < slen && src[i] == ' ' )
         {
             ++i;
-            ++x;
+            spaces_present = 1;
         }
 
         /* Spaces at end of buffer are OK */
@@ -270,20 +209,24 @@
             continue;
 
         /* Space inside a line is an error */
-        if( x != 0 )
+        if( spaces_present )
             return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
 
-        if( src[i] == '=' && ++j > 2 )
+        if( src[i] > 127 )
             return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
 
-        dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), src[i] );
-
-        if( src[i] > 127 || dec_map_lookup == 127 )
-            return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
-
-        if( dec_map_lookup < 64 && j != 0 )
-            return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
-
+        if( src[i] == '=' )
+        {
+            if( ++equals > 2 )
+                return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
+        }
+        else
+        {
+            if( equals != 0 )
+                return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
+            if( mbedtls_base64_dec_value( src[i] ) < 0 )
+                return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
+        }
         n++;
     }
 
@@ -298,7 +241,7 @@
      *     n = ( ( n * 6 ) + 7 ) >> 3;
      */
     n = ( 6 * ( n >> 3 ) ) + ( ( 6 * ( n & 0x7 ) + 7 ) >> 3 );
-    n -= j;
+    n -= equals;
 
     if( dst == NULL || dlen < n )
     {
@@ -306,22 +249,24 @@
         return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
     }
 
-   for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
-   {
+    equals = 0;
+    for( x = 0, p = dst; i > 0; i--, src++ )
+    {
         if( *src == '\r' || *src == '\n' || *src == ' ' )
             continue;
 
-        dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), *src );
+        x = x << 6;
+        if( *src == '=' )
+            ++equals;
+        else
+            x |= mbedtls_base64_dec_value( *src );
 
-        mbedtls_base64_cond_assign_uint32( &j, j - 1, mbedtls_base64_eq( dec_map_lookup, 64 ) );
-        x  = ( x << 6 ) | ( dec_map_lookup & 0x3F );
-
-        if( ++n == 4 )
+        if( ++accumulated_digits == 4 )
         {
-            n = 0;
-            if( j > 0 ) *p++ = MBEDTLS_BYTE_2( x );
-            if( j > 1 ) *p++ = MBEDTLS_BYTE_1( x );
-            if( j > 2 ) *p++ = MBEDTLS_BYTE_0( x );
+            accumulated_digits = 0;
+            *p++ = MBEDTLS_BYTE_2( x );
+            if( equals <= 1 ) *p++ = MBEDTLS_BYTE_1( x );
+            if( equals <= 0 ) *p++ = MBEDTLS_BYTE_0( x );
         }
     }
 
diff --git a/library/base64_invasive.h b/library/base64_invasive.h
new file mode 100644
index 0000000..ed5f7cb
--- /dev/null
+++ b/library/base64_invasive.h
@@ -0,0 +1,55 @@
+/**
+ * \file base_invasive.h
+ *
+ * \brief Base64 module: interfaces for invasive testing only.
+ *
+ * The interfaces in this file are intended for testing purposes only.
+ * They SHOULD NOT be made available in library integrations except when
+ * building the library for testing.
+ */
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+#ifndef MBEDTLS_BASE64_INVASIVE_H
+#define MBEDTLS_BASE64_INVASIVE_H
+
+#include "common.h"
+
+#if defined(MBEDTLS_TEST_HOOKS)
+/* Return 0xff if low <= c <= high, 0 otherwise.
+ *
+ * Constant flow with respect to c.
+ */
+unsigned char mbedtls_base64_mask_of_range( unsigned char low,
+                                            unsigned char high,
+                                            unsigned char c );
+
+/* Given a value in the range 0..63, return the corresponding Base64 digit.
+ *
+ * Operates in constant time (no branches or memory access depending on val).
+ */
+unsigned char mbedtls_base64_enc_char( unsigned char val );
+
+/* Given a Base64 digit, return its value.
+ * If c is not a Base64 digit ('A'..'Z', 'a'..'z', '0'..'9', '+' or '/'),
+ * return -1.
+ *
+ * Operates in constant time (no branches or memory access depending on c).
+ */
+signed char mbedtls_base64_dec_value( unsigned char c );
+#endif /* MBEDTLS_TEST_HOOKS */
+
+#endif /* MBEDTLS_BASE64_INVASIVE_H */
diff --git a/library/cipher.c b/library/cipher.c
index 457f8f6..b956030 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -1246,9 +1246,12 @@
         if( status != PSA_SUCCESS )
             return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
 
-        status = psa_cipher_set_iv( &cipher_op, iv, iv_len );
-        if( status != PSA_SUCCESS )
-            return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+        if( ctx->cipher_info->mode != MBEDTLS_MODE_ECB )
+        {
+            status = psa_cipher_set_iv( &cipher_op, iv, iv_len );
+            if( status != PSA_SUCCESS )
+                return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+        }
 
         status = psa_cipher_update( &cipher_op,
                                     input, ilen,
diff --git a/library/des.c b/library/des.c
index 7f90faa..91d22b5 100644
--- a/library/des.c
+++ b/library/des.c
@@ -28,6 +28,7 @@
 #if defined(MBEDTLS_DES_C)
 
 #include "mbedtls/des.h"
+#include "mbedtls/error.h"
 #include "mbedtls/platform_util.h"
 
 #include <string.h>
@@ -642,6 +643,7 @@
                     unsigned char *output )
 {
     int i;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char temp[8];
 
     if( length % 8 )
@@ -654,7 +656,9 @@
             for( i = 0; i < 8; i++ )
                 output[i] = (unsigned char)( input[i] ^ iv[i] );
 
-            mbedtls_des_crypt_ecb( ctx, output, output );
+            ret = mbedtls_des_crypt_ecb( ctx, output, output );
+            if( ret != 0 )
+                goto exit;
             memcpy( iv, output, 8 );
 
             input  += 8;
@@ -667,7 +671,9 @@
         while( length > 0 )
         {
             memcpy( temp, input, 8 );
-            mbedtls_des_crypt_ecb( ctx, input, output );
+            ret = mbedtls_des_crypt_ecb( ctx, input, output );
+            if( ret != 0 )
+                goto exit;
 
             for( i = 0; i < 8; i++ )
                 output[i] = (unsigned char)( output[i] ^ iv[i] );
@@ -679,8 +685,10 @@
             length -= 8;
         }
     }
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
 
@@ -741,6 +749,7 @@
                      unsigned char *output )
 {
     int i;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char temp[8];
 
     if( length % 8 )
@@ -753,7 +762,9 @@
             for( i = 0; i < 8; i++ )
                 output[i] = (unsigned char)( input[i] ^ iv[i] );
 
-            mbedtls_des3_crypt_ecb( ctx, output, output );
+            ret = mbedtls_des3_crypt_ecb( ctx, output, output );
+            if( ret != 0 )
+                goto exit;
             memcpy( iv, output, 8 );
 
             input  += 8;
@@ -766,7 +777,9 @@
         while( length > 0 )
         {
             memcpy( temp, input, 8 );
-            mbedtls_des3_crypt_ecb( ctx, input, output );
+            ret = mbedtls_des3_crypt_ecb( ctx, input, output );
+            if( ret != 0 )
+                goto exit;
 
             for( i = 0; i < 8; i++ )
                 output[i] = (unsigned char)( output[i] ^ iv[i] );
@@ -778,8 +791,10 @@
             length -= 8;
         }
     }
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
 
@@ -872,39 +887,43 @@
         switch( i )
         {
         case 0:
-            mbedtls_des_setkey_dec( &ctx, des3_test_keys );
+            ret = mbedtls_des_setkey_dec( &ctx, des3_test_keys );
             break;
 
         case 1:
-            mbedtls_des_setkey_enc( &ctx, des3_test_keys );
+            ret = mbedtls_des_setkey_enc( &ctx, des3_test_keys );
             break;
 
         case 2:
-            mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
             break;
 
         case 3:
-            mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
             break;
 
         case 4:
-            mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
             break;
 
         case 5:
-            mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
             break;
 
         default:
             return( 1 );
         }
+        if( ret != 0 )
+            goto exit;
 
         for( j = 0; j < 100; j++ )
         {
             if( u == 0 )
-                mbedtls_des_crypt_ecb( &ctx, buf, buf );
+                ret = mbedtls_des_crypt_ecb( &ctx, buf, buf );
             else
-                mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
+                ret = mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
+            if( ret != 0 )
+                goto exit;
         }
 
         if( ( v == MBEDTLS_DES_DECRYPT &&
@@ -947,41 +966,45 @@
         switch( i )
         {
         case 0:
-            mbedtls_des_setkey_dec( &ctx, des3_test_keys );
+            ret = mbedtls_des_setkey_dec( &ctx, des3_test_keys );
             break;
 
         case 1:
-            mbedtls_des_setkey_enc( &ctx, des3_test_keys );
+            ret = mbedtls_des_setkey_enc( &ctx, des3_test_keys );
             break;
 
         case 2:
-            mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
             break;
 
         case 3:
-            mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
             break;
 
         case 4:
-            mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
             break;
 
         case 5:
-            mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
             break;
 
         default:
             return( 1 );
         }
+        if( ret != 0 )
+            goto exit;
 
         if( v == MBEDTLS_DES_DECRYPT )
         {
             for( j = 0; j < 100; j++ )
             {
                 if( u == 0 )
-                    mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
+                    ret = mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
                 else
-                    mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
+                    ret = mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
+                if( ret != 0 )
+                    goto exit;
             }
         }
         else
@@ -991,9 +1014,11 @@
                 unsigned char tmp[8];
 
                 if( u == 0 )
-                    mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
+                    ret = mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
                 else
-                    mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
+                    ret = mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
+                if( ret != 0 )
+                    goto exit;
 
                 memcpy( tmp, prv, 8 );
                 memcpy( prv, buf, 8 );
@@ -1027,6 +1052,8 @@
     mbedtls_des_free( &ctx );
     mbedtls_des3_free( &ctx3 );
 
+    if( ret != 0 )
+        ret = 1;
     return( ret );
 }
 
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 3a24bfc..3c75989 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -516,6 +516,12 @@
                 return( PSA_ERROR_INVALID_ARGUMENT );
             break;
 #endif
+#if defined(PSA_WANT_KEY_TYPE_ARIA)
+        case PSA_KEY_TYPE_ARIA:
+            if( bits != 128 && bits != 192 && bits != 256 )
+                return( PSA_ERROR_INVALID_ARGUMENT );
+            break;
+#endif
 #if defined(PSA_WANT_KEY_TYPE_CAMELLIA)
         case PSA_KEY_TYPE_CAMELLIA:
             if( bits != 128 && bits != 192 && bits != 256 )
@@ -699,8 +705,8 @@
         return( alg1 );
     /* If the policies are from the same hash-and-sign family, check
      * if one is a wildcard. If so the other has the specific algorithm. */
-    if( PSA_ALG_IS_HASH_AND_SIGN( alg1 ) &&
-        PSA_ALG_IS_HASH_AND_SIGN( alg2 ) &&
+    if( PSA_ALG_IS_SIGN_HASH( alg1 ) &&
+        PSA_ALG_IS_SIGN_HASH( alg2 ) &&
         ( alg1 & ~PSA_ALG_HASH_MASK ) == ( alg2 & ~PSA_ALG_HASH_MASK ) )
     {
         if( PSA_ALG_SIGN_GET_HASH( alg1 ) == PSA_ALG_ANY_HASH )
@@ -802,7 +808,7 @@
     /* If policy_alg is a hash-and-sign with a wildcard for the hash,
      * and requested_alg is the same hash-and-sign family with any hash,
      * then requested_alg is compliant with policy_alg. */
-    if( PSA_ALG_IS_HASH_AND_SIGN( requested_alg ) &&
+    if( PSA_ALG_IS_SIGN_HASH( requested_alg ) &&
         PSA_ALG_SIGN_GET_HASH( policy_alg ) == PSA_ALG_ANY_HASH )
     {
         return( ( policy_alg & ~PSA_ALG_HASH_MASK ) ==
@@ -2398,7 +2404,7 @@
     status = psa_get_and_lock_key_slot_with_policy(
                  key,
                  &slot,
-                 is_sign ? PSA_KEY_USAGE_SIGN_HASH : PSA_KEY_USAGE_VERIFY_HASH,
+                 is_sign ? PSA_KEY_USAGE_SIGN_MESSAGE : PSA_KEY_USAGE_VERIFY_MESSAGE,
                  alg );
     if( status != PSA_SUCCESS )
         goto exit;
@@ -2583,8 +2589,9 @@
     uint8_t operation_mac_size = 0;
 
     status = psa_get_and_lock_key_slot_with_policy(
-                 key, &slot,
-                 is_sign ? PSA_KEY_USAGE_SIGN_HASH : PSA_KEY_USAGE_VERIFY_HASH,
+                 key,
+                 &slot,
+                 is_sign ? PSA_KEY_USAGE_SIGN_MESSAGE : PSA_KEY_USAGE_VERIFY_MESSAGE,
                  alg );
     if( status != PSA_SUCCESS )
         goto exit;
@@ -2691,7 +2698,7 @@
         if( ! PSA_ALG_IS_SIGN_MESSAGE( alg ) )
             return( PSA_ERROR_INVALID_ARGUMENT );
 
-        if ( PSA_ALG_IS_HASH_AND_SIGN( alg ) )
+        if ( PSA_ALG_IS_SIGN_HASH( alg ) )
         {
             if( ! PSA_ALG_IS_HASH( PSA_ALG_SIGN_GET_HASH( alg ) ) )
                 return( PSA_ERROR_INVALID_ARGUMENT );
@@ -2699,7 +2706,7 @@
     }
     else
     {
-        if( ! PSA_ALG_IS_HASH_AND_SIGN( alg ) )
+        if( ! PSA_ALG_IS_SIGN_HASH( alg ) )
             return( PSA_ERROR_INVALID_ARGUMENT );
     }
 
@@ -2849,7 +2856,7 @@
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
 
-    if ( PSA_ALG_IS_HASH_AND_SIGN( alg ) )
+    if ( PSA_ALG_IS_SIGN_HASH( alg ) )
     {
         size_t hash_length;
         uint8_t hash[PSA_HASH_MAX_SIZE];
@@ -2896,7 +2903,7 @@
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
 
-    if ( PSA_ALG_IS_HASH_AND_SIGN( alg ) )
+    if ( PSA_ALG_IS_SIGN_HASH( alg ) )
     {
         size_t hash_length;
         uint8_t hash[PSA_HASH_MAX_SIZE];
@@ -4275,6 +4282,9 @@
     if( psa_get_key_bits( attributes ) == 0 )
         return( PSA_ERROR_INVALID_ARGUMENT );
 
+    if( operation->alg == PSA_ALG_NONE )
+        return( PSA_ERROR_BAD_STATE );
+
     if( ! operation->can_output_key )
         return( PSA_ERROR_NOT_PERMITTED );
 
@@ -5229,6 +5239,10 @@
     if( psa_get_key_bits( attributes ) == 0 )
         return( PSA_ERROR_INVALID_ARGUMENT );
 
+    /* Reject any attempt to create a public key. */
+    if( PSA_KEY_TYPE_IS_PUBLIC_KEY(attributes->core.type) )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
     status = psa_start_key_creation( PSA_KEY_CREATION_GENERATE, attributes,
                                      &slot, &driver );
     if( status != PSA_SUCCESS )
diff --git a/library/psa_crypto_aead.c b/library/psa_crypto_aead.c
index 356679c..99f2e4d 100644
--- a/library/psa_crypto_aead.c
+++ b/library/psa_crypto_aead.c
@@ -224,7 +224,16 @@
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
     if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 )
     {
-        if( nonce_length != 12 || operation.tag_length != 16 )
+        if( nonce_length != 12 )
+        {
+            if( nonce_length == 8 )
+                status = PSA_ERROR_NOT_SUPPORTED;
+            else
+                status = PSA_ERROR_INVALID_ARGUMENT;
+            goto exit;
+        }
+
+        if( operation.tag_length != 16 )
         {
             status = PSA_ERROR_NOT_SUPPORTED;
             goto exit;
@@ -331,7 +340,16 @@
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
     if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 )
     {
-        if( nonce_length != 12 || operation.tag_length != 16 )
+        if( nonce_length != 12 )
+        {
+            if( nonce_length == 8 )
+                status = PSA_ERROR_NOT_SUPPORTED;
+            else
+                status = PSA_ERROR_INVALID_ARGUMENT;
+            goto exit;
+        }
+
+        if( operation.tag_length != 16 )
         {
             status = PSA_ERROR_NOT_SUPPORTED;
             goto exit;
diff --git a/library/psa_crypto_cipher.c b/library/psa_crypto_cipher.c
index 6c4150b..713c3d1 100644
--- a/library/psa_crypto_cipher.c
+++ b/library/psa_crypto_cipher.c
@@ -115,6 +115,9 @@
         case PSA_KEY_TYPE_AES:
             cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
             break;
+        case PSA_KEY_TYPE_ARIA:
+            cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA;
+            break;
         case PSA_KEY_TYPE_DES:
             /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
              * and 192 for three-key Triple-DES. */
diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c
index 135fa35..7e0a832 100644
--- a/library/psa_crypto_mac.c
+++ b/library/psa_crypto_mac.c
@@ -42,33 +42,6 @@
 #endif
 
 #if defined(BUILTIN_ALG_HMAC)
-static size_t psa_get_hash_block_size( psa_algorithm_t alg )
-{
-    switch( alg )
-    {
-        case PSA_ALG_MD2:
-            return( 16 );
-        case PSA_ALG_MD4:
-            return( 64 );
-        case PSA_ALG_MD5:
-            return( 64 );
-        case PSA_ALG_RIPEMD160:
-            return( 64 );
-        case PSA_ALG_SHA_1:
-            return( 64 );
-        case PSA_ALG_SHA_224:
-            return( 64 );
-        case PSA_ALG_SHA_256:
-            return( 64 );
-        case PSA_ALG_SHA_384:
-            return( 128 );
-        case PSA_ALG_SHA_512:
-            return( 128 );
-        default:
-            return( 0 );
-    }
-}
-
 static psa_status_t psa_hmac_abort_internal(
     mbedtls_psa_hmac_operation_t *hmac )
 {
@@ -85,7 +58,7 @@
     uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
     size_t i;
     size_t hash_size = PSA_HASH_LENGTH( hash_alg );
-    size_t block_size = psa_get_hash_block_size( hash_alg );
+    size_t block_size = PSA_HASH_BLOCK_LENGTH( hash_alg );
     psa_status_t status;
 
     hmac->alg = hash_alg;
@@ -157,7 +130,7 @@
     uint8_t tmp[MBEDTLS_MD_MAX_SIZE];
     psa_algorithm_t hash_alg = hmac->alg;
     size_t hash_size = 0;
-    size_t block_size = psa_get_hash_block_size( hash_alg );
+    size_t block_size = PSA_HASH_BLOCK_LENGTH( hash_alg );
     psa_status_t status;
 
     status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
diff --git a/library/psa_crypto_rsa.c b/library/psa_crypto_rsa.c
index 80b9985..3b71913 100644
--- a/library/psa_crypto_rsa.c
+++ b/library/psa_crypto_rsa.c
@@ -447,6 +447,27 @@
     return( status );
 }
 
+#if defined(BUILTIN_ALG_RSA_PSS)
+static int rsa_pss_expected_salt_len( psa_algorithm_t alg,
+                                      const mbedtls_rsa_context *rsa,
+                                      size_t hash_length )
+{
+    if( PSA_ALG_IS_RSA_PSS_ANY_SALT( alg ) )
+        return( MBEDTLS_RSA_SALT_LEN_ANY );
+    /* Otherwise: standard salt length, i.e. largest possible salt length
+     * up to the hash length. */
+    int klen = (int) mbedtls_rsa_get_len( rsa ); // known to fit
+    int hlen = (int) hash_length; // known to fit
+    int room = klen - 2 - hlen;
+    if( room < 0 )
+        return( 0 ); // there is no valid signature in this case anyway
+    else if( room > hlen )
+        return( hlen );
+    else
+        return( room );
+}
+#endif
+
 static psa_status_t rsa_verify_hash(
     const psa_key_attributes_t *attributes,
     const uint8_t *key_buffer, size_t key_buffer_size,
@@ -494,15 +515,18 @@
 #if defined(BUILTIN_ALG_RSA_PSS)
     if( PSA_ALG_IS_RSA_PSS( alg ) )
     {
+        int slen = rsa_pss_expected_salt_len( alg, rsa, hash_length );
         mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
-        ret = mbedtls_rsa_rsassa_pss_verify( rsa,
-                                             mbedtls_psa_get_random,
-                                             MBEDTLS_PSA_RANDOM_STATE,
-                                             MBEDTLS_RSA_PUBLIC,
-                                             md_alg,
-                                             (unsigned int) hash_length,
-                                             hash,
-                                             signature );
+        ret = mbedtls_rsa_rsassa_pss_verify_ext( rsa,
+                                                 mbedtls_psa_get_random,
+                                                 MBEDTLS_PSA_RANDOM_STATE,
+                                                 MBEDTLS_RSA_PUBLIC,
+                                                 md_alg,
+                                                 (unsigned int) hash_length,
+                                                 hash,
+                                                 md_alg,
+                                                 slen,
+                                                 signature );
     }
     else
 #endif /* BUILTIN_ALG_RSA_PSS */
diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c
index 76d7a07..6f69fc8 100644
--- a/library/psa_crypto_slot_management.c
+++ b/library/psa_crypto_slot_management.c
@@ -481,7 +481,8 @@
 
 psa_status_t psa_open_key( mbedtls_svc_key_id_t key, psa_key_handle_t *handle )
 {
-#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
+#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) || \
+    defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)
     psa_status_t status;
     psa_key_slot_t *slot;
 
@@ -499,11 +500,11 @@
 
     return( psa_unlock_key_slot( slot ) );
 
-#else /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
+#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
     (void) key;
     *handle = PSA_KEY_HANDLE_INIT;
     return( PSA_ERROR_NOT_SUPPORTED );
-#endif /* !defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
+#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
 }
 
 psa_status_t psa_close_key( psa_key_handle_t handle )
diff --git a/library/version_features.c b/library/version_features.c
index f665a23..40c9520 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -267,6 +267,9 @@
 #if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY)
     "MBEDTLS_CAMELLIA_SMALL_MEMORY",
 #endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
+#if defined(MBEDTLS_CHECK_RETURN_WARNING)
+    "MBEDTLS_CHECK_RETURN_WARNING",
+#endif /* MBEDTLS_CHECK_RETURN_WARNING */
 #if defined(MBEDTLS_CIPHER_MODE_CBC)
     "MBEDTLS_CIPHER_MODE_CBC",
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
diff --git a/programs/.gitignore b/programs/.gitignore
index 9816c34..5d3c5bd 100644
--- a/programs/.gitignore
+++ b/programs/.gitignore
@@ -53,6 +53,7 @@
 ssl/ssl_server2
 test/benchmark
 test/cpp_dummy_build
+test/cpp_dummy_build.cpp
 test/ecp-bench
 test/query_compile_time_config
 test/selftest
@@ -65,6 +66,7 @@
 x509/cert_req
 x509/cert_write
 x509/crl_app
+x509/load_roots
 x509/req_app
 
 # generated files
diff --git a/programs/Makefile b/programs/Makefile
index 8cd27ea..550887a 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -106,6 +106,7 @@
 	x509/cert_req$(EXEXT) \
 	x509/cert_write$(EXEXT) \
 	x509/crl_app$(EXEXT) \
+	x509/load_roots$(EXEXT) \
 	x509/req_app$(EXEXT) \
 # End of APPS
 
@@ -309,6 +310,10 @@
 	echo "  CC    test/benchmark.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/benchmark.c   $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
+test/cpp_dummy_build.cpp: test/generate_cpp_dummy_build.sh
+	echo "  Gen   test/cpp_dummy_build.cpp"
+	test/generate_cpp_dummy_build.sh
+
 test/cpp_dummy_build$(EXEXT): test/cpp_dummy_build.cpp $(DEP)
 	echo "  CXX   test/cpp_dummy_build.cpp"
 	$(CXX) $(LOCAL_CXXFLAGS) $(CXXFLAGS) test/cpp_dummy_build.cpp   $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
@@ -357,6 +362,10 @@
 	echo "  CC    x509/cert_req.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) x509/cert_req.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
+x509/load_roots$(EXEXT): x509/load_roots.c $(DEP)
+	echo "  CC    x509/load_roots.c"
+	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) x509/load_roots.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+
 x509/req_app$(EXEXT): x509/req_app.c $(DEP)
 	echo "  CC    x509/req_app.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) x509/req_app.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
@@ -369,10 +378,11 @@
 ifndef WINDOWS
 	rm -f $(APPS)
 	-rm -f ssl/ssl_pthread_server$(EXEXT)
-	-rm -f test/cpp_dummy_build$(EXEXT)
+	-rm -f test/cpp_dummy_build.cpp test/cpp_dummy_build$(EXEXT)
 else
 	if exist *.o del /Q /F *.o
 	if exist *.exe del /Q /F *.exe
+	if exist test\cpp_dummy_build.cpp del /Q /F test\cpp_dummy_build.cpp
 endif
 	$(MAKE) -C fuzz clean
 
diff --git a/programs/pkey/dh_client.c b/programs/pkey/dh_client.c
index d6e4990..f6c6226 100644
--- a/programs/pkey/dh_client.c
+++ b/programs/pkey/dh_client.c
@@ -274,7 +274,9 @@
     mbedtls_printf( "...\n  . Receiving and decrypting the ciphertext" );
     fflush( stdout );
 
-    mbedtls_aes_setkey_dec( &aes, buf, 256 );
+    ret = mbedtls_aes_setkey_dec( &aes, buf, 256 );
+    if( ret != 0 )
+        goto exit;
 
     memset( buf, 0, sizeof( buf ) );
 
@@ -284,7 +286,9 @@
         goto exit;
     }
 
-    mbedtls_aes_crypt_ecb( &aes, MBEDTLS_AES_DECRYPT, buf, buf );
+    ret = mbedtls_aes_crypt_ecb( &aes, MBEDTLS_AES_DECRYPT, buf, buf );
+    if( ret != 0 )
+        goto exit;
     buf[16] = '\0';
     mbedtls_printf( "\n  . Plaintext is \"%s\"\n\n", (char *) buf );
 
diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c
index dccf095..8f032a3 100644
--- a/programs/pkey/dh_server.c
+++ b/programs/pkey/dh_server.c
@@ -295,9 +295,13 @@
     mbedtls_printf( "...\n  . Encrypting and sending the ciphertext" );
     fflush( stdout );
 
-    mbedtls_aes_setkey_enc( &aes, buf, 256 );
+    ret = mbedtls_aes_setkey_enc( &aes, buf, 256 );
+    if( ret != 0 )
+        goto exit;
     memcpy( buf, PLAINTEXT, 16 );
-    mbedtls_aes_crypt_ecb( &aes, MBEDTLS_AES_ENCRYPT, buf, buf );
+    ret = mbedtls_aes_crypt_ecb( &aes, MBEDTLS_AES_ENCRYPT, buf, buf );
+    if( ret != 0 )
+        goto exit;
 
     if( ( ret = mbedtls_net_send( &client_fd, buf, 16 ) ) != 16 )
     {
diff --git a/programs/pkey/key_app_writer.c b/programs/pkey/key_app_writer.c
index 6a4d0e4..0d531ea 100644
--- a/programs/pkey/key_app_writer.c
+++ b/programs/pkey/key_app_writer.c
@@ -197,7 +197,9 @@
 {
     int ret = 1;
     int exit_code = MBEDTLS_EXIT_FAILURE;
-    char buf[1024];
+#if defined(MBEDTLS_ERROR_C)
+    char buf[200];
+#endif
     int i;
     char *p, *q;
 
@@ -208,7 +210,9 @@
      * Set to sane values
      */
     mbedtls_pk_init( &key );
+#if defined(MBEDTLS_ERROR_C)
     memset( buf, 0, sizeof( buf ) );
+#endif
 
     mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q );
     mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &DP );
@@ -296,8 +300,7 @@
 
         if( ret != 0 )
         {
-            mbedtls_strerror( ret, (char *) buf, sizeof(buf) );
-            mbedtls_printf( " failed\n  !  mbedtls_pk_parse_keyfile returned -0x%04x - %s\n\n", (unsigned int) -ret, buf );
+            mbedtls_printf( " failed\n  !  mbedtls_pk_parse_keyfile returned -0x%04x", (unsigned int) -ret );
             goto exit;
         }
 
@@ -357,8 +360,7 @@
 
         if( ret != 0 )
         {
-            mbedtls_strerror( ret, (char *) buf, sizeof(buf) );
-            mbedtls_printf( " failed\n  !  mbedtls_pk_parse_public_key returned -0x%04x - %s\n\n", (unsigned int) -ret, buf );
+            mbedtls_printf( " failed\n  !  mbedtls_pk_parse_public_key returned -0x%04x", (unsigned int) -ret );
             goto exit;
         }
 
diff --git a/programs/psa/psa_constant_names_generated.c b/programs/psa/psa_constant_names_generated.c
index bebb97c..de29716 100644
--- a/programs/psa/psa_constant_names_generated.c
+++ b/programs/psa/psa_constant_names_generated.c
@@ -96,6 +96,7 @@
     switch (type) {
     case PSA_KEY_TYPE_AES: append(&buffer, buffer_size, &required_size, "PSA_KEY_TYPE_AES", 16); break;
     case PSA_KEY_TYPE_ARC4: append(&buffer, buffer_size, &required_size, "PSA_KEY_TYPE_ARC4", 17); break;
+    case PSA_KEY_TYPE_ARIA: append(&buffer, buffer_size, &required_size, "PSA_KEY_TYPE_ARIA", 17); break;
     case PSA_KEY_TYPE_CAMELLIA: append(&buffer, buffer_size, &required_size, "PSA_KEY_TYPE_CAMELLIA", 21); break;
     case PSA_KEY_TYPE_CATEGORY_FLAG_PAIR: append(&buffer, buffer_size, &required_size, "PSA_KEY_TYPE_CATEGORY_FLAG_PAIR", 31); break;
     case PSA_KEY_TYPE_CATEGORY_KEY_PAIR: append(&buffer, buffer_size, &required_size, "PSA_KEY_TYPE_CATEGORY_KEY_PAIR", 30); break;
@@ -220,12 +221,14 @@
     case PSA_ALG_MD2: append(&buffer, buffer_size, &required_size, "PSA_ALG_MD2", 11); break;
     case PSA_ALG_MD4: append(&buffer, buffer_size, &required_size, "PSA_ALG_MD4", 11); break;
     case PSA_ALG_MD5: append(&buffer, buffer_size, &required_size, "PSA_ALG_MD5", 11); break;
+    case PSA_ALG_NONE: append(&buffer, buffer_size, &required_size, "PSA_ALG_NONE", 12); break;
     case PSA_ALG_OFB: append(&buffer, buffer_size, &required_size, "PSA_ALG_OFB", 11); break;
     case PSA_ALG_PURE_EDDSA: append(&buffer, buffer_size, &required_size, "PSA_ALG_PURE_EDDSA", 18); break;
     case PSA_ALG_RIPEMD160: append(&buffer, buffer_size, &required_size, "PSA_ALG_RIPEMD160", 17); break;
     case PSA_ALG_RSA_OAEP_BASE: append(&buffer, buffer_size, &required_size, "PSA_ALG_RSA_OAEP_BASE", 21); break;
     case PSA_ALG_RSA_PKCS1V15_CRYPT: append(&buffer, buffer_size, &required_size, "PSA_ALG_RSA_PKCS1V15_CRYPT", 26); break;
     case PSA_ALG_RSA_PKCS1V15_SIGN_RAW: append(&buffer, buffer_size, &required_size, "PSA_ALG_RSA_PKCS1V15_SIGN_RAW", 29); break;
+    case PSA_ALG_RSA_PSS_ANY_SALT_BASE: append(&buffer, buffer_size, &required_size, "PSA_ALG_RSA_PSS_ANY_SALT_BASE", 29); break;
     case PSA_ALG_RSA_PSS_BASE: append(&buffer, buffer_size, &required_size, "PSA_ALG_RSA_PSS_BASE", 20); break;
     case PSA_ALG_SHA3_224: append(&buffer, buffer_size, &required_size, "PSA_ALG_SHA3_224", 16); break;
     case PSA_ALG_SHA3_256: append(&buffer, buffer_size, &required_size, "PSA_ALG_SHA3_256", 16); break;
@@ -300,13 +303,20 @@
                             psa_hash_algorithm_name,
                             PSA_ALG_GET_HASH(core_alg));
             append(&buffer, buffer_size, &required_size, ")", 1);
-        } else if (PSA_ALG_IS_RSA_PSS(core_alg)) {
+        } else if (PSA_ALG_IS_RSA_PSS_STANDARD_SALT(core_alg)) {
             append(&buffer, buffer_size, &required_size,
                    "PSA_ALG_RSA_PSS(", 15 + 1);
             append_with_alg(&buffer, buffer_size, &required_size,
                             psa_hash_algorithm_name,
                             PSA_ALG_GET_HASH(core_alg));
             append(&buffer, buffer_size, &required_size, ")", 1);
+        } else if (PSA_ALG_IS_RSA_PSS_ANY_SALT(core_alg)) {
+            append(&buffer, buffer_size, &required_size,
+                   "PSA_ALG_RSA_PSS_ANY_SALT(", 24 + 1);
+            append_with_alg(&buffer, buffer_size, &required_size,
+                            psa_hash_algorithm_name,
+                            PSA_ALG_GET_HASH(core_alg));
+            append(&buffer, buffer_size, &required_size, ")", 1);
         } else if (PSA_ALG_IS_TLS12_PRF(core_alg)) {
             append(&buffer, buffer_size, &required_size,
                    "PSA_ALG_TLS12_PRF(", 17 + 1);
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 3937981..574caa6 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -19,6 +19,10 @@
 
 #include "ssl_test_lib.h"
 
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "test/psa_crypto_helpers.h"
+#endif
+
 #if defined(MBEDTLS_SSL_TEST_IMPOSSIBLE)
 int main( void )
 {
@@ -2997,6 +3001,19 @@
 
     mbedtls_net_free( &server_fd );
 
+    mbedtls_ssl_free( &ssl );
+    mbedtls_ssl_config_free( &conf );
+    mbedtls_ssl_session_free( &saved_session );
+
+    if( session_data != NULL )
+        mbedtls_platform_zeroize( session_data, session_data_len );
+    mbedtls_free( session_data );
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+    if( context_buf != NULL )
+        mbedtls_platform_zeroize( context_buf, context_buf_len );
+    mbedtls_free( context_buf );
+#endif
+
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
     mbedtls_x509_crt_free( &clicert );
     mbedtls_x509_crt_free( &cacert );
@@ -3027,23 +3044,25 @@
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED &&
           MBEDTLS_USE_PSA_CRYPTO */
 
-    mbedtls_ssl_session_free( &saved_session );
-    mbedtls_ssl_free( &ssl );
-    mbedtls_ssl_config_free( &conf );
-    rng_free( &rng );
-    if( session_data != NULL )
-        mbedtls_platform_zeroize( session_data, session_data_len );
-    mbedtls_free( session_data );
-#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
-    if( context_buf != NULL )
-        mbedtls_platform_zeroize( context_buf, context_buf_len );
-    mbedtls_free( context_buf );
-#endif
-
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
+    const char* message = mbedtls_test_helper_is_psa_leaking();
+    if( message )
+    {
+        if( ret == 0 )
+            ret = 1;
+        mbedtls_printf( "PSA memory leak detected: %s\n",  message);
+    }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+    /* For builds with MBEDTLS_TEST_USE_PSA_CRYPTO_RNG psa crypto
+     * resources are freed by rng_free(). */
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
+    !defined(MBEDTLS_TEST_USE_PSA_CRYPTO_RNG)
     mbedtls_psa_crypto_free( );
 #endif
 
+    rng_free( &rng );
+
 #if defined(MBEDTLS_TEST_HOOKS)
     if( test_hooks_failure_detected( ) )
     {
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index bd4dbb6..329305e 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -63,6 +63,10 @@
 #include <windows.h>
 #endif
 
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "test/psa_crypto_helpers.h"
+#endif
+
 /* Size of memory to be allocated for the heap, when using the library's memory
  * management and MBEDTLS_MEMORY_BUFFER_ALLOC_C is enabled. */
 #define MEMORY_HEAP_SIZE        120000
@@ -3928,9 +3932,35 @@
     mbedtls_net_free( &client_fd );
     mbedtls_net_free( &listen_fd );
 
-#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
-    mbedtls_dhm_free( &dhm );
+    mbedtls_ssl_free( &ssl );
+    mbedtls_ssl_config_free( &conf );
+
+#if defined(MBEDTLS_SSL_CACHE_C)
+    mbedtls_ssl_cache_free( &cache );
 #endif
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+    mbedtls_ssl_ticket_free( &ticket_ctx );
+#endif
+#if defined(MBEDTLS_SSL_COOKIE_C)
+    mbedtls_ssl_cookie_free( &cookie_ctx );
+#endif
+
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+    if( context_buf != NULL )
+        mbedtls_platform_zeroize( context_buf, context_buf_len );
+    mbedtls_free( context_buf );
+#endif
+
+#if defined(SNI_OPTION)
+    sni_free( sni_info );
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+    ret = psk_free( psk_info );
+    if( ( ret != 0 ) && ( opt.query_config_mode == DFL_QUERY_CONFIG_MODE ) )
+        mbedtls_printf( "Failed to list of opaque PSKs - error was %d\n", ret );
+#endif
+
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
     mbedtls_x509_crt_free( &cacert );
     mbedtls_x509_crt_free( &srvcert );
@@ -3938,6 +3968,11 @@
     mbedtls_x509_crt_free( &srvcert2 );
     mbedtls_pk_free( &pkey2 );
 #endif
+
+#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
+    mbedtls_dhm_free( &dhm );
+#endif
+
 #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
     for( i = 0; (size_t) i < ssl_async_keys.slots_used; i++ )
     {
@@ -3949,17 +3984,6 @@
         }
     }
 #endif
-#if defined(SNI_OPTION)
-    sni_free( sni_info );
-#endif
-#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
-    ret = psk_free( psk_info );
-    if( ( ret != 0 ) && ( opt.query_config_mode == DFL_QUERY_CONFIG_MODE ) )
-        mbedtls_printf( "Failed to list of opaque PSKs - error was %d\n", ret );
-#endif
-#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
-    mbedtls_dhm_free( &dhm );
-#endif
 
 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) && \
     defined(MBEDTLS_USE_PSA_CRYPTO)
@@ -3980,32 +4004,27 @@
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED &&
           MBEDTLS_USE_PSA_CRYPTO */
 
-    mbedtls_ssl_free( &ssl );
-    mbedtls_ssl_config_free( &conf );
-    rng_free( &rng );
-
-#if defined(MBEDTLS_SSL_CACHE_C)
-    mbedtls_ssl_cache_free( &cache );
-#endif
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
-    mbedtls_ssl_ticket_free( &ticket_ctx );
-#endif
-#if defined(MBEDTLS_SSL_COOKIE_C)
-    mbedtls_ssl_cookie_free( &cookie_ctx );
-#endif
-
-    mbedtls_free( buf );
-
-#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
-    if( context_buf != NULL )
-        mbedtls_platform_zeroize( context_buf, context_buf_len );
-    mbedtls_free( context_buf );
-#endif
-
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
+    const char* message = mbedtls_test_helper_is_psa_leaking();
+    if( message )
+    {
+        if( ret == 0 )
+            ret = 1;
+        mbedtls_printf( "PSA memory leak detected: %s\n",  message);
+    }
+#endif
+
+    /* For builds with MBEDTLS_TEST_USE_PSA_CRYPTO_RNG psa crypto
+     * resources are freed by rng_free(). */
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
+    !defined(MBEDTLS_TEST_USE_PSA_CRYPTO_RNG)
     mbedtls_psa_crypto_free( );
 #endif
 
+    rng_free( &rng );
+
+    mbedtls_free( buf );
+
 #if defined(MBEDTLS_TEST_HOOKS)
     /* Let test hooks detect errors such as resource leaks.
      * Don't do it in query_config mode, because some test code prints
diff --git a/programs/test/CMakeLists.txt b/programs/test/CMakeLists.txt
index 2b1e61e..04ec7fc 100644
--- a/programs/test/CMakeLists.txt
+++ b/programs/test/CMakeLists.txt
@@ -22,7 +22,17 @@
 )
 
 if(TEST_CPP)
-    list(APPEND executables_mbedcrypto cpp_dummy_build)
+    set(cpp_dummy_build_cpp "${CMAKE_CURRENT_BINARY_DIR}/cpp_dummy_build.cpp")
+    set(generate_cpp_dummy_build "${CMAKE_CURRENT_SOURCE_DIR}/generate_cpp_dummy_build.sh")
+    add_custom_command(
+        OUTPUT "${cpp_dummy_build_cpp}"
+        COMMAND "${generate_cpp_dummy_build}" "${cpp_dummy_build_cpp}"
+        DEPENDS "${generate_cpp_dummy_build}"
+        WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+    )
+    add_executable(cpp_dummy_build "${cpp_dummy_build_cpp}")
+    target_include_directories(cpp_dummy_build PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../include)
+    target_link_libraries(cpp_dummy_build ${mbedcrypto_target})
 endif()
 
 foreach(exe IN LISTS executables_libs executables_mbedcrypto)
diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c
index 9c5911b..88c9e65 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -449,7 +449,8 @@
     {
         mbedtls_des3_context des3;
         mbedtls_des3_init( &des3 );
-        mbedtls_des3_set3key_enc( &des3, tmp );
+        if( mbedtls_des3_set3key_enc( &des3, tmp ) != 0 )
+            mbedtls_exit( 1 );
         TIME_AND_TSC( "3DES",
                 mbedtls_des3_crypt_cbc( &des3, MBEDTLS_DES_ENCRYPT, BUFSIZE, tmp, buf, buf ) );
         mbedtls_des3_free( &des3 );
@@ -459,7 +460,8 @@
     {
         mbedtls_des_context des;
         mbedtls_des_init( &des );
-        mbedtls_des_setkey_enc( &des, tmp );
+        if( mbedtls_des_setkey_enc( &des, tmp ) != 0 )
+            mbedtls_exit( 1 );
         TIME_AND_TSC( "DES",
                 mbedtls_des_crypt_cbc( &des, MBEDTLS_DES_ENCRYPT, BUFSIZE, tmp, buf, buf ) );
         mbedtls_des_free( &des );
@@ -497,7 +499,7 @@
 
             memset( buf, 0, sizeof( buf ) );
             memset( tmp, 0, sizeof( tmp ) );
-            mbedtls_aes_setkey_enc( &aes, tmp, keysize );
+            CHECK_AND_CONTINUE( mbedtls_aes_setkey_enc( &aes, tmp, keysize ) );
 
             TIME_AND_TSC( title,
                 mbedtls_aes_crypt_cbc( &aes, MBEDTLS_AES_ENCRYPT, BUFSIZE, tmp, buf, buf ) );
@@ -518,7 +520,7 @@
 
             memset( buf, 0, sizeof( buf ) );
             memset( tmp, 0, sizeof( tmp ) );
-            mbedtls_aes_xts_setkey_enc( &ctx, tmp, keysize * 2 );
+            CHECK_AND_CONTINUE( mbedtls_aes_xts_setkey_enc( &ctx, tmp, keysize * 2 ) );
 
             TIME_AND_TSC( title,
                     mbedtls_aes_crypt_xts( &ctx, MBEDTLS_AES_ENCRYPT, BUFSIZE,
diff --git a/programs/test/cpp_dummy_build.cpp b/programs/test/cpp_dummy_build.cpp
deleted file mode 100644
index d052682..0000000
--- a/programs/test/cpp_dummy_build.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- *  This program is a dummy C++ program to ensure Mbed TLS library header files
- *  can be included and built with a C++ compiler.
- *
- *  Copyright The Mbed TLS Contributors
- *  SPDX-License-Identifier: Apache-2.0
- *
- *  Licensed under the Apache License, Version 2.0 (the "License"); you may
- *  not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#include "mbedtls/aes.h"
-#include "mbedtls/aesni.h"
-#include "mbedtls/arc4.h"
-#include "mbedtls/aria.h"
-#include "mbedtls/asn1.h"
-#include "mbedtls/asn1write.h"
-#include "mbedtls/base64.h"
-#include "mbedtls/bignum.h"
-#include "mbedtls/blowfish.h"
-#include "mbedtls/bn_mul.h"
-#include "mbedtls/camellia.h"
-#include "mbedtls/ccm.h"
-#include "mbedtls/certs.h"
-#include "mbedtls/chacha20.h"
-#include "mbedtls/chachapoly.h"
-#include "mbedtls/check_config.h"
-#include "mbedtls/cipher.h"
-#include "mbedtls/cipher_internal.h"
-#include "mbedtls/cmac.h"
-#include "mbedtls/compat-1.3.h"
-#include "mbedtls/config_psa.h"
-#include "mbedtls/ctr_drbg.h"
-#include "mbedtls/debug.h"
-#include "mbedtls/des.h"
-#include "mbedtls/dhm.h"
-#include "mbedtls/ecdh.h"
-#include "mbedtls/ecdsa.h"
-#include "mbedtls/ecjpake.h"
-#include "mbedtls/ecp.h"
-#include "mbedtls/ecp_internal.h"
-#include "mbedtls/entropy.h"
-#include "mbedtls/entropy_poll.h"
-#include "mbedtls/error.h"
-#include "mbedtls/gcm.h"
-#include "mbedtls/havege.h"
-#include "mbedtls/hkdf.h"
-#include "mbedtls/hmac_drbg.h"
-#include "mbedtls/md.h"
-#include "mbedtls/md2.h"
-#include "mbedtls/md4.h"
-#include "mbedtls/md5.h"
-#include "mbedtls/md_internal.h"
-#include "mbedtls/net.h"
-#include "mbedtls/net_sockets.h"
-#include "mbedtls/nist_kw.h"
-#include "mbedtls/oid.h"
-#include "mbedtls/padlock.h"
-#include "mbedtls/pem.h"
-#include "mbedtls/pk.h"
-#include "mbedtls/pk_internal.h"
-#include "mbedtls/pkcs11.h"
-#include "mbedtls/pkcs12.h"
-#include "mbedtls/pkcs5.h"
-#include "mbedtls/platform_time.h"
-#include "mbedtls/platform_util.h"
-#include "mbedtls/poly1305.h"
-#include "mbedtls/psa_util.h"
-#include "mbedtls/ripemd160.h"
-#include "mbedtls/rsa.h"
-#include "mbedtls/rsa_internal.h"
-#include "mbedtls/sha1.h"
-#include "mbedtls/sha256.h"
-#include "mbedtls/sha512.h"
-#include "mbedtls/ssl.h"
-#include "mbedtls/ssl_cache.h"
-#include "mbedtls/ssl_ciphersuites.h"
-#include "mbedtls/ssl_cookie.h"
-#include "mbedtls/ssl_internal.h"
-#include "mbedtls/ssl_ticket.h"
-#include "mbedtls/threading.h"
-#include "mbedtls/timing.h"
-#include "mbedtls/version.h"
-#include "mbedtls/x509.h"
-#include "mbedtls/x509_crl.h"
-#include "mbedtls/x509_crt.h"
-#include "mbedtls/x509_csr.h"
-#include "mbedtls/xtea.h"
-
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#endif
-
-#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
-#include "mbedtls/memory_buffer_alloc.h"
-#endif
-
-#include "psa/crypto.h"
-#include "psa/crypto_se_driver.h"
-#include "../library/psa_crypto_its.h"
-
-int main()
-{
-    mbedtls_platform_context *ctx = NULL;
-    mbedtls_platform_setup(ctx);
-    mbedtls_printf("CPP Build test\n");
-    mbedtls_platform_teardown(ctx);
-}
diff --git a/programs/test/generate_cpp_dummy_build.sh b/programs/test/generate_cpp_dummy_build.sh
new file mode 100755
index 0000000..90a181d
--- /dev/null
+++ b/programs/test/generate_cpp_dummy_build.sh
@@ -0,0 +1,97 @@
+#!/bin/sh
+
+DEFAULT_OUTPUT_FILE=programs/test/cpp_dummy_build.cpp
+
+if [ "$1" = "--help" ]; then
+    cat <<EOF
+Usage: $0 [OUTPUT]
+Generate a C++ dummy build program that includes all the headers.
+OUTPUT defaults to "programs/test/cpp_dummy_build.cpp".
+Run this program from the root of an Mbed TLS directory tree or from
+its "programs" or "programs/test" subdirectory.
+EOF
+    exit
+fi
+
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -e
+
+# Ensure a reproducible order for *.h
+export LC_ALL=C
+
+print_cpp () {
+    cat <<'EOF'
+/* Automatically generated file. Do not edit.
+ *
+ *  This program is a dummy C++ program to ensure Mbed TLS library header files
+ *  can be included and built with a C++ compiler.
+ *
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include "mbedtls/config.h"
+
+EOF
+
+  for header in include/mbedtls/*.h include/psa/*.h; do
+    case ${header#include/} in
+      psa/crypto_config.h) :;; # not meant for direct inclusion
+      # Some of the psa/crypto_*.h headers are not meant to be included directly.
+      # They do have include guards that make them no-ops if psa/crypto.h
+      # has been included before. Since psa/crypto.h comes before psa/crypto_*.h
+      # in the wildcard enumeration, we don't need to skip those headers.
+      *) echo "#include \"${header#include/}\"";;
+    esac
+  done
+
+    cat <<'EOF'
+
+int main()
+{
+    mbedtls_platform_context *ctx = NULL;
+    mbedtls_platform_setup(ctx);
+    mbedtls_printf("CPP Build test passed\n");
+    mbedtls_platform_teardown(ctx);
+}
+EOF
+}
+
+if [ -d include/mbedtls ]; then
+    :
+elif [ -d ../include/mbedtls ]; then
+    cd ..
+elif [ -d ../../include/mbedtls ]; then
+    cd ../..
+else
+    echo >&2 "This script must be run from an Mbed TLS source tree."
+    exit 3
+fi
+
+print_cpp >"${1:-$DEFAULT_OUTPUT_FILE}"
diff --git a/programs/test/query_config.c b/programs/test/query_config.c
index 9b9d0c0..5dfe383 100644
--- a/programs/test/query_config.c
+++ b/programs/test/query_config.c
@@ -770,6 +770,14 @@
     }
 #endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
 
+#if defined(MBEDTLS_CHECK_RETURN_WARNING)
+    if( strcmp( "MBEDTLS_CHECK_RETURN_WARNING", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_CHECK_RETURN_WARNING );
+        return( 0 );
+    }
+#endif /* MBEDTLS_CHECK_RETURN_WARNING */
+
 #if defined(MBEDTLS_CIPHER_MODE_CBC)
     if( strcmp( "MBEDTLS_CIPHER_MODE_CBC", config ) == 0 )
     {
@@ -2642,6 +2650,22 @@
     }
 #endif /* MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO */
 
+#if defined(MBEDTLS_CHECK_RETURN)
+    if( strcmp( "MBEDTLS_CHECK_RETURN", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_CHECK_RETURN );
+        return( 0 );
+    }
+#endif /* MBEDTLS_CHECK_RETURN */
+
+#if defined(MBEDTLS_IGNORE_RETURN)
+    if( strcmp( "MBEDTLS_IGNORE_RETURN", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_IGNORE_RETURN );
+        return( 0 );
+    }
+#endif /* MBEDTLS_IGNORE_RETURN */
+
 #if defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
     if( strcmp( "MBEDTLS_PSA_HMAC_DRBG_MD_TYPE", config ) == 0 )
     {
diff --git a/programs/x509/CMakeLists.txt b/programs/x509/CMakeLists.txt
index 29cbeb8..5b1c319 100644
--- a/programs/x509/CMakeLists.txt
+++ b/programs/x509/CMakeLists.txt
@@ -15,6 +15,7 @@
     cert_req
     cert_write
     crl_app
+    load_roots
     req_app
 )
 
diff --git a/programs/x509/load_roots.c b/programs/x509/load_roots.c
new file mode 100644
index 0000000..6a40949
--- /dev/null
+++ b/programs/x509/load_roots.c
@@ -0,0 +1,217 @@
+/*
+ *  Root CA reading application
+ *
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ *
+ *  This file is provided under the Apache License 2.0, or the
+ *  GNU General Public License v2.0 or later.
+ *
+ *  **********
+ *  Apache License 2.0:
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  **********
+ *
+ *  **********
+ *  GNU General Public License v2.0 or later:
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  **********
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_time            time
+#define mbedtls_time_t          time_t
+#define mbedtls_fprintf         fprintf
+#define mbedtls_printf          printf
+#define mbedtls_exit            exit
+#define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
+#define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
+#endif /* MBEDTLS_PLATFORM_C */
+
+#if !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_FS_IO) ||  \
+    !defined(MBEDTLS_TIMING_C)
+int main( void )
+{
+    mbedtls_printf("MBEDTLS_X509_CRT_PARSE_C and/or MBEDTLS_FS_IO and/or "
+           "MBEDTLS_TIMING_C not defined.\n");
+    mbedtls_exit( 0 );
+}
+#else
+
+#include "mbedtls/error.h"
+#include "mbedtls/timing.h"
+#include "mbedtls/x509_crt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define DFL_ITERATIONS          1
+#define DFL_PRIME_CACHE         1
+
+#define USAGE \
+    "\n usage: load_roots param=<>... [--] FILE...\n"   \
+    "\n acceptable parameters:\n"                       \
+    "    iterations=%%d        Iteration count (not including cache priming); default: 1\n"  \
+    "    prime=%%d             Prime the disk read cache? Default: 1 (yes)\n"  \
+    "\n"
+
+
+/*
+ * global options
+ */
+struct options
+{
+    const char **filenames;     /* NULL-terminated list of file names */
+    unsigned iterations;        /* Number of iterations to time */
+    int prime_cache;            /* Prime the disk read cache? */
+} opt;
+
+
+int read_certificates( const char *const *filenames )
+{
+    mbedtls_x509_crt cas;
+    int ret = 0;
+    const char *const *cur;
+
+    mbedtls_x509_crt_init( &cas );
+
+    for( cur = filenames; *cur != NULL; cur++ )
+    {
+        ret = mbedtls_x509_crt_parse_file( &cas, *cur );
+        if( ret != 0 )
+        {
+#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
+            char error_message[200];
+            mbedtls_strerror( ret, error_message, sizeof( error_message ) );
+            printf( "\n%s: -0x%04x (%s)\n",
+                    *cur, (unsigned) -ret, error_message );
+#else
+            printf( "\n%s: -0x%04x\n",
+                    *cur, (unsigned) -ret );
+#endif
+            goto exit;
+        }
+    }
+
+exit:
+    mbedtls_x509_crt_free( &cas );
+    return( ret == 0 );
+}
+
+int main( int argc, char *argv[] )
+{
+    int exit_code = MBEDTLS_EXIT_FAILURE;
+    unsigned i, j;
+    struct mbedtls_timing_hr_time timer;
+    unsigned long ms;
+
+    if( argc <= 1 )
+    {
+        mbedtls_printf( USAGE );
+        goto exit;
+    }
+
+    opt.filenames = NULL;
+    opt.iterations = DFL_ITERATIONS;
+    opt.prime_cache = DFL_PRIME_CACHE;
+
+    for( i = 1; i < (unsigned) argc; i++ )
+    {
+        char *p = argv[i];
+        char *q = NULL;
+
+        if( strcmp( p, "--" ) == 0 )
+            break;
+        if( ( q = strchr( p, '=' ) ) == NULL )
+            break;
+        *q++ = '\0';
+
+        for( j = 0; p + j < q; j++ )
+        {
+            if( argv[i][j] >= 'A' && argv[i][j] <= 'Z' )
+                argv[i][j] |= 0x20;
+        }
+
+        if( strcmp( p, "iterations" ) == 0 )
+        {
+            opt.iterations = atoi( q );
+        }
+        else if( strcmp( p, "prime" ) == 0 )
+        {
+            opt.iterations = atoi( q ) != 0;
+        }
+        else
+        {
+            mbedtls_printf( "Unknown option: %s\n", p );
+            mbedtls_printf( USAGE );
+            goto exit;
+        }
+    }
+
+    opt.filenames = (const char**) argv + i;
+    if( *opt.filenames == 0 )
+    {
+        mbedtls_printf( "Missing list of certificate files to parse\n" );
+        goto exit;
+    }
+
+    mbedtls_printf( "Parsing %u certificates", argc - i );
+    if( opt.prime_cache )
+    {
+        if( ! read_certificates( opt.filenames ) )
+            goto exit;
+        mbedtls_printf( " " );
+    }
+
+    (void) mbedtls_timing_get_timer( &timer, 1 );
+    for( i = 1; i <= opt.iterations; i++ )
+    {
+        if( ! read_certificates( opt.filenames ) )
+            goto exit;
+        mbedtls_printf( "." );
+    }
+    ms = mbedtls_timing_get_timer( &timer, 0 );
+    mbedtls_printf( "\n%u iterations -> %lu ms\n", opt.iterations, ms );
+    exit_code = MBEDTLS_EXIT_SUCCESS;
+
+exit:
+    mbedtls_exit( exit_code );
+}
+#endif /* necessary configuration */
diff --git a/scripts/mbedtls_dev/macro_collector.py b/scripts/mbedtls_dev/macro_collector.py
index f8d6155..3440ba7 100644
--- a/scripts/mbedtls_dev/macro_collector.py
+++ b/scripts/mbedtls_dev/macro_collector.py
@@ -232,6 +232,27 @@
         self.key_types_from_group = {} #type: Dict[str, str]
         self.algorithms_from_hash = {} #type: Dict[str, str]
 
+    @staticmethod
+    def algorithm_tester(name: str) -> str:
+        """The predicate for whether an algorithm is built from the given constructor.
+
+        The given name must be the name of an algorithm constructor of the
+        form ``PSA_ALG_xxx`` which is used as ``PSA_ALG_xxx(yyy)`` to build
+        an algorithm value. Return the corresponding predicate macro which
+        is used as ``predicate(alg)`` to test whether ``alg`` can be built
+        as ``PSA_ALG_xxx(yyy)``. The predicate is usually called
+        ``PSA_ALG_IS_xxx``.
+        """
+        prefix = 'PSA_ALG_'
+        assert name.startswith(prefix)
+        midfix = 'IS_'
+        suffix = name[len(prefix):]
+        if suffix in ['DSA', 'ECDSA']:
+            midfix += 'RANDOMIZED_'
+        elif suffix == 'RSA_PSS':
+            suffix += '_STANDARD_SALT'
+        return prefix + midfix + suffix
+
     def record_algorithm_subtype(self, name: str, expansion: str) -> None:
         """Record the subtype of an algorithm constructor.
 
@@ -307,12 +328,7 @@
             self.algorithms.add(name)
             self.record_algorithm_subtype(name, expansion)
         elif name.startswith('PSA_ALG_') and parameter == 'hash_alg':
-            if name in ['PSA_ALG_DSA', 'PSA_ALG_ECDSA']:
-                # A naming irregularity
-                tester = name[:8] + 'IS_RANDOMIZED_' + name[8:]
-            else:
-                tester = name[:8] + 'IS_' + name[8:]
-            self.algorithms_from_hash[name] = tester
+            self.algorithms_from_hash[name] = self.algorithm_tester(name)
         elif name.startswith('PSA_KEY_USAGE_') and not parameter:
             self.key_usage_flags.add(name)
         else:
diff --git a/scripts/mbedtls_dev/test_case.py b/scripts/mbedtls_dev/test_case.py
index d01e143..6a46e42 100644
--- a/scripts/mbedtls_dev/test_case.py
+++ b/scripts/mbedtls_dev/test_case.py
@@ -83,8 +83,6 @@
             out.write('depends_on:' + ':'.join(self.dependencies) + '\n')
         out.write(self.function + ':' + ':'.join(self.arguments) + '\n')
 
-
-
 def write_data_file(filename: str,
                     test_cases: Iterable[TestCase],
                     caller: Optional[str] = None) -> None:
diff --git a/tests/Makefile b/tests/Makefile
index 6be6f33..5c59607 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -6,6 +6,9 @@
 WARNING_CFLAGS ?= -Wall -Wextra -Wformat=2 -Wno-format-nonliteral
 LDFLAGS ?=
 
+# Set this to -v to see the details of failing test cases
+TEST_FLAGS ?= $(if $(filter-out 0 OFF Off off NO No no FALSE False false N n,$(CTEST_OUTPUT_ON_FAILURE)),-v,)
+
 # Include public header files from ../include, test-specific header files
 # from ./include, and private header files (used by some invasive tests)
 # from ../library.
@@ -138,7 +141,7 @@
 
 clean:
 ifndef WINDOWS
-	rm -rf $(BINARIES) *.c *.datax TESTS
+	rm -rf $(BINARIES) *.c *.datax
 	rm -f src/*.o src/drivers/*.o src/libmbed*
 	rm -f include/test/instrument_record_status.h
 else
@@ -149,51 +152,14 @@
 	if exist src/drivers/*.o del /Q /F src/drivers/*.o
 	if exist src/libmbed* del /Q /F src/libmed*
 	if exist include/test/instrument_record_status.h del /Q /F include/test/instrument_record_status.h
-ifneq ($(wildcard TESTS/.*),)
-	rmdir /Q /S TESTS
-endif
 endif
 
 # Test suites caught by SKIP_TEST_SUITES are built but not executed.
 check: $(BINARIES)
-	perl scripts/run-test-suites.pl --skip=$(SKIP_TEST_SUITES)
+	perl scripts/run-test-suites.pl $(TEST_FLAGS) --skip=$(SKIP_TEST_SUITES)
 
 test: check
 
-# Create separate targets for generating embedded tests.
-EMBEDDED_TESTS := $(addprefix embedded_,$(APPS))
-
-# Generate test code for target.
-
-.SECONDEXPANSION:
-$(EMBEDDED_TESTS): embedded_%: suites/$$(firstword $$(subst ., ,$$*)).function suites/%.data scripts/generate_test_code.py suites/helpers.function suites/main_test.function suites/target_test.function
-	echo "  Gen  ./TESTS/mbedtls/$*/$*.c"
-	$(PYTHON) scripts/generate_test_code.py -f suites/$(firstword $(subst ., ,$*)).function \
-		-d suites/$*.data \
-		-t suites/main_test.function \
-		-p suites/target_test.function \
-		-s suites  \
-		--helpers-file suites/helpers.function \
-		-o ./TESTS/mbedtls/$*
-
-generate-target-tests: $(EMBEDDED_TESTS)
-
-define copy_header_to_target
-TESTS/mbedtls/$(1)/$(2): include/test/$(2)
-	echo "  Copy ./$$@"
-ifndef WINDOWS
-	mkdir -p $$(@D)
-	cp $$< $$@
-else
-	mkdir $$(@D)
-	copy $$< $$@
-endif
-
-endef
-$(foreach app, $(APPS), $(foreach file, $(notdir $(wildcard include/test/*.h)), \
-	$(eval $(call copy_header_to_target,$(app),$(file)))))
-$(addprefix embedded_,$(filter test_suite_psa_%, $(APPS))): embedded_%: $(patsubst TESTS/mbedtls/%, include/test/%, $(wildcard include/test/*. include/test/*/*.h))
-
 ifdef RECORD_PSA_STATUS_COVERAGE_LOG
 include/test/instrument_record_status.h: ../include/psa/crypto.h Makefile
 	echo "  Gen  $@"
diff --git a/tests/configs/user-config-for-test.h b/tests/configs/user-config-for-test.h
new file mode 100644
index 0000000..6e7c154
--- /dev/null
+++ b/tests/configs/user-config-for-test.h
@@ -0,0 +1,59 @@
+/* MBEDTLS_USER_CONFIG_FILE for testing.
+ * Only used for a few test configurations.
+ *
+ * Typical usage (note multiple levels of quoting):
+ *     make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/user-config-for-test.h\"'"
+ */
+
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#if defined(PSA_CRYPTO_DRIVER_TEST_ALL)
+
+/* Enable the use of the test driver in the library, and build the generic
+ * part of the test driver. */
+#define PSA_CRYPTO_DRIVER_TEST
+
+/* Use the accelerator driver for all cryptographic mechanisms for which
+ * the test driver implemented. */
+#define MBEDTLS_PSA_ACCEL_KEY_TYPE_AES
+#define MBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA
+#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR
+#define MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR
+#define MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING
+#define MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7
+#define MBEDTLS_PSA_ACCEL_ALG_CTR
+#define MBEDTLS_PSA_ACCEL_ALG_CFB
+#define MBEDTLS_PSA_ACCEL_ALG_ECDSA
+#define MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA
+#define MBEDTLS_PSA_ACCEL_ALG_MD2
+#define MBEDTLS_PSA_ACCEL_ALG_MD4
+#define MBEDTLS_PSA_ACCEL_ALG_MD5
+#define MBEDTLS_PSA_ACCEL_ALG_OFB
+#define MBEDTLS_PSA_ACCEL_ALG_RIPEMD160
+#define MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN
+#define MBEDTLS_PSA_ACCEL_ALG_RSA_PSS
+#define MBEDTLS_PSA_ACCEL_ALG_SHA_1
+#define MBEDTLS_PSA_ACCEL_ALG_SHA_224
+#define MBEDTLS_PSA_ACCEL_ALG_SHA_256
+#define MBEDTLS_PSA_ACCEL_ALG_SHA_384
+#define MBEDTLS_PSA_ACCEL_ALG_SHA_512
+#define MBEDTLS_PSA_ACCEL_ALG_XTS
+#define MBEDTLS_PSA_ACCEL_ALG_CMAC
+#define MBEDTLS_PSA_ACCEL_ALG_HMAC
+
+#endif  /* PSA_CRYPTO_DRIVER_TEST_ALL */
diff --git a/tests/include/test/helpers.h b/tests/include/test/helpers.h
index dfc09cd..5d10190 100644
--- a/tests/include/test/helpers.h
+++ b/tests/include/test/helpers.h
@@ -72,6 +72,8 @@
     const char *filename;
     int line_no;
     unsigned long step;
+    char line1[76];
+    char line2[76];
 #if defined(MBEDTLS_TEST_MUTEX_USAGE)
     const char *mutex_usage_error;
 #endif
@@ -131,6 +133,27 @@
 void mbedtls_test_info_reset( void );
 
 /**
+ * \brief           Record the current test case as a failure if two integers
+ *                  have a different value.
+ *
+ *                  This function is usually called via the macro
+ *                  #TEST_EQUAL.
+ *
+ * \param test      Description of the failure or assertion that failed. This
+ *                  MUST be a string literal. This normally has the form
+ *                  "EXPR1 == EXPR2" where EXPR1 has the value \p value1
+ *                  and EXPR2 has the value \p value2.
+ * \param line_no   Line number where the failure originated.
+ * \param filename  Filename where the failure originated.
+ * \param value1    The first value to compare.
+ * \param value2    The second value to compare.
+ *
+ * \return          \c 1 if the values are equal, otherwise \c 0.
+ */
+int mbedtls_test_equal( const char *test, int line_no, const char* filename,
+                        unsigned long long value1, unsigned long long value2 );
+
+/**
  * \brief          This function decodes the hexadecimal representation of
  *                 data.
  *
diff --git a/tests/include/test/macros.h b/tests/include/test/macros.h
index b7b6e8f..7b4c2f6 100644
--- a/tests/include/test/macros.h
+++ b/tests/include/test/macros.h
@@ -84,15 +84,21 @@
        }                                                    \
     } while( 0 )
 
-/** Evaluate two expressions and fail the test case if they have different
- * values.
+/** Evaluate two integer expressions and fail the test case if they have
+ * different values.
  *
- * \param expr1     An expression to evaluate.
- * \param expr2     The expected value of \p expr1. This can be any
- *                  expression, but it is typically a constant.
+ * The two expressions should have the same signedness, otherwise the
+ * comparison is not meaningful if the signed value is negative.
+ *
+ * \param expr1     An integral-typed expression to evaluate.
+ * \param expr2     Another integral-typed expression to evaluate.
  */
-#define TEST_EQUAL( expr1, expr2 )              \
-    TEST_ASSERT( ( expr1 ) == ( expr2 ) )
+#define TEST_EQUAL( expr1, expr2 )                                      \
+    do {                                                                \
+        if( ! mbedtls_test_equal( #expr1 " == " #expr2, __LINE__, __FILE__, \
+                                  expr1, expr2 ) )                      \
+            goto exit;                                                  \
+    } while( 0 )
 
 /** Allocate memory dynamically and fail the test case if this fails.
  * The allocated memory will be filled with zeros.
diff --git a/tests/include/test/psa_crypto_helpers.h b/tests/include/test/psa_crypto_helpers.h
index 8a8c37e..f5622e2 100644
--- a/tests/include/test/psa_crypto_helpers.h
+++ b/tests/include/test/psa_crypto_helpers.h
@@ -28,7 +28,6 @@
 #include "test/psa_helpers.h"
 
 #include <psa/crypto.h>
-#include <psa_crypto_slot_management.h>
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
 #include "mbedtls/psa_util.h"
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index fa6791c..bbc2d9c 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1,4 +1,4 @@
-#! /usr/bin/env sh
+#! /usr/bin/env bash
 
 # all.sh
 #
@@ -59,6 +59,15 @@
 # This script must be invoked from the toplevel directory of a git
 # working copy of Mbed TLS.
 #
+# The behavior on an error depends on whether --keep-going (alias -k)
+# is in effect.
+#  * Without --keep-going: the script stops on the first error without
+#    cleaning up. This lets you work in the configuration of the failing
+#    component.
+#  * With --keep-going: the script runs all requested components and
+#    reports failures at the end. In particular the script always cleans
+#    up on exit.
+#
 # Note that the output is not saved. You may want to run
 #   script -c tests/scripts/all.sh
 # or
@@ -81,6 +90,12 @@
 #
 # Each component must start by invoking `msg` with a short informative message.
 #
+# Warning: due to the way bash detects errors, the failure of a command
+# inside 'if' or '!' is not detected. Use the 'not' function instead of '!'.
+#
+# Each component is executed in a separate shell process. The component
+# fails if any command in it returns a non-zero status.
+#
 # The framework performs some cleanup tasks after each component. This
 # means that components can assume that the working directory is in a
 # cleaned-up state, and don't need to perform the cleanup themselves.
@@ -91,19 +106,6 @@
 #   `tests/Makefile` and `programs/fuzz/Makefile` from git.
 #   This cleans up after an in-tree use of CMake.
 #
-# Any command that is expected to fail must be protected so that the
-# script keeps running in --keep-going mode despite `set -e`. In keep-going
-# mode, if a protected command fails, this is logged as a failure and the
-# script will exit with a failure status once it has run all components.
-# Commands can be protected in any of the following ways:
-# * `make` is a function which runs the `make` command with protection.
-#   Note that you must write `make VAR=value`, not `VAR=value make`,
-#   because the `VAR=value make` syntax doesn't work with functions.
-# * Put `report_status` before the command to protect it.
-# * Put `if_build_successful` before a command. This protects it, and
-#   additionally skips it if a prior invocation of `make` in the same
-#   component failed.
-#
 # The tests are roughly in order from fastest to slowest. This doesn't
 # have to be exact, but in general you should add slower tests towards
 # the end and fast checks near the beginning.
@@ -114,8 +116,9 @@
 #### Initialization and command line parsing
 ################################################################
 
-# Abort on errors (and uninitialised variables)
-set -eu
+# Abort on errors (even on the left-hand side of a pipe).
+# Treat uninitialised variables as errors.
+set -e -o pipefail -u
 
 pre_check_environment () {
     if [ -d library -a -d include -a -d tests ]; then :; else
@@ -126,9 +129,16 @@
 
 pre_initialize_variables () {
     CONFIG_H='include/mbedtls/config.h'
-    CONFIG_BAK="$CONFIG_H.bak"
     CRYPTO_CONFIG_H='include/psa/crypto_config.h'
-    CRYPTO_CONFIG_BAK="$CRYPTO_CONFIG_H.bak"
+
+    # Files that are clobbered by some jobs will be backed up. Use a different
+    # suffix from auxiliary scripts so that all.sh and auxiliary scripts can
+    # independently decide when to remove the backup file.
+    backup_suffix='.all.bak'
+    # Files clobbered by config.py
+    files_to_back_up="$CONFIG_H $CRYPTO_CONFIG_H"
+    # Files clobbered by in-tree cmake
+    files_to_back_up="$files_to_back_up Makefile library/Makefile programs/Makefile tests/Makefile programs/fuzz/Makefile"
 
     append_outcome=0
     MEMORY=0
@@ -165,10 +175,10 @@
 
     # if MAKEFLAGS is not set add the -j option to speed up invocations of make
     if [ -z "${MAKEFLAGS+set}" ]; then
-        export MAKEFLAGS="-j"
+        export MAKEFLAGS="-j$(all_sh_nproc)"
     fi
 
-    # Include more verbose output for failing tests run by CMake
+    # Include more verbose output for failing tests run by CMake or make
     export CTEST_OUTPUT_ON_FAILURE=1
 
     # CFLAGS and LDFLAGS for Asan builds that don't use CMake
@@ -176,8 +186,8 @@
 
     # Gather the list of available components. These are the functions
     # defined in this script whose name starts with "component_".
-    # Parse the script with sed, because in sh there is no way to list
-    # defined functions.
+    # Parse the script with sed. This way we get the functions in the order
+    # they are defined.
     ALL_COMPONENTS=$(sed -n 's/^ *component_\([0-9A-Z_a-z]*\) *().*/\1/p' <"$0")
 
     # Exclude components that are not supported on this platform.
@@ -194,6 +204,8 @@
 # Test whether the component $1 is included in the command line patterns.
 is_component_included()
 {
+    # Temporarily disable wildcard expansion so that $COMMAND_LINE_COMPONENTS
+    # only does word splitting.
     set -f
     for pattern in $COMMAND_LINE_COMPONENTS; do
         set +f
@@ -235,6 +247,11 @@
                         Prefix for a cross-compiler for arm-linux-gnueabi
                         (default: "${ARM_LINUX_GNUEABI_GCC_PREFIX}")
      --armcc            Run ARM Compiler builds (on by default).
+     --restore          First clean up the build tree, restoring backed up
+                        files. Do not run any components unless they are
+                        explicitly specified.
+     --error-test       Error test mode: run a failing function in addition
+                        to any specified component. May be repeated.
      --except           Exclude the COMPONENTs listed on the command line,
                         instead of running only those.
      --no-append-outcome    Write a new outcome file and analyze it (default).
@@ -263,13 +280,11 @@
 EOF
 }
 
-# remove built files as well as the cmake cache/config
+# Cleanup before/after running a component.
+# Remove built files as well as the cmake cache/config.
+# Does not remove generated source files.
 cleanup()
 {
-    if [ -n "${MBEDTLS_ROOT_DIR+set}" ]; then
-        cd "$MBEDTLS_ROOT_DIR"
-    fi
-
     command make clean
 
     # Remove CMake artefacts
@@ -280,21 +295,26 @@
               -iname CMakeCache.txt \) -exec rm {} \+
     # Recover files overwritten by in-tree CMake builds
     rm -f include/Makefile include/mbedtls/Makefile programs/*/Makefile
-    git update-index --no-skip-worktree Makefile library/Makefile programs/Makefile tests/Makefile programs/fuzz/Makefile
-    git checkout -- Makefile library/Makefile programs/Makefile tests/Makefile programs/fuzz/Makefile
 
     # Remove any artifacts from the component_test_cmake_as_subdirectory test.
     rm -rf programs/test/cmake_subproject/build
     rm -f programs/test/cmake_subproject/Makefile
     rm -f programs/test/cmake_subproject/cmake_subproject
 
-    if [ -f "$CONFIG_BAK" ]; then
-        mv "$CONFIG_BAK" "$CONFIG_H"
-    fi
+    # Restore files that may have been clobbered by the job
+    for x in $files_to_back_up; do
+        cp -p "$x$backup_suffix" "$x"
+    done
+}
 
-    if [ -f "$CRYPTO_CONFIG_BAK" ]; then
-        mv "$CRYPTO_CONFIG_BAK" "$CRYPTO_CONFIG_H"
-    fi
+# Final cleanup when this script exits (except when exiting on a failure
+# in non-keep-going mode).
+final_cleanup () {
+    cleanup
+
+    for x in $files_to_back_up; do
+        rm -f "$x$backup_suffix"
+    done
 }
 
 # Executed on exit. May be redefined depending on command line options.
@@ -303,7 +323,7 @@
 }
 
 fatal_signal () {
-    cleanup
+    final_cleanup
     final_report $1
     trap - $1
     kill -$1 $$
@@ -313,6 +333,18 @@
 trap 'fatal_signal INT' INT
 trap 'fatal_signal TERM' TERM
 
+# Number of processors on this machine. Used as the default setting
+# for parallel make.
+all_sh_nproc ()
+{
+    {
+        nproc || # Linux
+        sysctl -n hw.ncpuonline || # NetBSD, OpenBSD
+        sysctl -n hw.ncpu || # FreeBSD
+        echo 1
+    } 2>/dev/null
+}
+
 msg()
 {
     if [ -n "${current_component:-}" ]; then
@@ -361,17 +393,11 @@
     done
 }
 
-check_headers_in_cpp () {
-    ls include/mbedtls | grep "\.h$" >headers.txt
-    <programs/test/cpp_dummy_build.cpp sed -n 's/"$//; s!^#include "mbedtls/!!p' |
-    sort |
-    diff headers.txt -
-    rm headers.txt
-}
-
 pre_parse_command_line () {
     COMMAND_LINE_COMPONENTS=
     all_except=0
+    error_test=0
+    restore_first=0
     no_armcc=
 
     # Note that legacy options are ignored instead of being omitted from this
@@ -385,6 +411,7 @@
             --armcc) no_armcc=;;
             --armc5-bin-dir) shift; ARMC5_BIN_DIR="$1";;
             --armc6-bin-dir) shift; ARMC6_BIN_DIR="$1";;
+            --error-test) error_test=$((error_test + 1));;
             --except) all_except=1;;
             --force|-f) FORCE=1;;
             --gnutls-cli) shift; GNUTLS_CLI="$1";;
@@ -410,6 +437,7 @@
             --quiet|-q) QUIET=1;;
             --random-seed) unset SEED;;
             --release-test|-r) SEED=$RELEASE_SEED;;
+            --restore) restore_first=1;;
             --seed|-s) shift; SEED="$1";;
             -*)
                 echo >&2 "Unknown option: $1"
@@ -422,7 +450,7 @@
     done
 
     # With no list of components, run everything.
-    if [ -z "$COMMAND_LINE_COMPONENTS" ]; then
+    if [ -z "$COMMAND_LINE_COMPONENTS" ] && [ $restore_first -eq 0 ]; then
         all_except=1
     fi
 
@@ -432,6 +460,32 @@
         COMMAND_LINE_COMPONENTS="$COMMAND_LINE_COMPONENTS *_armcc*"
     fi
 
+    # Error out if an explicitly requested component doesn't exist.
+    if [ $all_except -eq 0 ]; then
+        unsupported=0
+        # Temporarily disable wildcard expansion so that $COMMAND_LINE_COMPONENTS
+        # only does word splitting.
+        set -f
+        for component in $COMMAND_LINE_COMPONENTS; do
+            set +f
+            # If the requested name includes a wildcard character, don't
+            # check it. Accept wildcard patterns that don't match anything.
+            case $component in
+                *[*?\[]*) continue;;
+            esac
+            case " $SUPPORTED_COMPONENTS " in
+                *" $component "*) :;;
+                *)
+                    echo >&2 "Component $component was explicitly requested, but is not known or not supported."
+                    unsupported=$((unsupported + 1));;
+            esac
+        done
+        set +f
+        if [ $unsupported -ne 0 ]; then
+            exit 2
+        fi
+    fi
+
     # Build the list of components to run.
     RUN_COMPONENTS=
     for component in $SUPPORTED_COMPONENTS; do
@@ -467,9 +521,36 @@
     fi
 }
 
+pre_restore_files () {
+    # If the makefiles have been generated by a framework such as cmake,
+    # restore them from git. If the makefiles look like modifications from
+    # the ones checked into git, take care not to modify them. Whatever
+    # this function leaves behind is what the script will restore before
+    # each component.
+    case "$(head -n1 Makefile)" in
+        *[Gg]enerated*)
+            git update-index --no-skip-worktree Makefile library/Makefile programs/Makefile tests/Makefile programs/fuzz/Makefile
+            git checkout -- Makefile library/Makefile programs/Makefile tests/Makefile programs/fuzz/Makefile
+            ;;
+    esac
+}
+
+pre_back_up () {
+    for x in $files_to_back_up; do
+        cp -p "$x" "$x$backup_suffix"
+    done
+}
+
 pre_setup_keep_going () {
-    failure_summary=
-    failure_count=0
+    failure_count=0 # Number of failed components
+    last_failure_status=0 # Last failure status in this component
+
+    # See err_trap
+    previous_failure_status=0
+    previous_failed_command=
+    previous_failure_funcall_depth=0
+    unset report_failed_command
+
     start_red=
     end_color=
     if [ -t 1 ]; then
@@ -480,76 +561,106 @@
                 ;;
         esac
     fi
-    record_status () {
-        if "$@"; then
-            last_status=0
-        else
-            last_status=$?
-            text="$current_section: $* -> $last_status"
-            failure_summary="$failure_summary
-$text"
-            failure_count=$((failure_count + 1))
-            echo "${start_red}^^^^$text^^^^${end_color}" >&2
-        fi
-    }
-    make () {
-        case "$*" in
-            *test|*check)
-                if [ $build_status -eq 0 ]; then
-                    record_status command make "$@"
-                else
-                    echo "(skipped because the build failed)"
-                fi
-                ;;
-            *)
-                record_status command make "$@"
-                build_status=$last_status
-                ;;
+
+    # Keep a summary of failures in a file. We'll print it out at the end.
+    failure_summary_file=$PWD/all-sh-failures-$$.log
+    : >"$failure_summary_file"
+
+    # Whether it makes sense to keep a component going after the specified
+    # command fails (test command) or not (configure or build).
+    # This function normally receives the failing simple command
+    # ($BASH_COMMAND) as an argument, but if $report_failed_command is set,
+    # this is passed instead.
+    # This doesn't have to be 100% accurate: all failures are recorded anyway.
+    # False positives result in running things that can't be expected to
+    # work. False negatives result in things not running after something else
+    # failed even though they might have given useful feedback.
+    can_keep_going_after_failure () {
+        case "$1" in
+            "msg "*) false;;
+            "cd "*) false;;
+            *make*[\ /]tests*) false;; # make tests, make CFLAGS=-I../tests, ...
+            *test*) true;; # make test, tests/stuff, env V=v tests/stuff, ...
+            *make*check*) true;;
+            "grep "*) true;;
+            "[ "*) true;;
+            "! "*) true;;
+            *) false;;
         esac
     }
+
+    # This function runs if there is any error in a component.
+    # It must either exit with a nonzero status, or set
+    # last_failure_status to a nonzero value.
+    err_trap () {
+        # Save $? (status of the failing command). This must be the very
+        # first thing, before $? is overridden.
+        last_failure_status=$?
+        failed_command=${report_failed_command-$BASH_COMMAND}
+
+        if [[ $last_failure_status -eq $previous_failure_status &&
+              "$failed_command" == "$previous_failed_command" &&
+              ${#FUNCNAME[@]} == $((previous_failure_funcall_depth - 1)) ]]
+        then
+            # The same command failed twice in a row, but this time one level
+            # less deep in the function call stack. This happens when the last
+            # command of a function returns a nonzero status, and the function
+            # returns that same status. Ignore the second failure.
+            previous_failure_funcall_depth=${#FUNCNAME[@]}
+            return
+        fi
+        previous_failure_status=$last_failure_status
+        previous_failed_command=$failed_command
+        previous_failure_funcall_depth=${#FUNCNAME[@]}
+
+        text="$current_section: $failed_command -> $last_failure_status"
+        echo "${start_red}^^^^$text^^^^${end_color}" >&2
+        echo "$text" >>"$failure_summary_file"
+
+        # If the command is fatal (configure or build command), stop this
+        # component. Otherwise (test command) keep the component running
+        # (run more tests from the same build).
+        if ! can_keep_going_after_failure "$failed_command"; then
+            exit $last_failure_status
+        fi
+    }
+
     final_report () {
         if [ $failure_count -gt 0 ]; then
             echo
             echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
-            echo "${start_red}FAILED: $failure_count${end_color}$failure_summary"
+            echo "${start_red}FAILED: $failure_count components${end_color}"
+            cat "$failure_summary_file"
             echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
-            exit 1
         elif [ -z "${1-}" ]; then
             echo "SUCCESS :)"
         fi
         if [ -n "${1-}" ]; then
             echo "Killed by SIG$1."
         fi
+        rm -f "$failure_summary_file"
+        if [ $failure_count -gt 0 ]; then
+            exit 1
+        fi
     }
 }
 
+# record_status() and if_build_succeeded() are kept temporarily for backward
+# compatibility. Don't use them in new components.
+record_status () {
+    "$@"
+}
 if_build_succeeded () {
-    if [ $build_status -eq 0 ]; then
-        record_status "$@"
-    fi
+    "$@"
 }
 
-# to be used instead of ! for commands run with
-# record_status or if_build_succeeded
-not() {
-    ! "$@"
-}
-
-pre_setup_quiet_redirect () {
-    if [ $QUIET -ne 1 ]; then
-        redirect_out () {
-            "$@"
-        }
-        redirect_err () {
-            "$@"
-        }
-    else
-        redirect_out () {
-            "$@" >/dev/null
-        }
-        redirect_err () {
-            "$@" 2>/dev/null
-        }
+# '! true' does not trigger the ERR trap. Arrange to trigger it, with
+# a reasonably informative error message (not just "$@").
+not () {
+    if "$@"; then
+        report_failed_command="! $*"
+        false
+        unset report_failed_command
     fi
 }
 
@@ -674,28 +785,28 @@
 
 component_check_recursion () {
     msg "Check: recursion.pl" # < 1s
-    record_status tests/scripts/recursion.pl library/*.c
+    tests/scripts/recursion.pl library/*.c
 }
 
 component_check_generated_files () {
     msg "Check: freshness of generated source files" # < 1s
-    record_status tests/scripts/check-generated-files.sh
+    tests/scripts/check-generated-files.sh
 }
 
 component_check_doxy_blocks () {
     msg "Check: doxygen markup outside doxygen blocks" # < 1s
-    record_status tests/scripts/check-doxy-blocks.pl
+    tests/scripts/check-doxy-blocks.pl
 }
 
 component_check_files () {
     msg "Check: file sanity checks (permissions, encodings)" # < 1s
-    record_status tests/scripts/check_files.py
+    tests/scripts/check_files.py
 }
 
 component_check_changelog () {
     msg "Check: changelog entries" # < 1s
     rm -f ChangeLog.new
-    record_status scripts/assemble_changelog.py -o 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.
@@ -706,7 +817,7 @@
 
 component_check_names () {
     msg "Check: declared and exported names (builds the library)" # < 3s
-    record_status tests/scripts/check-names.sh -v
+    tests/scripts/check_names.py -v
 }
 
 component_check_test_cases () {
@@ -716,13 +827,13 @@
     else
         opt=''
     fi
-    record_status tests/scripts/check_test_cases.py $opt
+    tests/scripts/check_test_cases.py $opt
     unset opt
 }
 
 component_check_doxygen_warnings () {
     msg "Check: doxygen warnings (builds the documentation)" # ~ 3s
-    record_status tests/scripts/doxygen.sh
+    tests/scripts/doxygen.sh
 }
 
 
@@ -742,7 +853,7 @@
     make test
 
     msg "selftest: make, default config (out-of-box)" # ~10s
-    if_build_succeeded programs/test/selftest
+    programs/test/selftest
 
     export MBEDTLS_TEST_OUTCOME_FILE="$SAVE_MBEDTLS_TEST_OUTCOME_FILE"
     unset SAVE_MBEDTLS_TEST_OUTCOME_FILE
@@ -757,16 +868,16 @@
     make test
 
     msg "test: selftest (ASan build)" # ~ 10s
-    if_build_succeeded programs/test/selftest
+    programs/test/selftest
 
     msg "test: ssl-opt.sh (ASan build)" # ~ 1 min
-    if_build_succeeded tests/ssl-opt.sh
+    tests/ssl-opt.sh
 
     msg "test: compat.sh (ASan build)" # ~ 6 min
-    if_build_succeeded tests/compat.sh
+    tests/compat.sh
 
     msg "test: context-info.sh (ASan build)" # ~ 15 sec
-    if_build_succeeded tests/context-info.sh
+    tests/context-info.sh
 }
 
 component_test_full_cmake_gcc_asan () {
@@ -779,16 +890,16 @@
     make test
 
     msg "test: selftest (ASan build)" # ~ 10s
-    if_build_succeeded programs/test/selftest
+    programs/test/selftest
 
     msg "test: ssl-opt.sh (full config, ASan build)"
-    if_build_succeeded tests/ssl-opt.sh
+    tests/ssl-opt.sh
 
     msg "test: compat.sh (full config, ASan build)"
-    if_build_succeeded tests/compat.sh
+    tests/compat.sh
 
     msg "test: context-info.sh (full config, ASan build)" # ~ 15 sec
-    if_build_succeeded tests/context-info.sh
+    tests/context-info.sh
 }
 
 component_test_psa_crypto_key_id_encodes_owner () {
@@ -826,7 +937,7 @@
     # 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"
-    if_build_succeeded check_renamed_symbols tests/include/spe/crypto_spe.h library/libmbedcrypto.a
+    check_renamed_symbols tests/include/spe/crypto_spe.h library/libmbedcrypto.a
 }
 
 component_test_psa_crypto_client () {
@@ -843,13 +954,13 @@
 component_test_zlib_make() {
     msg "build: zlib enabled, make"
     scripts/config.py set MBEDTLS_ZLIB_SUPPORT
-    make ZLIB=1 CFLAGS='-Werror -O1'
+    make ZLIB=1 CFLAGS='-Werror -O2'
 
     msg "test: main suites (zlib, make)"
     make test
 
     msg "test: ssl-opt.sh (zlib, make)"
-    if_build_succeeded tests/ssl-opt.sh
+    tests/ssl-opt.sh
 }
 support_test_zlib_make () {
     base=support_test_zlib_$$
@@ -866,14 +977,14 @@
 component_test_zlib_cmake() {
     msg "build: zlib enabled, cmake"
     scripts/config.py set MBEDTLS_ZLIB_SUPPORT
-    cmake -D ENABLE_ZLIB_SUPPORT=On -D CMAKE_BUILD_TYPE:String=Check .
+    cmake -D ENABLE_ZLIB_SUPPORT=On -D CMAKE_BUILD_TYPE:String=Release .
     make
 
     msg "test: main suites (zlib, cmake)"
     make test
 
     msg "test: ssl-opt.sh (zlib, cmake)"
-    if_build_succeeded tests/ssl-opt.sh
+    tests/ssl-opt.sh
 }
 support_test_zlib_cmake () {
     support_test_zlib_make "$@"
@@ -891,7 +1002,7 @@
 component_test_ref_configs () {
     msg "test/build: ref-configs (ASan build)" # ~ 6 min 20s
     CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    record_status tests/scripts/test-ref-configs.pl
+    tests/scripts/test-ref-configs.pl
 }
 
 component_test_sslv3 () {
@@ -904,14 +1015,14 @@
     make test
 
     msg "build: SSLv3 - compat.sh (ASan build)" # ~ 6 min
-    if_build_succeeded tests/compat.sh -m 'tls1 tls1_1 tls1_2 dtls1 dtls1_2'
-    if_build_succeeded env OPENSSL_CMD="$OPENSSL_LEGACY" tests/compat.sh -m 'ssl3'
+    tests/compat.sh -m 'tls1 tls1_1 tls1_2 dtls1 dtls1_2'
+    env OPENSSL_CMD="$OPENSSL_LEGACY" tests/compat.sh -m 'ssl3'
 
     msg "build: SSLv3 - ssl-opt.sh (ASan build)" # ~ 6 min
-    if_build_succeeded tests/ssl-opt.sh
+    tests/ssl-opt.sh
 
     msg "build: SSLv3 - context-info.sh (ASan build)" # ~ 15 sec
-    if_build_succeeded tests/context-info.sh
+    tests/context-info.sh
 }
 
 component_test_no_renegotiation () {
@@ -924,7 +1035,7 @@
     make test
 
     msg "test: !MBEDTLS_SSL_RENEGOTIATION - ssl-opt.sh (ASan build)" # ~ 6 min
-    if_build_succeeded tests/ssl-opt.sh
+    tests/ssl-opt.sh
 }
 
 component_test_no_pem_no_fs () {
@@ -940,7 +1051,7 @@
     make test
 
     msg "test: !MBEDTLS_PEM_PARSE_C !MBEDTLS_FS_IO - ssl-opt.sh (ASan build)" # ~ 6 min
-    if_build_succeeded tests/ssl-opt.sh
+    tests/ssl-opt.sh
 }
 
 component_test_rsa_no_crt () {
@@ -953,13 +1064,13 @@
     make test
 
     msg "test: RSA_NO_CRT - RSA-related part of ssl-opt.sh (ASan build)" # ~ 5s
-    if_build_succeeded tests/ssl-opt.sh -f RSA
+    tests/ssl-opt.sh -f RSA
 
     msg "test: RSA_NO_CRT - RSA-related part of compat.sh (ASan build)" # ~ 3 min
-    if_build_succeeded tests/compat.sh -t RSA
+    tests/compat.sh -t RSA
 
     msg "test: RSA_NO_CRT - RSA-related part of context-info.sh (ASan build)" # ~ 15 sec
-    if_build_succeeded tests/context-info.sh
+    tests/context-info.sh
 }
 
 component_test_no_ctr_drbg_classic () {
@@ -978,10 +1089,10 @@
     # 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)"
-    if_build_succeeded tests/ssl-opt.sh -f 'Default\|SSL async private.*delay=\|tickets enabled on server'
+    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)"
-    if_build_succeeded tests/compat.sh -m tls1_2 -t 'ECDSA PSK' -V NO -p OpenSSL
+    tests/compat.sh -m tls1_2 -t 'ECDSA PSK' -V NO -p OpenSSL
 }
 
 component_test_no_ctr_drbg_use_psa () {
@@ -1000,10 +1111,10 @@
     # 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)"
-    if_build_succeeded tests/ssl-opt.sh -f 'Default\|SSL async private.*delay=\|tickets enabled on server'
+    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)"
-    if_build_succeeded tests/compat.sh -m tls1_2 -t 'ECDSA PSK' -V NO -p OpenSSL
+    tests/compat.sh -m tls1_2 -t 'ECDSA PSK' -V NO -p OpenSSL
 }
 
 component_test_no_hmac_drbg_classic () {
@@ -1025,12 +1136,12 @@
     # 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)"
-    if_build_succeeded tests/ssl-opt.sh -f 'Default\|SSL async private: sign'
+    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)"
-    if_build_succeeded tests/compat.sh -m tls1_2 -t 'ECDSA'
+    tests/compat.sh -m tls1_2 -t 'ECDSA'
 }
 
 component_test_no_hmac_drbg_use_psa () {
@@ -1052,12 +1163,12 @@
     # 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)"
-    if_build_succeeded tests/ssl-opt.sh -f 'Default\|SSL async private: sign'
+    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)"
-    if_build_succeeded tests/compat.sh -m tls1_2 -t 'ECDSA'
+    tests/compat.sh -m tls1_2 -t 'ECDSA'
 }
 
 component_test_psa_external_rng_no_drbg_classic () {
@@ -1081,7 +1192,7 @@
     make test
 
     msg "test: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG, classic crypto - ssl-opt.sh (subset)"
-    if_build_succeeded tests/ssl-opt.sh -f 'Default'
+    tests/ssl-opt.sh -f 'Default'
 }
 
 component_test_psa_external_rng_no_drbg_use_psa () {
@@ -1101,7 +1212,7 @@
     make test
 
     msg "test: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG, PSA crypto - ssl-opt.sh (subset)"
-    if_build_succeeded tests/ssl-opt.sh -f 'Default\|opaque'
+    tests/ssl-opt.sh -f 'Default\|opaque'
 }
 
 component_test_psa_external_rng_use_psa_crypto () {
@@ -1116,7 +1227,7 @@
     make test
 
     msg "test: full + PSA_CRYPTO_EXTERNAL_RNG + USE_PSA_CRYPTO minus CTR_DRBG"
-    if_build_succeeded tests/ssl-opt.sh -f 'Default\|opaque'
+    tests/ssl-opt.sh -f 'Default\|opaque'
 }
 
 component_test_ecp_no_internal_rng () {
@@ -1166,11 +1277,11 @@
     make test
 
     msg "test: new ECDH context - ECDH-related part of ssl-opt.sh (ASan build)" # ~ 5s
-    if_build_succeeded tests/ssl-opt.sh -f ECDH
+    tests/ssl-opt.sh -f ECDH
 
     msg "test: new ECDH context - compat.sh with some ECDH ciphersuites (ASan build)" # ~ 3 min
     # Exclude some symmetric ciphers that are redundant here to gain time.
-    if_build_succeeded tests/compat.sh -f ECDH -V NO -e 'ARCFOUR\|ARIA\|CAMELLIA\|CHACHA\|DES\|RC4'
+    tests/compat.sh -f ECDH -V NO -e 'ARCFOUR\|ARIA\|CAMELLIA\|CHACHA\|DES\|RC4'
 }
 
 component_test_everest () {
@@ -1184,11 +1295,11 @@
     make test
 
     msg "test: Everest ECDH context - ECDH-related part of ssl-opt.sh (ASan build)" # ~ 5s
-    if_build_succeeded tests/ssl-opt.sh -f ECDH
+    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.
-    if_build_succeeded tests/compat.sh -f ECDH -V NO -e 'ARCFOUR\|ARIA\|CAMELLIA\|CHACHA\|DES\|RC4'
+    tests/compat.sh -f ECDH -V NO -e 'ARCFOUR\|ARIA\|CAMELLIA\|CHACHA\|DES\|RC4'
 }
 
 component_test_everest_curve25519_only () {
@@ -1218,7 +1329,7 @@
     make
 
     msg "test: small SSL_OUT_CONTENT_LEN - ssl-opt.sh MFL and large packet tests"
-    if_build_succeeded tests/ssl-opt.sh -f "Max fragment\|Large packet"
+    tests/ssl-opt.sh -f "Max fragment\|Large packet"
 }
 
 component_test_small_ssl_in_content_len () {
@@ -1229,7 +1340,7 @@
     make
 
     msg "test: small SSL_IN_CONTENT_LEN - ssl-opt.sh MFL tests"
-    if_build_succeeded tests/ssl-opt.sh -f "Max fragment"
+    tests/ssl-opt.sh -f "Max fragment"
 }
 
 component_test_small_ssl_dtls_max_buffering () {
@@ -1239,7 +1350,7 @@
     make
 
     msg "test: small MBEDTLS_SSL_DTLS_MAX_BUFFERING #0 - ssl-opt.sh specific reordering test"
-    if_build_succeeded tests/ssl-opt.sh -f "DTLS reordering: Buffer out-of-order hs msg before reassembling next, free buffered msg"
+    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 () {
@@ -1249,38 +1360,38 @@
     make
 
     msg "test: small MBEDTLS_SSL_DTLS_MAX_BUFFERING #1 - ssl-opt.sh specific reordering test"
-    if_build_succeeded tests/ssl-opt.sh -f "DTLS reordering: Buffer encrypted Finished message, drop for fragmented NewSessionTicket"
+    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
-  record_status tests/scripts/psa_collect_statuses.py
+  tests/scripts/psa_collect_statuses.py
   # Check that psa_crypto_init() succeeded at least once
-  record_status grep -q '^0:psa_crypto_init:' tests/statuses.log
+  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 cmake -D CMAKE_BUILD_TYPE:String=Check -D ENABLE_TESTING=On .
+    CC=clang cmake -D CMAKE_BUILD_TYPE:String=Release -D ENABLE_TESTING=On .
     make
 
     msg "test: main suites (full config, clang)" # ~ 5s
     make test
 
     msg "test: psa_constant_names (full config, clang)" # ~ 1s
-    record_status tests/scripts/test_psa_constant_names.py
+    tests/scripts/test_psa_constant_names.py
 
     msg "test: ssl-opt.sh default, ECJPAKE, SSL async (full config)" # ~ 1s
-    if_build_succeeded tests/ssl-opt.sh -f 'Default\|ECJPAKE\|SSL async private'
+    tests/ssl-opt.sh -f 'Default\|ECJPAKE\|SSL async private'
 
     msg "test: compat.sh RC4, DES, 3DES & NULL (full config)" # ~ 2 min
-    if_build_succeeded env OPENSSL_CMD="$OPENSSL_LEGACY" GNUTLS_CLI="$GNUTLS_LEGACY_CLI" GNUTLS_SERV="$GNUTLS_LEGACY_SERV" tests/compat.sh -e '^$' -f 'NULL\|DES\|RC4\|ARCFOUR'
+    env OPENSSL_CMD="$OPENSSL_LEGACY" GNUTLS_CLI="$GNUTLS_LEGACY_CLI" GNUTLS_SERV="$GNUTLS_LEGACY_SERV" tests/compat.sh -e '^$' -f 'NULL\|DES\|RC4\|ARCFOUR'
 
     msg "test: compat.sh ARIA + ChachaPoly"
-    if_build_succeeded env OPENSSL_CMD="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA'
+    env OPENSSL_CMD="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA'
 }
 
 component_test_memsan_constant_flow () {
@@ -1387,70 +1498,68 @@
   msg "build: make, crypto only"
   scripts/config.py crypto
   make CFLAGS='-O1 -Werror'
-  if_build_succeeded are_empty_libraries library/libmbedx509.* library/libmbedtls.*
+  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'
-  if_build_succeeded are_empty_libraries library/libmbedx509.* library/libmbedtls.*
+  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'
-  if_build_succeeded are_empty_libraries library/libmbedx509.* library/libmbedtls.*
+  are_empty_libraries library/libmbedx509.* library/libmbedtls.*
 }
 
 component_test_depends_curves () {
     msg "test/build: curves.pl (gcc)" # ~ 4 min
-    record_status tests/scripts/curves.pl
+    tests/scripts/curves.pl
 }
 
 component_test_depends_curves_psa () {
     msg "test/build: curves.pl with MBEDTLS_USE_PSA_CRYPTO defined (gcc)"
     scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
-    record_status tests/scripts/curves.pl
+    tests/scripts/curves.pl
 }
 
 component_test_depends_hashes () {
     msg "test/build: depends-hashes.pl (gcc)" # ~ 2 min
-    record_status tests/scripts/depends-hashes.pl
+    tests/scripts/depends-hashes.pl
 }
 
 component_test_depends_hashes_psa () {
     msg "test/build: depends-hashes.pl with MBEDTLS_USE_PSA_CRYPTO defined (gcc)"
     scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
-    record_status tests/scripts/depends-hashes.pl
+    tests/scripts/depends-hashes.pl
 }
 
 component_test_depends_pkalgs () {
     msg "test/build: depends-pkalgs.pl (gcc)" # ~ 2 min
-    record_status tests/scripts/depends-pkalgs.pl
+    tests/scripts/depends-pkalgs.pl
 }
 
 component_test_depends_pkalgs_psa () {
     msg "test/build: depends-pkalgs.pl with MBEDTLS_USE_PSA_CRYPTO defined (gcc)"
     scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
-    record_status tests/scripts/depends-pkalgs.pl
+    tests/scripts/depends-pkalgs.pl
 }
 
 component_build_key_exchanges () {
     msg "test/build: key-exchanges (gcc)" # ~ 1 min
-    record_status tests/scripts/key-exchanges.pl
+    tests/scripts/key-exchanges.pl
 }
 
-component_build_default_make_gcc_and_cxx () {
-    msg "build: Unix make, -Os (gcc)" # ~ 30s
-    make CC=gcc CFLAGS='-Werror -Wall -Wextra -Os'
+component_test_make_cxx () {
+    msg "build: Unix make, full, gcc + g++"
+    scripts/config.py full
+    make TEST_CPP=1 lib programs
 
-    msg "test: verify header list in cpp_dummy_build.cpp"
-    record_status check_headers_in_cpp
-
-    msg "build: Unix make, incremental g++"
-    make TEST_CPP=1
+    msg "test: cpp_dummy_build"
+    programs/test/cpp_dummy_build
 }
 
 component_test_no_use_psa_crypto_full_cmake_asan() {
@@ -1470,16 +1579,16 @@
     make test
 
     msg "test: ssl-opt.sh (full minus MBEDTLS_USE_PSA_CRYPTO)"
-    if_build_succeeded tests/ssl-opt.sh
+    tests/ssl-opt.sh
 
     msg "test: compat.sh default (full minus MBEDTLS_USE_PSA_CRYPTO)"
-    if_build_succeeded tests/compat.sh
+    tests/compat.sh
 
     msg "test: compat.sh RC4, DES & NULL (full minus MBEDTLS_USE_PSA_CRYPTO)"
-    if_build_succeeded env OPENSSL_CMD="$OPENSSL_LEGACY" GNUTLS_CLI="$GNUTLS_LEGACY_CLI" GNUTLS_SERV="$GNUTLS_LEGACY_SERV" tests/compat.sh -e '3DES\|DES-CBC3' -f 'NULL\|DES\|RC4\|ARCFOUR'
+    env OPENSSL_CMD="$OPENSSL_LEGACY" GNUTLS_CLI="$GNUTLS_LEGACY_CLI" GNUTLS_SERV="$GNUTLS_LEGACY_SERV" tests/compat.sh -e '3DES\|DES-CBC3' -f 'NULL\|DES\|RC4\|ARCFOUR'
 
     msg "test: compat.sh ARIA + ChachaPoly (full minus MBEDTLS_USE_PSA_CRYPTO)"
-    if_build_succeeded env OPENSSL_CMD="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA'
+    env OPENSSL_CMD="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA'
 }
 
 component_test_psa_crypto_config_basic() {
@@ -1511,33 +1620,8 @@
     scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_KEY_TYPE_DES
     scripts/config.py unset MBEDTLS_DES_C
 
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    loc_cflags="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_AES"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CTR"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CFB"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_ECDSA"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD2"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD4"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD5"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_OFB"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RIPEMD160"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PSS"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_1"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_224"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_256"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_384"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_512"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_XTS"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CMAC"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_HMAC"
+    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=gcc CFLAGS="$loc_cflags" LDFLAGS="$ASAN_CFLAGS"
@@ -1560,6 +1644,19 @@
     make test
 }
 
+component_test_psa_crypto_config_chachapoly_disabled() {
+    # full minus MBEDTLS_CHACHAPOLY_C without PSA_WANT_ALG_GCM and PSA_WANT_ALG_CHACHA20_POLY1305
+    msg "build: full minus MBEDTLS_CHACHAPOLY_C without PSA_WANT_ALG_GCM and PSA_WANT_ALG_CHACHA20_POLY1305"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
+    scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_GCM
+    scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_CHACHA20_POLY1305
+    make CC=gcc CFLAGS="$ASAN_CFLAGS -O2" LDFLAGS="$ASAN_CFLAGS"
+
+    msg "test: full minus MBEDTLS_CHACHAPOLY_C without PSA_WANT_ALG_GCM and PSA_WANT_ALG_CHACHA20_POLY1305"
+    make test
+}
+
 # This should be renamed to test and updated once the accelerator ECDSA code is in place and ready to test.
 component_build_psa_accel_alg_ecdsa() {
     # full plus MBEDTLS_PSA_CRYPTO_CONFIG with PSA_WANT_ALG_ECDSA
@@ -1988,7 +2085,8 @@
     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
-    make CC=gcc CFLAGS='-Werror -Wall -Wextra -Os'
+    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Check .
+    make
 }
 
 component_build_no_ssl_srv () {
@@ -2021,7 +2119,7 @@
     scripts/config.py set MBEDTLS_PLATFORM_MEMORY
     scripts/config.py set MBEDTLS_MEMORY_BACKTRACE
     scripts/config.py set MBEDTLS_MEMORY_DEBUG
-    CC=gcc cmake .
+    CC=gcc cmake -DCMAKE_BUILD_TYPE:String=Release .
     make
 
     msg "test: MBEDTLS_MEMORY_BUFFER_ALLOC_C and MBEDTLS_MEMORY_BACKTRACE"
@@ -2032,7 +2130,7 @@
     msg "build: default config with memory buffer allocator"
     scripts/config.py set MBEDTLS_MEMORY_BUFFER_ALLOC_C
     scripts/config.py set MBEDTLS_PLATFORM_MEMORY
-    CC=gcc cmake .
+    CC=gcc cmake -DCMAKE_BUILD_TYPE:String=Release .
     make
 
     msg "test: MBEDTLS_MEMORY_BUFFER_ALLOC_C"
@@ -2040,7 +2138,7 @@
 
     msg "test: ssl-opt.sh, MBEDTLS_MEMORY_BUFFER_ALLOC_C"
     # MBEDTLS_MEMORY_BUFFER_ALLOC is slow. Skip tests that tend to time out.
-    if_build_succeeded tests/ssl-opt.sh -e '^DTLS proxy'
+    tests/ssl-opt.sh -e '^DTLS proxy'
 }
 
 component_test_no_max_fragment_length () {
@@ -2051,7 +2149,7 @@
     make
 
     msg "test: ssl-opt.sh, MFL-related tests"
-    if_build_succeeded tests/ssl-opt.sh -f "Max fragment length"
+    tests/ssl-opt.sh -f "Max fragment length"
 }
 
 component_test_asan_remove_peer_certificate () {
@@ -2064,13 +2162,13 @@
     make test
 
     msg "test: ssl-opt.sh, !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE"
-    if_build_succeeded tests/ssl-opt.sh
+    tests/ssl-opt.sh
 
     msg "test: compat.sh, !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE"
-    if_build_succeeded tests/compat.sh
+    tests/compat.sh
 
     msg "test: context-info.sh, !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE"
-    if_build_succeeded tests/context-info.sh
+    tests/context-info.sh
 }
 
 component_test_no_max_fragment_length_small_ssl_out_content_len () {
@@ -2082,10 +2180,10 @@
     make
 
     msg "test: MFL tests (disabled MFL extension case) & large packet tests"
-    if_build_succeeded tests/ssl-opt.sh -f "Max fragment length\|Large buffer"
+    tests/ssl-opt.sh -f "Max fragment length\|Large buffer"
 
     msg "test: context-info.sh (disabled MFL extension case)"
-    if_build_succeeded tests/context-info.sh
+    tests/context-info.sh
 }
 
 component_test_variable_ssl_in_out_buffer_len () {
@@ -2098,10 +2196,10 @@
     make test
 
     msg "test: ssl-opt.sh, MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH enabled"
-    if_build_succeeded tests/ssl-opt.sh
+    tests/ssl-opt.sh
 
     msg "test: compat.sh, MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH enabled"
-    if_build_succeeded tests/compat.sh
+    tests/compat.sh
 }
 
 component_test_variable_ssl_in_out_buffer_len_CID () {
@@ -2116,10 +2214,10 @@
     make test
 
     msg "test: ssl-opt.sh, MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH and MBEDTLS_SSL_DTLS_CONNECTION_ID enabled"
-    if_build_succeeded tests/ssl-opt.sh
+    tests/ssl-opt.sh
 
     msg "test: compat.sh, MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH and MBEDTLS_SSL_DTLS_CONNECTION_ID enabled"
-    if_build_succeeded tests/compat.sh
+    tests/compat.sh
 }
 
 component_test_variable_ssl_in_out_buffer_len_record_splitting () {
@@ -2134,10 +2232,10 @@
     make test
 
     msg "test: ssl-opt.sh, MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH and MBEDTLS_SSL_CBC_RECORD_SPLITTING enabled"
-    if_build_succeeded tests/ssl-opt.sh
+    tests/ssl-opt.sh
 
     msg "test: compat.sh, MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH and MBEDTLS_SSL_CBC_RECORD_SPLITTING enabled"
-    if_build_succeeded tests/compat.sh
+    tests/compat.sh
 }
 
 component_test_ssl_alloc_buffer_and_mfl () {
@@ -2147,14 +2245,14 @@
     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
-    CC=gcc cmake .
+    CC=gcc 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"
-    if_build_succeeded tests/ssl-opt.sh -f "Handshake memory usage"
+    tests/ssl-opt.sh -f "Handshake memory usage"
 }
 
 component_test_when_no_ciphersuites_have_mac () {
@@ -2168,7 +2266,7 @@
     make test
 
     msg "test ssl-opt.sh: !MBEDTLS_SSL_SOME_MODES_USE_MAC"
-    if_build_succeeded tests/ssl-opt.sh -f 'Default\|EtM' -e 'without EtM'
+    tests/ssl-opt.sh -f 'Default\|EtM' -e 'without EtM'
 }
 
 component_test_null_entropy () {
@@ -2190,7 +2288,7 @@
 component_test_no_date_time () {
     msg "build: default config without MBEDTLS_HAVE_TIME_DATE"
     scripts/config.py unset MBEDTLS_HAVE_TIME_DATE
-    CC=gcc cmake
+    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Check .
     make
 
     msg "test: !MBEDTLS_HAVE_TIME_DATE - main suites"
@@ -2220,7 +2318,7 @@
     msg "selftest: malloc(0) returns NULL (ASan+UBSan build)"
     # Just the calloc selftest. "make test" ran the others as part of the
     # test suites.
-    if_build_succeeded programs/test/selftest calloc
+    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
@@ -2228,7 +2326,7 @@
     # 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.
-    if_build_succeeded tests/ssl-opt.sh -e 'proxy'
+    tests/ssl-opt.sh -e 'proxy'
 }
 
 component_test_aes_fewer_tables () {
@@ -2310,33 +2408,8 @@
     scripts/config.py full
     scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
     scripts/config.py set MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    loc_cflags="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_AES"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CTR"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CFB"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_ECDSA"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD2"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD4"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD5"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_OFB"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RIPEMD160"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PSS"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_1"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_224"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_256"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_384"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_512"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_XTS"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CMAC"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_HMAC"
+    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=gcc CFLAGS="${loc_cflags}" LDFLAGS="$ASAN_CFLAGS"
@@ -2396,7 +2469,8 @@
 }
 
 component_test_m32_o0 () {
-    # Build once with -O0, to compile out the i386 specific inline assembly
+    # Build without optimization, so as to use portable C code (in a 32-bit
+    # build) and not the i386-specific inline assembly.
     msg "build: i386, make, gcc -O0 (ASan build)" # ~ 30s
     scripts/config.py full
     make CC=gcc CFLAGS="$ASAN_CFLAGS -m32 -O0" LDFLAGS="-m32 $ASAN_CFLAGS"
@@ -2411,19 +2485,20 @@
     esac
 }
 
-component_test_m32_o1 () {
-    # Build again with -O1, to compile in the i386 specific inline assembly
-    msg "build: i386, make, gcc -O1 (ASan build)" # ~ 30s
+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
-    make CC=gcc CFLAGS="$ASAN_CFLAGS -m32 -O1" LDFLAGS="-m32 $ASAN_CFLAGS"
+    make CC=gcc CFLAGS="$ASAN_CFLAGS -m32 -O2" LDFLAGS="-m32 $ASAN_CFLAGS"
 
-    msg "test: i386, make, gcc -O1 (ASan build)"
+    msg "test: i386, make, gcc -O2 (ASan build)"
     make test
 
-    msg "test ssl-opt.sh, i386, make, gcc-O1"
-    if_build_succeeded tests/ssl-opt.sh
+    msg "test ssl-opt.sh, i386, make, gcc-O2"
+    tests/ssl-opt.sh
 }
-support_test_m32_o1 () {
+support_test_m32_o2 () {
     support_test_m32_o0 "$@"
 }
 
@@ -2437,11 +2512,11 @@
     make test
 
     msg "test: i386, Everest ECDH context - ECDH-related part of ssl-opt.sh (ASan build)" # ~ 5s
-    if_build_succeeded tests/ssl-opt.sh -f ECDH
+    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.
-    if_build_succeeded tests/compat.sh -f ECDH -V NO -e 'ARCFOUR\|ARIA\|CAMELLIA\|CHACHA\|DES\|RC4'
+    tests/compat.sh -f ECDH -V NO -e 'ARCFOUR\|ARIA\|CAMELLIA\|CHACHA\|DES\|RC4'
 }
 support_test_m32_everest () {
     support_test_m32_o0 "$@"
@@ -2581,7 +2656,7 @@
     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"
-    if_build_succeeded not grep __aeabi_uldiv library/*.o
+    not grep __aeabi_uldiv library/*.o
 }
 
 component_build_arm_none_eabi_gcc_no_64bit_multiplication () {
@@ -2590,7 +2665,7 @@
     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"
-    if_build_succeeded not grep __aeabi_lmul library/*.o
+    not grep __aeabi_lmul library/*.o
 }
 
 component_build_armcc () {
@@ -2664,13 +2739,13 @@
     make test
 
     msg "test: ssl-opt.sh (MSan)" # ~ 1 min
-    if_build_succeeded tests/ssl-opt.sh
+    tests/ssl-opt.sh
 
     # Optional part(s)
 
     if [ "$MEMORY" -gt 0 ]; then
         msg "test: compat.sh (MSan)" # ~ 6 min 20s
-        if_build_succeeded tests/compat.sh
+        tests/compat.sh
     fi
 }
 
@@ -2686,17 +2761,17 @@
     # seem to receive signals under valgrind on OS X).
     if [ "$MEMORY" -gt 0 ]; then
         msg "test: ssl-opt.sh --memcheck (Release)"
-        if_build_succeeded tests/ssl-opt.sh --memcheck
+        tests/ssl-opt.sh --memcheck
     fi
 
     if [ "$MEMORY" -gt 1 ]; then
         msg "test: compat.sh --memcheck (Release)"
-        if_build_succeeded tests/compat.sh --memcheck
+        tests/compat.sh --memcheck
     fi
 
     if [ "$MEMORY" -gt 0 ]; then
         msg "test: context-info.sh --memcheck (Release)"
-        if_build_succeeded tests/context-info.sh --memcheck
+        tests/context-info.sh --memcheck
     fi
 }
 
@@ -2705,7 +2780,7 @@
     MBEDTLS_ROOT_DIR="$PWD"
     mkdir "$OUT_OF_SOURCE_DIR"
     cd "$OUT_OF_SOURCE_DIR"
-    cmake "$MBEDTLS_ROOT_DIR"
+    cmake -D CMAKE_BUILD_TYPE:String=Check "$MBEDTLS_ROOT_DIR"
     make
 
     msg "test: cmake 'out-of-source' build"
@@ -2715,15 +2790,13 @@
     # "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).
-    if_build_succeeded ./tests/ssl-opt.sh -f 'Fallback SCSV: beginning of list' 2>ssl-opt.err
-    if [ -s ssl-opt.err ]; then
-        cat ssl-opt.err >&2
-        record_status [ ! -s ssl-opt.err ]
-        rm ssl-opt.err
-    fi
+    ./tests/ssl-opt.sh -f 'Fallback SCSV: beginning of list' 2>ssl-opt.err
+    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.err
     cd "$MBEDTLS_ROOT_DIR"
     rm -rf "$OUT_OF_SOURCE_DIR"
-    unset MBEDTLS_ROOT_DIR
 }
 
 component_test_cmake_as_subdirectory () {
@@ -2733,7 +2806,7 @@
     cd programs/test/cmake_subproject
     cmake .
     make
-    if_build_succeeded ./cmake_subproject
+    ./cmake_subproject
 
     cd "$MBEDTLS_ROOT_DIR"
     unset MBEDTLS_ROOT_DIR
@@ -2758,9 +2831,9 @@
         for compiler in clang gcc; do
             msg "test: $compiler $optimization_flag, mbedtls_platform_zeroize()"
             make programs CC="$compiler" DEBUG=1 CFLAGS="$optimization_flag"
-            if_build_succeeded gdb -ex "$gdb_disable_aslr" -x tests/scripts/test_zeroize.gdb -nw -batch -nx 2>&1 | tee test_zeroize.log
-            if_build_succeeded grep "The buffer was correctly zeroized" test_zeroize.log
-            if_build_succeeded not grep -i "error" test_zeroize.log
+            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
@@ -2769,9 +2842,30 @@
     unset gdb_disable_aslr
 }
 
+component_test_psa_compliance () {
+    msg "build: make, default config + CMAC, libmbedcrypto.a only"
+    scripts/config.py set MBEDTLS_CMAC_C
+    make -C library libmbedcrypto.a
+
+    msg "unit test: test_psa_compliance.py"
+    ./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_python_files () {
     msg "Lint: Python scripts"
-    record_status tests/scripts/check-python-files.sh
+    tests/scripts/check-python-files.sh
 }
 
 component_check_generate_test_code () {
@@ -2779,7 +2873,7 @@
     # 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.
-    record_status ./tests/scripts/test_generate_test_code.py 2>&1
+    ./tests/scripts/test_generate_test_code.py 2>&1
 }
 
 ################################################################
@@ -2788,7 +2882,7 @@
 
 post_report () {
     msg "Done, cleaning up"
-    cleanup
+    final_cleanup
 
     final_report
 }
@@ -2799,26 +2893,71 @@
 #### Run all the things
 ################################################################
 
+# Function invoked by --error-test to test error reporting.
+pseudo_component_error_test () {
+    msg "Testing error reporting $error_test_i"
+    if [ $KEEP_GOING -ne 0 ]; then
+        echo "Expect three failing commands."
+    fi
+    # If the component doesn't run in a subshell, changing error_test_i to an
+    # invalid integer will cause an error in the loop that runs this function.
+    error_test_i=this_should_not_be_used_since_the_component_runs_in_a_subshell
+    # Expected error: 'grep non_existent /dev/null -> 1'
+    grep non_existent /dev/null
+    # Expected error: '! grep -q . tests/scripts/all.sh -> 1'
+    not grep -q . "$0"
+    # Expected error: 'make unknown_target -> 2'
+    make unknown_target
+    false "this should not be executed"
+}
+
 # Run one component and clean up afterwards.
 run_component () {
-    # Back up the configuration in case the component modifies it.
-    # The cleanup function will restore it.
-    cp -p "$CONFIG_H" "$CONFIG_BAK"
-    cp -p "$CRYPTO_CONFIG_H" "$CRYPTO_CONFIG_BAK"
     current_component="$1"
     export MBEDTLS_TEST_CONFIGURATION="$current_component"
 
     # Unconditionally create a seedfile that's sufficiently long.
     # Do this before each component, because a previous component may
     # have messed it up or shortened it.
-    redirect_err dd if=/dev/urandom of=./tests/seedfile bs=64 count=1
+    local dd_cmd
+    dd_cmd=(dd if=/dev/urandom of=./tests/seedfile bs=64 count=1)
+    case $OSTYPE in
+        linux*|freebsd*|openbsd*|darwin*) dd_cmd+=(status=none)
+    esac
+    "${dd_cmd[@]}"
 
-    # Run the component code.
-    if [ $QUIET -eq 1 ]; then
-        # msg() is silenced, so just print the component name here
-        echo "${current_component#component_}"
+    # Run the component in a subshell, with error trapping and output
+    # redirection set up based on the relevant options.
+    if [ $KEEP_GOING -eq 1 ]; then
+        # We want to keep running if the subshell fails, so 'set -e' must
+        # be off when the subshell runs.
+        set +e
     fi
-    redirect_out "$@"
+    (
+        if [ $QUIET -eq 1 ]; then
+            # msg() will be silenced, so just print the component name here.
+            echo "${current_component#component_}"
+            exec >/dev/null
+        fi
+        if [ $KEEP_GOING -eq 1 ]; then
+            # Keep "set -e" off, and run an ERR trap instead to record failures.
+            set -E
+            trap err_trap ERR
+        fi
+        # The next line is what runs the component
+        "$@"
+        if [ $KEEP_GOING -eq 1 ]; then
+            trap - ERR
+            exit $last_failure_status
+        fi
+    )
+    component_status=$?
+    if [ $KEEP_GOING -eq 1 ]; then
+        set -e
+        if [ $component_status -ne 0 ]; then
+            failure_count=$((failure_count + 1))
+        fi
+    fi
 
     # Restore the build tree to a clean state.
     cleanup
@@ -2831,22 +2970,23 @@
 pre_parse_command_line "$@"
 
 pre_check_git
+pre_restore_files
+pre_back_up
 
 build_status=0
 if [ $KEEP_GOING -eq 1 ]; then
     pre_setup_keep_going
-else
-    record_status () {
-        "$@"
-    }
 fi
-pre_setup_quiet_redirect
 pre_prepare_outcome_file
 pre_print_configuration
 pre_check_tools
 cleanup
 
 # Run the requested tests.
+for ((error_test_i=1; error_test_i <= error_test; error_test_i++)); do
+    run_component pseudo_component_error_test
+done
+unset error_test_i
 for component in $RUN_COMPONENTS; do
     run_component "component_$component"
 done
diff --git a/tests/scripts/check-names.sh b/tests/scripts/check-names.sh
deleted file mode 100755
index 293afa8..0000000
--- a/tests/scripts/check-names.sh
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/bin/sh
-#
-# Copyright The Mbed TLS Contributors
-# SPDX-License-Identifier: Apache-2.0
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -eu
-
-if [ $# -ne 0 ] && [ "$1" = "--help" ]; then
-    cat <<EOF
-$0 [-v]
-This script confirms that the naming of all symbols and identifiers in mbed
-TLS are consistent with the house style and are also self-consistent.
-
-  -v    If the script fails unexpectedly, print a command trace.
-EOF
-    exit
-fi
-
-trace=
-if [ $# -ne 0 ] && [ "$1" = "-v" ]; then
-  shift
-  trace='-x'
-  exec 2>check-names.err
-  trap 'echo "FAILED UNEXPECTEDLY, status=$?";
-        cat check-names.err' EXIT
-  set -x
-fi
-
-printf "Analysing source code...\n"
-
-sh $trace tests/scripts/list-macros.sh
-tests/scripts/list-enum-consts.pl
-sh $trace tests/scripts/list-identifiers.sh
-sh $trace tests/scripts/list-symbols.sh
-
-FAIL=0
-
-printf "\nExported symbols declared in header: "
-UNDECLARED=$( diff exported-symbols identifiers | sed -n -e 's/^< //p' )
-if [ "x$UNDECLARED" = "x" ]; then
-    echo "PASS"
-else
-    echo "FAIL"
-    echo "$UNDECLARED"
-    FAIL=1
-fi
-
-diff macros identifiers | sed -n -e 's/< //p' > actual-macros
-
-for THING in actual-macros enum-consts; do
-    printf 'Names of %s: ' "$THING"
-    test -r $THING
-    BAD=$( grep -E -v '^(MBEDTLS|PSA)_[0-9A-Z_]*[0-9A-Z]$' $THING || true )
-    UNDERSCORES=$( grep -E '.*__.*' $THING || true )
-
-    if [ "x$BAD" = "x" ] && [ "x$UNDERSCORES" = "x" ]; then
-        echo "PASS"
-    else
-        echo "FAIL"
-        echo "$BAD"
-        echo "$UNDERSCORES"
-        FAIL=1
-    fi
-done
-
-for THING in identifiers; do
-    printf 'Names of %s: ' "$THING"
-    test -r $THING
-    BAD=$( grep -E -v '^(mbedtls|psa)_[0-9a-z_]*[0-9a-z]$' $THING || true )
-    if [ "x$BAD" = "x" ]; then
-        echo "PASS"
-    else
-        echo "FAIL"
-        echo "$BAD"
-        FAIL=1
-    fi
-done
-
-printf "Likely typos: "
-sort -u actual-macros enum-consts > _caps
-HEADERS=$( ls include/mbedtls/*.h include/psa/*.h | egrep -v 'compat-1\.3\.h' )
-HEADERS="$HEADERS library/*.h"
-HEADERS="$HEADERS 3rdparty/everest/include/everest/everest.h 3rdparty/everest/include/everest/x25519.h"
-LIBRARY="$( ls library/*.c )"
-LIBRARY="$LIBRARY 3rdparty/everest/library/everest.c 3rdparty/everest/library/x25519.c"
-NL='
-'
-sed -n 's/MBED..._[A-Z0-9_]*/\'"$NL"'&\'"$NL"/gp \
-    $HEADERS $LIBRARY \
-    | grep MBEDTLS | sort -u > _MBEDTLS_XXX
-TYPOS=$( diff _caps _MBEDTLS_XXX | sed -n 's/^> //p' \
-            | egrep -v 'XXX|__|_$|^MBEDTLS_.*CONFIG_FILE$' || true )
-rm _MBEDTLS_XXX _caps
-if [ "x$TYPOS" = "x" ]; then
-    echo "PASS"
-else
-    echo "FAIL"
-    echo "$TYPOS"
-    FAIL=1
-fi
-
-if [ -n "$trace" ]; then
-  set +x
-  trap - EXIT
-  rm check-names.err
-fi
-
-printf "\nOverall: "
-if [ "$FAIL" -eq 0 ]; then
-    rm macros actual-macros enum-consts identifiers exported-symbols
-    echo "PASSED"
-    exit 0
-else
-    echo "FAILED"
-    exit 1
-fi
diff --git a/tests/scripts/check_names.py b/tests/scripts/check_names.py
new file mode 100755
index 0000000..cae722e
--- /dev/null
+++ b/tests/scripts/check_names.py
@@ -0,0 +1,862 @@
+#!/usr/bin/env python3
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+This script confirms that the naming of all symbols and identifiers in Mbed TLS
+are consistent with the house style and are also self-consistent. It only runs
+on Linux and macOS since it depends on nm.
+
+It contains two major Python classes, CodeParser and NameChecker. They both have
+a comprehensive "run-all" function (comprehensive_parse() and perform_checks())
+but the individual functions can also be used for specific needs.
+
+CodeParser makes heavy use of regular expressions to parse the code, and is
+dependent on the current code formatting. Many Python C parser libraries require
+preprocessed C code, which means no macro parsing. Compiler tools are also not
+very helpful when we want the exact location in the original source (which
+becomes impossible when e.g. comments are stripped).
+
+NameChecker performs the following checks:
+
+- All exported and available symbols in the library object files, are explicitly
+  declared in the header files. This uses the nm command.
+- All macros, constants, and identifiers (function names, struct names, etc)
+  follow the required regex pattern.
+- Typo checking: All words that begin with MBED exist as macros or constants.
+
+The script returns 0 on success, 1 on test failure, and 2 if there is a script
+error. It must be run from Mbed TLS root.
+"""
+
+import abc
+import argparse
+import fnmatch
+import glob
+import textwrap
+import os
+import sys
+import traceback
+import re
+import enum
+import shutil
+import subprocess
+import logging
+
+# Naming patterns to check against. These are defined outside the NameCheck
+# class for ease of modification.
+MACRO_PATTERN = r"^(MBEDTLS|PSA)_[0-9A-Z_]*[0-9A-Z]$"
+CONSTANTS_PATTERN = MACRO_PATTERN
+IDENTIFIER_PATTERN = r"^(mbedtls|psa)_[0-9a-z_]*[0-9a-z]$"
+
+class Match(): # pylint: disable=too-few-public-methods
+    """
+    A class representing a match, together with its found position.
+
+    Fields:
+    * filename: the file that the match was in.
+    * line: the full line containing the match.
+    * line_no: the line number.
+    * pos: a tuple of (start, end) positions on the line where the match is.
+    * name: the match itself.
+    """
+    def __init__(self, filename, line, line_no, pos, name):
+        # pylint: disable=too-many-arguments
+        self.filename = filename
+        self.line = line
+        self.line_no = line_no
+        self.pos = pos
+        self.name = name
+
+    def __str__(self):
+        """
+        Return a formatted code listing representation of the erroneous line.
+        """
+        gutter = format(self.line_no, "4d")
+        underline = self.pos[0] * " " + (self.pos[1] - self.pos[0]) * "^"
+
+        return (
+            " {0} |\n".format(" " * len(gutter)) +
+            " {0} | {1}".format(gutter, self.line) +
+            " {0} | {1}\n".format(" " * len(gutter), underline)
+        )
+
+class Problem(abc.ABC): # pylint: disable=too-few-public-methods
+    """
+    An abstract parent class representing a form of static analysis error.
+    It extends an Abstract Base Class, which means it is not instantiable, and
+    it also mandates certain abstract methods to be implemented in subclasses.
+    """
+    # Class variable to control the quietness of all problems
+    quiet = False
+    def __init__(self):
+        self.textwrapper = textwrap.TextWrapper()
+        self.textwrapper.width = 80
+        self.textwrapper.initial_indent = "    > "
+        self.textwrapper.subsequent_indent = "      "
+
+    def __str__(self):
+        """
+        Unified string representation method for all Problems.
+        """
+        if self.__class__.quiet:
+            return self.quiet_output()
+        return self.verbose_output()
+
+    @abc.abstractmethod
+    def quiet_output(self):
+        """
+        The output when --quiet is enabled.
+        """
+        pass
+
+    @abc.abstractmethod
+    def verbose_output(self):
+        """
+        The default output with explanation and code snippet if appropriate.
+        """
+        pass
+
+class SymbolNotInHeader(Problem): # pylint: disable=too-few-public-methods
+    """
+    A problem that occurs when an exported/available symbol in the object file
+    is not explicitly declared in header files. Created with
+    NameCheck.check_symbols_declared_in_header()
+
+    Fields:
+    * symbol_name: the name of the symbol.
+    """
+    def __init__(self, symbol_name):
+        self.symbol_name = symbol_name
+        Problem.__init__(self)
+
+    def quiet_output(self):
+        return "{0}".format(self.symbol_name)
+
+    def verbose_output(self):
+        return self.textwrapper.fill(
+            "'{0}' was found as an available symbol in the output of nm, "
+            "however it was not declared in any header files."
+            .format(self.symbol_name))
+
+class PatternMismatch(Problem): # pylint: disable=too-few-public-methods
+    """
+    A problem that occurs when something doesn't match the expected pattern.
+    Created with NameCheck.check_match_pattern()
+
+    Fields:
+    * pattern: the expected regex pattern
+    * match: the Match object in question
+    """
+    def __init__(self, pattern, match):
+        self.pattern = pattern
+        self.match = match
+        Problem.__init__(self)
+
+
+    def quiet_output(self):
+        return (
+            "{0}:{1}:{2}"
+            .format(self.match.filename, self.match.line_no, self.match.name)
+        )
+
+    def verbose_output(self):
+        return self.textwrapper.fill(
+            "{0}:{1}: '{2}' does not match the required pattern '{3}'."
+            .format(
+                self.match.filename,
+                self.match.line_no,
+                self.match.name,
+                self.pattern
+            )
+        ) + "\n" + str(self.match)
+
+class Typo(Problem): # pylint: disable=too-few-public-methods
+    """
+    A problem that occurs when a word using MBED doesn't appear to be defined as
+    constants nor enum values. Created with NameCheck.check_for_typos()
+
+    Fields:
+    * match: the Match object of the MBED name in question.
+    """
+    def __init__(self, match):
+        self.match = match
+        Problem.__init__(self)
+
+    def quiet_output(self):
+        return (
+            "{0}:{1}:{2}"
+            .format(self.match.filename, self.match.line_no, self.match.name)
+        )
+
+    def verbose_output(self):
+        return self.textwrapper.fill(
+            "{0}:{1}: '{2}' looks like a typo. It was not found in any "
+            "macros or any enums. If this is not a typo, put "
+            "//no-check-names after it."
+            .format(self.match.filename, self.match.line_no, self.match.name)
+        ) + "\n" + str(self.match)
+
+class CodeParser():
+    """
+    Class for retrieving files and parsing the code. This can be used
+    independently of the checks that NameChecker performs, for example for
+    list_internal_identifiers.py.
+    """
+    def __init__(self, log):
+        self.log = log
+        self.check_repo_path()
+
+        # Memo for storing "glob expression": set(filepaths)
+        self.files = {}
+
+        # Globally excluded filenames.
+        # Note that "*" can match directory separators in exclude lists.
+        self.excluded_files = ["*/bn_mul", "*/compat-1.3.h"]
+
+    @staticmethod
+    def check_repo_path():
+        """
+        Check that the current working directory is the project root, and throw
+        an exception if not.
+        """
+        if not all(os.path.isdir(d) for d in ["include", "library", "tests"]):
+            raise Exception("This script must be run from Mbed TLS root")
+
+    def comprehensive_parse(self):
+        """
+        Comprehensive ("default") function to call each parsing function and
+        retrieve various elements of the code, together with the source location.
+
+        Returns a dict of parsed item key to the corresponding List of Matches.
+        """
+        self.log.info("Parsing source code...")
+        self.log.debug(
+            "The following files are excluded from the search: {}"
+            .format(str(self.excluded_files))
+        )
+
+        all_macros = self.parse_macros([
+            "include/mbedtls/*.h",
+            "include/psa/*.h",
+            "library/*.h",
+            "tests/include/test/drivers/*.h",
+            "3rdparty/everest/include/everest/everest.h",
+            "3rdparty/everest/include/everest/x25519.h"
+        ])
+        enum_consts = self.parse_enum_consts([
+            "include/mbedtls/*.h",
+            "library/*.h",
+            "3rdparty/everest/include/everest/everest.h",
+            "3rdparty/everest/include/everest/x25519.h"
+        ])
+        identifiers = self.parse_identifiers([
+            "include/mbedtls/*.h",
+            "include/psa/*.h",
+            "library/*.h",
+            "3rdparty/everest/include/everest/everest.h",
+            "3rdparty/everest/include/everest/x25519.h"
+        ])
+        mbed_words = self.parse_mbed_words([
+            "include/mbedtls/*.h",
+            "include/psa/*.h",
+            "library/*.h",
+            "3rdparty/everest/include/everest/everest.h",
+            "3rdparty/everest/include/everest/x25519.h",
+            "library/*.c",
+            "3rdparty/everest/library/everest.c",
+            "3rdparty/everest/library/x25519.c"
+        ])
+        symbols = self.parse_symbols()
+
+        # Remove identifier macros like mbedtls_printf or mbedtls_calloc
+        identifiers_justname = [x.name for x in identifiers]
+        actual_macros = []
+        for macro in all_macros:
+            if macro.name not in identifiers_justname:
+                actual_macros.append(macro)
+
+        self.log.debug("Found:")
+        # Aligns the counts on the assumption that none exceeds 4 digits
+        self.log.debug("  {:4} Total Macros".format(len(all_macros)))
+        self.log.debug("  {:4} Non-identifier Macros".format(len(actual_macros)))
+        self.log.debug("  {:4} Enum Constants".format(len(enum_consts)))
+        self.log.debug("  {:4} Identifiers".format(len(identifiers)))
+        self.log.debug("  {:4} Exported Symbols".format(len(symbols)))
+        return {
+            "macros": actual_macros,
+            "enum_consts": enum_consts,
+            "identifiers": identifiers,
+            "symbols": symbols,
+            "mbed_words": mbed_words
+        }
+
+    def is_file_excluded(self, path, exclude_wildcards):
+        """Whether the given file path is excluded."""
+        # exclude_wildcards may be None. Also, consider the global exclusions.
+        exclude_wildcards = (exclude_wildcards or []) + self.excluded_files
+        for pattern in exclude_wildcards:
+            if fnmatch.fnmatch(path, pattern):
+                return True
+        return False
+
+    def get_files(self, include_wildcards, exclude_wildcards):
+        """
+        Get all files that match any of the UNIX-style wildcards. While the
+        check_names script is designed only for use on UNIX/macOS (due to nm),
+        this function alone would work fine on Windows even with forward slashes
+        in the wildcard.
+
+        Args:
+        * include_wildcards: a List of shell-style wildcards to match filepaths.
+        * exclude_wildcards: a List of shell-style wildcards to exclude.
+
+        Returns a List of relative filepaths.
+        """
+        accumulator = set()
+
+        for include_wildcard in include_wildcards:
+            accumulator = accumulator.union(glob.iglob(include_wildcard))
+
+        return list(path for path in accumulator
+                    if not self.is_file_excluded(path, exclude_wildcards))
+
+    def parse_macros(self, include, exclude=None):
+        """
+        Parse all macros defined by #define preprocessor directives.
+
+        Args:
+        * include: A List of glob expressions to look for files through.
+        * exclude: A List of glob expressions for excluding files.
+
+        Returns a List of Match objects for the found macros.
+        """
+        macro_regex = re.compile(r"# *define +(?P<macro>\w+)")
+        exclusions = (
+            "asm", "inline", "EMIT", "_CRT_SECURE_NO_DEPRECATE", "MULADDC_"
+        )
+
+        files = self.get_files(include, exclude)
+        self.log.debug("Looking for macros in {} files".format(len(files)))
+
+        macros = []
+        for header_file in files:
+            with open(header_file, "r", encoding="utf-8") as header:
+                for line_no, line in enumerate(header):
+                    for macro in macro_regex.finditer(line):
+                        if macro.group("macro").startswith(exclusions):
+                            continue
+
+                        macros.append(Match(
+                            header_file,
+                            line,
+                            line_no,
+                            macro.span("macro"),
+                            macro.group("macro")))
+
+        return macros
+
+    def parse_mbed_words(self, include, exclude=None):
+        """
+        Parse all words in the file that begin with MBED, in and out of macros,
+        comments, anything.
+
+        Args:
+        * include: A List of glob expressions to look for files through.
+        * exclude: A List of glob expressions for excluding files.
+
+        Returns a List of Match objects for words beginning with MBED.
+        """
+        # Typos of TLS are common, hence the broader check below than MBEDTLS.
+        mbed_regex = re.compile(r"\bMBED.+?_[A-Z0-9_]*")
+        exclusions = re.compile(r"// *no-check-names|#error")
+
+        files = self.get_files(include, exclude)
+        self.log.debug("Looking for MBED words in {} files".format(len(files)))
+
+        mbed_words = []
+        for filename in files:
+            with open(filename, "r", encoding="utf-8") as fp:
+                for line_no, line in enumerate(fp):
+                    if exclusions.search(line):
+                        continue
+
+                    for name in mbed_regex.finditer(line):
+                        mbed_words.append(Match(
+                            filename,
+                            line,
+                            line_no,
+                            name.span(0),
+                            name.group(0)))
+
+        return mbed_words
+
+    def parse_enum_consts(self, include, exclude=None):
+        """
+        Parse all enum value constants that are declared.
+
+        Args:
+        * include: A List of glob expressions to look for files through.
+        * exclude: A List of glob expressions for excluding files.
+
+        Returns a List of Match objects for the findings.
+        """
+        files = self.get_files(include, exclude)
+        self.log.debug("Looking for enum consts in {} files".format(len(files)))
+
+        # Emulate a finite state machine to parse enum declarations.
+        # OUTSIDE_KEYWORD = outside the enum keyword
+        # IN_BRACES = inside enum opening braces
+        # IN_BETWEEN = between enum keyword and opening braces
+        states = enum.Enum("FSM", ["OUTSIDE_KEYWORD", "IN_BRACES", "IN_BETWEEN"])
+        enum_consts = []
+        for header_file in files:
+            state = states.OUTSIDE_KEYWORD
+            with open(header_file, "r", encoding="utf-8") as header:
+                for line_no, line in enumerate(header):
+                    # Match typedefs and brackets only when they are at the
+                    # beginning of the line -- if they are indented, they might
+                    # be sub-structures within structs, etc.
+                    if (state == states.OUTSIDE_KEYWORD and
+                            re.search(r"^(typedef +)?enum +{", line)):
+                        state = states.IN_BRACES
+                    elif (state == states.OUTSIDE_KEYWORD and
+                          re.search(r"^(typedef +)?enum", line)):
+                        state = states.IN_BETWEEN
+                    elif (state == states.IN_BETWEEN and
+                          re.search(r"^{", line)):
+                        state = states.IN_BRACES
+                    elif (state == states.IN_BRACES and
+                          re.search(r"^}", line)):
+                        state = states.OUTSIDE_KEYWORD
+                    elif (state == states.IN_BRACES and
+                          not re.search(r"^ *#", line)):
+                        enum_const = re.search(r"^ *(?P<enum_const>\w+)", line)
+                        if not enum_const:
+                            continue
+
+                        enum_consts.append(Match(
+                            header_file,
+                            line,
+                            line_no,
+                            enum_const.span("enum_const"),
+                            enum_const.group("enum_const")))
+
+        return enum_consts
+
+    def parse_identifiers(self, include, exclude=None):
+        """
+        Parse all lines of a header where a function/enum/struct/union/typedef
+        identifier is declared, based on some regex and heuristics. Highly
+        dependent on formatting style.
+
+        Args:
+        * include: A List of glob expressions to look for files through.
+        * exclude: A List of glob expressions for excluding files.
+
+        Returns a List of Match objects with identifiers.
+        """
+        identifier_regex = re.compile(
+            # Match " something(a" or " *something(a". Functions.
+            # Assumptions:
+            # - function definition from return type to one of its arguments is
+            #   all on one line
+            # - function definition line only contains alphanumeric, asterisk,
+            #   underscore, and open bracket
+            r".* \**(\w+) *\( *\w|"
+            # Match "(*something)(".
+            r".*\( *\* *(\w+) *\) *\(|"
+            # Match names of named data structures.
+            r"(?:typedef +)?(?:struct|union|enum) +(\w+)(?: *{)?$|"
+            # Match names of typedef instances, after closing bracket.
+            r"}? *(\w+)[;[].*"
+        )
+        # The regex below is indented for clarity.
+        exclusion_lines = re.compile(
+            r"^("
+                r"extern +\"C\"|" # pylint: disable=bad-continuation
+                r"(typedef +)?(struct|union|enum)( *{)?$|"
+                r"} *;?$|"
+                r"$|"
+                r"//|"
+                r"#"
+            r")"
+        )
+
+        files = self.get_files(include, exclude)
+        self.log.debug("Looking for identifiers in {} files".format(len(files)))
+
+        identifiers = []
+        for header_file in files:
+            with open(header_file, "r", encoding="utf-8") as header:
+                in_block_comment = False
+                # The previous line variable is used for concatenating lines
+                # when identifiers are formatted and spread across multiple
+                # lines.
+                previous_line = ""
+
+                for line_no, line in enumerate(header):
+                    # Skip parsing this line if a block comment ends on it,
+                    # but don't skip if it has just started -- there is a chance
+                    # it ends on the same line.
+                    if re.search(r"/\*", line):
+                        in_block_comment = not in_block_comment
+                    if re.search(r"\*/", line):
+                        in_block_comment = not in_block_comment
+                        continue
+
+                    if in_block_comment:
+                        previous_line = ""
+                        continue
+
+                    if exclusion_lines.search(line):
+                        previous_line = ""
+                        continue
+
+                    # If the line contains only space-separated alphanumeric
+                    # characters (or underscore, asterisk, or, open bracket),
+                    # and nothing else, high chance it's a declaration that
+                    # continues on the next line
+                    if re.search(r"^([\w\*\(]+\s+)+$", line):
+                        previous_line += line
+                        continue
+
+                    # If previous line seemed to start an unfinished declaration
+                    # (as above), concat and treat them as one.
+                    if previous_line:
+                        line = previous_line.strip() + " " + line.strip() + "\n"
+                        previous_line = ""
+
+                    # Skip parsing if line has a space in front = heuristic to
+                    # skip function argument lines (highly subject to formatting
+                    # changes)
+                    if line[0] == " ":
+                        continue
+
+                    identifier = identifier_regex.search(line)
+
+                    if not identifier:
+                        continue
+
+                    # Find the group that matched, and append it
+                    for group in identifier.groups():
+                        if not group:
+                            continue
+
+                        identifiers.append(Match(
+                            header_file,
+                            line,
+                            line_no,
+                            identifier.span(),
+                            group))
+
+        return identifiers
+
+    def parse_symbols(self):
+        """
+        Compile the Mbed TLS libraries, and parse the TLS, Crypto, and x509
+        object files using nm to retrieve the list of referenced symbols.
+        Exceptions thrown here are rethrown because they would be critical
+        errors that void several tests, and thus needs to halt the program. This
+        is explicitly done for clarity.
+
+        Returns a List of unique symbols defined and used in the libraries.
+        """
+        self.log.info("Compiling...")
+        symbols = []
+
+        # Back up the config and atomically compile with the full configratuion.
+        shutil.copy(
+            "include/mbedtls/config.h",
+            "include/mbedtls/config.h.bak"
+        )
+        try:
+            # Use check=True in all subprocess calls so that failures are raised
+            # as exceptions and logged.
+            subprocess.run(
+                ["python3", "scripts/config.py", "full"],
+                universal_newlines=True,
+                check=True
+            )
+            my_environment = os.environ.copy()
+            my_environment["CFLAGS"] = "-fno-asynchronous-unwind-tables"
+            # Run make clean separately to lib to prevent unwanted behavior when
+            # make is invoked with parallelism.
+            subprocess.run(
+                ["make", "clean"],
+                universal_newlines=True,
+                check=True
+            )
+            subprocess.run(
+                ["make", "lib"],
+                env=my_environment,
+                universal_newlines=True,
+                stdout=subprocess.PIPE,
+                stderr=subprocess.STDOUT,
+                check=True
+            )
+
+            # Perform object file analysis using nm
+            symbols = self.parse_symbols_from_nm([
+                "library/libmbedcrypto.a",
+                "library/libmbedtls.a",
+                "library/libmbedx509.a"
+            ])
+
+            subprocess.run(
+                ["make", "clean"],
+                universal_newlines=True,
+                check=True
+            )
+        except subprocess.CalledProcessError as error:
+            self.log.debug(error.output)
+            raise error
+        finally:
+            # Put back the original config regardless of there being errors.
+            # Works also for keyboard interrupts.
+            shutil.move(
+                "include/mbedtls/config.h.bak",
+                "include/mbedtls/config.h"
+            )
+
+        return symbols
+
+    def parse_symbols_from_nm(self, object_files):
+        """
+        Run nm to retrieve the list of referenced symbols in each object file.
+        Does not return the position data since it is of no use.
+
+        Args:
+        * object_files: a List of compiled object filepaths to search through.
+
+        Returns a List of unique symbols defined and used in any of the object
+        files.
+        """
+        nm_undefined_regex = re.compile(r"^\S+: +U |^$|^\S+:$")
+        nm_valid_regex = re.compile(r"^\S+( [0-9A-Fa-f]+)* . _*(?P<symbol>\w+)")
+        exclusions = ("FStar", "Hacl")
+
+        symbols = []
+
+        # Gather all outputs of nm
+        nm_output = ""
+        for lib in object_files:
+            nm_output += subprocess.run(
+                ["nm", "-og", lib],
+                universal_newlines=True,
+                stdout=subprocess.PIPE,
+                stderr=subprocess.STDOUT,
+                check=True
+            ).stdout
+
+        for line in nm_output.splitlines():
+            if not nm_undefined_regex.search(line):
+                symbol = nm_valid_regex.search(line)
+                if (symbol and not symbol.group("symbol").startswith(exclusions)):
+                    symbols.append(symbol.group("symbol"))
+                else:
+                    self.log.error(line)
+
+        return symbols
+
+class NameChecker():
+    """
+    Representation of the core name checking operation performed by this script.
+    """
+    def __init__(self, parse_result, log):
+        self.parse_result = parse_result
+        self.log = log
+
+    def perform_checks(self, quiet=False):
+        """
+        A comprehensive checker that performs each check in order, and outputs
+        a final verdict.
+
+        Args:
+        * quiet: whether to hide detailed problem explanation.
+        """
+        self.log.info("=============")
+        Problem.quiet = quiet
+        problems = 0
+        problems += self.check_symbols_declared_in_header()
+
+        pattern_checks = [
+            ("macros", MACRO_PATTERN),
+            ("enum_consts", CONSTANTS_PATTERN),
+            ("identifiers", IDENTIFIER_PATTERN)
+        ]
+        for group, check_pattern in pattern_checks:
+            problems += self.check_match_pattern(group, check_pattern)
+
+        problems += self.check_for_typos()
+
+        self.log.info("=============")
+        if problems > 0:
+            self.log.info("FAIL: {0} problem(s) to fix".format(str(problems)))
+            if quiet:
+                self.log.info("Remove --quiet to see explanations.")
+            else:
+                self.log.info("Use --quiet for minimal output.")
+            return 1
+        else:
+            self.log.info("PASS")
+            return 0
+
+    def check_symbols_declared_in_header(self):
+        """
+        Perform a check that all detected symbols in the library object files
+        are properly declared in headers.
+        Assumes parse_names_in_source() was called before this.
+
+        Returns the number of problems that need fixing.
+        """
+        problems = []
+
+        for symbol in self.parse_result["symbols"]:
+            found_symbol_declared = False
+            for identifier_match in self.parse_result["identifiers"]:
+                if symbol == identifier_match.name:
+                    found_symbol_declared = True
+                    break
+
+            if not found_symbol_declared:
+                problems.append(SymbolNotInHeader(symbol))
+
+        self.output_check_result("All symbols in header", problems)
+        return len(problems)
+
+    def check_match_pattern(self, group_to_check, check_pattern):
+        """
+        Perform a check that all items of a group conform to a regex pattern.
+        Assumes parse_names_in_source() was called before this.
+
+        Args:
+        * group_to_check: string key to index into self.parse_result.
+        * check_pattern: the regex to check against.
+
+        Returns the number of problems that need fixing.
+        """
+        problems = []
+
+        for item_match in self.parse_result[group_to_check]:
+            if not re.search(check_pattern, item_match.name):
+                problems.append(PatternMismatch(check_pattern, item_match))
+            # Double underscore should not be used for names
+            if re.search(r".*__.*", item_match.name):
+                problems.append(
+                    PatternMismatch("no double underscore allowed", item_match))
+
+        self.output_check_result(
+            "Naming patterns of {}".format(group_to_check),
+            problems)
+        return len(problems)
+
+    def check_for_typos(self):
+        """
+        Perform a check that all words in the soure code beginning with MBED are
+        either defined as macros, or as enum constants.
+        Assumes parse_names_in_source() was called before this.
+
+        Returns the number of problems that need fixing.
+        """
+        problems = []
+
+        # Set comprehension, equivalent to a list comprehension wrapped by set()
+        all_caps_names = {
+            match.name
+            for match
+            in self.parse_result["macros"] + self.parse_result["enum_consts"]}
+        typo_exclusion = re.compile(r"XXX|__|_$|^MBEDTLS_.*CONFIG_FILE$")
+
+        for name_match in self.parse_result["mbed_words"]:
+            found = name_match.name in all_caps_names
+
+            # Since MBEDTLS_PSA_ACCEL_XXX defines are defined by the
+            # PSA driver, they will not exist as macros. However, they
+            # should still be checked for typos using the equivalent
+            # BUILTINs that exist.
+            if "MBEDTLS_PSA_ACCEL_" in name_match.name:
+                found = name_match.name.replace(
+                    "MBEDTLS_PSA_ACCEL_",
+                    "MBEDTLS_PSA_BUILTIN_") in all_caps_names
+
+            if not found and not typo_exclusion.search(name_match.name):
+                problems.append(Typo(name_match))
+
+        self.output_check_result("Likely typos", problems)
+        return len(problems)
+
+    def output_check_result(self, name, problems):
+        """
+        Write out the PASS/FAIL status of a performed check depending on whether
+        there were problems.
+
+        Args:
+        * name: the name of the test
+        * problems: a List of encountered Problems
+        """
+        if problems:
+            self.log.info("{}: FAIL\n".format(name))
+            for problem in problems:
+                self.log.warning(str(problem))
+        else:
+            self.log.info("{}: PASS".format(name))
+
+def main():
+    """
+    Perform argument parsing, and create an instance of CodeParser and
+    NameChecker to begin the core operation.
+    """
+    parser = argparse.ArgumentParser(
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        description=(
+            "This script confirms that the naming of all symbols and identifiers "
+            "in Mbed TLS are consistent with the house style and are also "
+            "self-consistent.\n\n"
+            "Expected to be run from the MbedTLS root directory.")
+    )
+    parser.add_argument(
+        "-v", "--verbose",
+        action="store_true",
+        help="show parse results"
+    )
+    parser.add_argument(
+        "-q", "--quiet",
+        action="store_true",
+        help="hide unnecessary text, explanations, and highlighs"
+    )
+
+    args = parser.parse_args()
+
+    # Configure the global logger, which is then passed to the classes below
+    log = logging.getLogger()
+    log.setLevel(logging.DEBUG if args.verbose else logging.INFO)
+    log.addHandler(logging.StreamHandler())
+
+    try:
+        code_parser = CodeParser(log)
+        parse_result = code_parser.comprehensive_parse()
+    except Exception: # pylint: disable=broad-except
+        traceback.print_exc()
+        sys.exit(2)
+
+    name_checker = NameChecker(parse_result, log)
+    return_code = name_checker.perform_checks(quiet=args.quiet)
+
+    sys.exit(return_code)
+
+if __name__ == "__main__":
+    main()
diff --git a/tests/scripts/generate_psa_tests.py b/tests/scripts/generate_psa_tests.py
index 441b1c2..af25feb 100755
--- a/tests/scripts/generate_psa_tests.py
+++ b/tests/scripts/generate_psa_tests.py
@@ -88,9 +88,13 @@
     return frozenset(symbol
                      for line in open(filename)
                      for symbol in re.findall(r'\bPSA_WANT_\w+\b', line))
-IMPLEMENTED_DEPENDENCIES = read_implemented_dependencies('include/psa/crypto_config.h')
+_implemented_dependencies = None #type: Optional[FrozenSet[str]] #pylint: disable=invalid-name
 def hack_dependencies_not_implemented(dependencies: List[str]) -> None:
-    if not all(dep.lstrip('!') in IMPLEMENTED_DEPENDENCIES
+    global _implemented_dependencies #pylint: disable=global-statement,invalid-name
+    if _implemented_dependencies is None:
+        _implemented_dependencies = \
+            read_implemented_dependencies('include/psa/crypto_config.h')
+    if not all((dep.lstrip('!') in _implemented_dependencies or 'PSA_WANT' not in dep)
                for dep in dependencies):
         dependencies.append('DEPENDENCY_NOT_IMPLEMENTED_YET')
 
@@ -197,12 +201,15 @@
                 # supported or not depending on implementation capabilities,
                 # only generate the test case once.
                 continue
-            yield test_case_for_key_type_not_supported(
-                'generate', kt.expression, bits,
-                finish_family_dependencies(generate_dependencies, bits),
-                str(bits),
-                param_descr=param_descr,
-            )
+                # For public key we expect that key generation fails with
+                # INVALID_ARGUMENT. It is handled by KeyGenerate class.
+            if not kt.name.endswith('_PUBLIC_KEY'):
+                yield test_case_for_key_type_not_supported(
+                    'generate', kt.expression, bits,
+                    finish_family_dependencies(generate_dependencies, bits),
+                    str(bits),
+                    param_descr=param_descr,
+                )
             # To be added: derive
 
     ECC_KEY_TYPES = ('PSA_KEY_TYPE_ECC_KEY_PAIR',
@@ -223,6 +230,78 @@
                 yield from self.test_cases_for_key_type_not_supported(
                     kt, 0, param_descr='curve')
 
+def test_case_for_key_generation(
+        key_type: str, bits: int,
+        dependencies: List[str],
+        *args: str,
+        result: str = ''
+) -> test_case.TestCase:
+    """Return one test case exercising a key generation.
+    """
+    hack_dependencies_not_implemented(dependencies)
+    tc = test_case.TestCase()
+    short_key_type = re.sub(r'PSA_(KEY_TYPE|ECC_FAMILY)_', r'', key_type)
+    tc.set_description('PSA {} {}-bit'
+                       .format(short_key_type, bits))
+    tc.set_dependencies(dependencies)
+    tc.set_function('generate_key')
+    tc.set_arguments([key_type] + list(args) + [result])
+
+    return tc
+
+class KeyGenerate:
+    """Generate positive and negative (invalid argument) test cases for key generation."""
+
+    def __init__(self, info: Information) -> None:
+        self.constructors = info.constructors
+
+    ECC_KEY_TYPES = ('PSA_KEY_TYPE_ECC_KEY_PAIR',
+                     'PSA_KEY_TYPE_ECC_PUBLIC_KEY')
+
+    @staticmethod
+    def test_cases_for_key_type_key_generation(
+            kt: crypto_knowledge.KeyType
+    ) -> Iterator[test_case.TestCase]:
+        """Return test cases exercising key generation.
+
+        All key types can be generated except for public keys. For public key
+        PSA_ERROR_INVALID_ARGUMENT status is expected.
+        """
+        result = 'PSA_SUCCESS'
+
+        import_dependencies = [psa_want_symbol(kt.name)]
+        if kt.params is not None:
+            import_dependencies += [psa_want_symbol(sym)
+                                    for i, sym in enumerate(kt.params)]
+        if kt.name.endswith('_PUBLIC_KEY'):
+            # The library checks whether the key type is a public key generically,
+            # before it reaches a point where it needs support for the specific key
+            # type, so it returns INVALID_ARGUMENT for unsupported public key types.
+            generate_dependencies = []
+            result = 'PSA_ERROR_INVALID_ARGUMENT'
+        else:
+            generate_dependencies = import_dependencies
+            if kt.name == 'PSA_KEY_TYPE_RSA_KEY_PAIR':
+                generate_dependencies.append("MBEDTLS_GENPRIME")
+        for bits in kt.sizes_to_test():
+            yield test_case_for_key_generation(
+                kt.expression, bits,
+                finish_family_dependencies(generate_dependencies, bits),
+                str(bits),
+                result
+            )
+
+    def test_cases_for_key_generation(self) -> Iterator[test_case.TestCase]:
+        """Generate test cases that exercise the generation of keys."""
+        for key_type in sorted(self.constructors.key_types):
+            if key_type in self.ECC_KEY_TYPES:
+                continue
+            kt = crypto_knowledge.KeyType(key_type)
+            yield from self.test_cases_for_key_type_key_generation(kt)
+        for curve_family in sorted(self.constructors.ecc_curves):
+            for constr in self.ECC_KEY_TYPES:
+                kt = crypto_knowledge.KeyType(constr, [curve_family])
+                yield from self.test_cases_for_key_type_key_generation(kt)
 
 class StorageKey(psa_storage.Key):
     """Representation of a key for storage format testing."""
@@ -645,6 +724,8 @@
         test_case.write_data_file(filename, test_cases)
 
     TARGETS = {
+        'test_suite_psa_crypto_generate_key.generated':
+        lambda info: KeyGenerate(info).test_cases_for_key_generation(),
         'test_suite_psa_crypto_not_supported.generated':
         lambda info: NotSupported(info).test_cases_for_not_supported(),
         'test_suite_psa_crypto_storage_format.current':
diff --git a/tests/scripts/generate_test_code.py b/tests/scripts/generate_test_code.py
index 7382fb6..f5750aa 100755
--- a/tests/scripts/generate_test_code.py
+++ b/tests/scripts/generate_test_code.py
@@ -106,10 +106,6 @@
 Platform file contains platform specific setup code and test case
 dispatch code. For example, host_test.function reads test data
 file from host's file system and dispatches tests.
-In case of on-target target_test.function tests are not dispatched
-on target. Target code is kept minimum and only test functions are
-dispatched. Test case dispatch is done on the host using tools like
-Greentea.
 
 Template file:
 ---------
diff --git a/tests/scripts/list-enum-consts.pl b/tests/scripts/list-enum-consts.pl
deleted file mode 100755
index 88a062e..0000000
--- a/tests/scripts/list-enum-consts.pl
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/env perl
-#
-# Copyright The Mbed TLS Contributors
-# SPDX-License-Identifier: Apache-2.0
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-use warnings;
-use strict;
-
-use utf8;
-use open qw(:std utf8);
-
--d 'include/mbedtls' or die "$0: must be run from root\n";
-
-@ARGV = grep { ! /compat-1\.3\.h/ } <include/mbedtls/*.h>;
-push @ARGV, "3rdparty/everest/include/everest/everest.h";
-push @ARGV, "3rdparty/everest/include/everest/x25519.h";
-push @ARGV, glob("library/*.h");
-
-my @consts;
-my $state = 'out';
-while (<>)
-{
-    if( $state eq 'out' and /^(typedef )?enum \{/ ) {
-        $state = 'in';
-    } elsif( $state eq 'out' and /^(typedef )?enum/ ) {
-        $state = 'start';
-    } elsif( $state eq 'start' and /{/ ) {
-        $state = 'in';
-    } elsif( $state eq 'in' and /}/ ) {
-        $state = 'out';
-    } elsif( $state eq 'in' and not /^#/) {
-        s/=.*//; s!/\*.*!!; s/,.*//; s/\s+//g; chomp;
-        push @consts, $_ if $_;
-    }
-}
-
-open my $fh, '>', 'enum-consts' or die;
-print $fh "$_\n" for sort @consts;
-close $fh or die;
-
-printf "%8d enum-consts\n", scalar @consts;
diff --git a/tests/scripts/list-identifiers.sh b/tests/scripts/list-identifiers.sh
index a1c3d2d..9b93080 100755
--- a/tests/scripts/list-identifiers.sh
+++ b/tests/scripts/list-identifiers.sh
@@ -1,8 +1,11 @@
 #!/bin/bash
 #
 # Create a file named identifiers containing identifiers from internal header
-# files or all header files, based on --internal flag.
+# files, based on the --internal flag.
 # Outputs the line count of the file to stdout.
+# A very thin wrapper around list_internal_identifiers.py for backwards
+# compatibility.
+# Must be run from Mbed TLS root.
 #
 # Usage: list-identifiers.sh [ -i | --internal ]
 #
@@ -24,7 +27,7 @@
 set -eu
 
 if [ -d include/mbedtls ]; then :; else
-    echo "$0: must be run from root" >&2
+    echo "$0: Must be run from Mbed TLS root" >&2
     exit 1
 fi
 
@@ -47,32 +50,17 @@
 
 if [ $INTERNAL ]
 then
-    HEADERS=$( ls include/mbedtls/*_internal.h library/*.h | egrep -v 'compat-1\.3\.h|bn_mul' )
+    tests/scripts/list_internal_identifiers.py
+    wc -l identifiers
 else
-    HEADERS=$( ls include/mbedtls/*.h include/psa/*.h library/*.h | egrep -v 'compat-1\.3\.h|bn_mul' )
-    HEADERS="$HEADERS 3rdparty/everest/include/everest/everest.h 3rdparty/everest/include/everest/x25519.h"
+    cat <<EOF
+Sorry, this script has to be called with --internal.
+
+This script exists solely for backwards compatibility with the previous
+iteration of list-identifiers.sh, of which only the --internal option remains in
+use. It is a thin wrapper around list_internal_identifiers.py.
+
+check-names.sh, which used to depend on this script, has been replaced with
+check_names.py and is now self-complete.
+EOF
 fi
-
-rm -f identifiers
-
-grep '^[^ /#{]' $HEADERS | \
-    sed -e 's/^[^:]*://' | \
-    egrep -v '^(extern "C"|(typedef )?(struct|union|enum)( {)?$|};?$)' \
-    > _decls
-
-if true; then
-sed -n -e 's/.* \**\([a-zA-Z_][a-zA-Z0-9_]*\)(.*/\1/p' \
-       -e 's/.*(\*\(.*\))(.*/\1/p' _decls
-grep -v '(' _decls | sed -e 's/\([a-zA-Z0-9_]*\)[;[].*/\1/' -e 's/.* \**//'
-fi > _identifiers
-
-if [ $( wc -l < _identifiers ) -eq $( wc -l < _decls ) ]; then
-    rm _decls
-    egrep -v '^(u?int(16|32|64)_t)$' _identifiers | sort > identifiers
-    rm _identifiers
-else
-    echo "$0: oops, lost some identifiers" 2>&1
-    exit 1
-fi
-
-wc -l identifiers
diff --git a/tests/scripts/list-macros.sh b/tests/scripts/list-macros.sh
deleted file mode 100755
index 8ed9571..0000000
--- a/tests/scripts/list-macros.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-#
-# Copyright The Mbed TLS Contributors
-# SPDX-License-Identifier: Apache-2.0
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -eu
-
-if [ -d include/mbedtls ]; then :; else
-    echo "$0: must be run from root" >&2
-    exit 1
-fi
-
-HEADERS=$( ls include/mbedtls/*.h include/psa/*.h tests/include/test/drivers/*.h | egrep -v 'compat-1\.3\.h' )
-HEADERS="$HEADERS library/*.h"
-HEADERS="$HEADERS 3rdparty/everest/include/everest/everest.h 3rdparty/everest/include/everest/x25519.h"
-
-sed -n -e 's/.*#define \([a-zA-Z0-9_]*\).*/\1/p' $HEADERS \
-    | egrep -v '^(asm|inline|EMIT|_CRT_SECURE_NO_DEPRECATE)$|^MULADDC_' \
-    | sort -u > macros
-
-# For include/mbedtls/config_psa.h need to ignore the MBEDTLS_xxx define
-# in that file since they may not be defined in include/psa/crypto_config.h
-# This line renames the potentially missing defines to ones that should
-# be present.
-sed -ne 's/^MBEDTLS_PSA_BUILTIN_/MBEDTLS_PSA_ACCEL_/p' <macros >>macros
-
-wc -l macros
diff --git a/tests/scripts/list-symbols.sh b/tests/scripts/list-symbols.sh
deleted file mode 100755
index 8bdc55f..0000000
--- a/tests/scripts/list-symbols.sh
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/bin/sh
-#
-# Copyright The Mbed TLS Contributors
-# SPDX-License-Identifier: Apache-2.0
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -eu
-
-if [ -d include/mbedtls ]; then :; else
-    echo "$0: must be run from root" >&2
-    exit 1
-fi
-
-if grep -i cmake Makefile >/dev/null; then
-    echo "$0: not compatible with cmake" >&2
-    exit 1
-fi
-
-cp include/mbedtls/config.h include/mbedtls/config.h.bak
-scripts/config.py full
-make clean
-make_ret=
-CFLAGS=-fno-asynchronous-unwind-tables make lib \
-      >list-symbols.make.log 2>&1 ||
-  {
-    make_ret=$?
-    echo "Build failure: CFLAGS=-fno-asynchronous-unwind-tables make lib"
-    cat list-symbols.make.log >&2
-  }
-rm list-symbols.make.log
-mv include/mbedtls/config.h.bak include/mbedtls/config.h
-if [ -n "$make_ret" ]; then
-    exit "$make_ret"
-fi
-
-if uname | grep -F Darwin >/dev/null; then
-    nm -gUj library/libmbed*.a 2>/dev/null | sed -n -e 's/^_//p' | grep -v -e ^FStar -e ^Hacl
-elif uname | grep -F Linux >/dev/null; then
-    nm -og library/libmbed*.a | grep -v '^[^ ]*: *U \|^$\|^[^ ]*:$' | sed 's/^[^ ]* . //' | grep -v -e ^FStar -e ^Hacl
-fi | sort > exported-symbols
-make clean
-
-wc -l exported-symbols
diff --git a/tests/scripts/list_internal_identifiers.py b/tests/scripts/list_internal_identifiers.py
new file mode 100755
index 0000000..779a16f
--- /dev/null
+++ b/tests/scripts/list_internal_identifiers.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python3
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+This script generates a file called identifiers that contains all Mbed TLS
+identifiers found on internal headers. This is the equivalent of what was
+previously `list-identifiers.sh --internal`, and is useful for generating an
+exclusion file list for ABI/API checking, since we do not promise compatibility
+for them.
+
+It uses the CodeParser class from check_names.py to perform the parsing.
+
+The script returns 0 on success, 1 if there is a script error.
+Must be run from Mbed TLS root.
+"""
+
+import argparse
+import logging
+from check_names import CodeParser
+
+def main():
+    parser = argparse.ArgumentParser(
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        description=(
+            "This script writes a list of parsed identifiers in internal "
+            "headers to \"identifiers\". This is useful for generating a list "
+            "of names to exclude from API/ABI compatibility checking. "))
+
+    parser.parse_args()
+
+    name_check = CodeParser(logging.getLogger())
+    result = name_check.parse_identifiers([
+        "include/mbedtls/*_internal.h",
+        "library/*.h"
+    ])
+    result.sort(key=lambda x: x.name)
+
+    identifiers = ["{}\n".format(match.name) for match in result]
+    with open("identifiers", "w", encoding="utf-8") as f:
+        f.writelines(identifiers)
+
+if __name__ == "__main__":
+    main()
diff --git a/tests/scripts/mbedtls_test.py b/tests/scripts/mbedtls_test.py
deleted file mode 100755
index 64f12bb..0000000
--- a/tests/scripts/mbedtls_test.py
+++ /dev/null
@@ -1,382 +0,0 @@
-#!/usr/bin/env python3
-
-# Greentea host test script for Mbed TLS on-target test suite testing.
-#
-# Copyright The Mbed TLS Contributors
-# SPDX-License-Identifier: Apache-2.0
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-"""
-Mbed TLS on-target test suite tests are implemented as Greentea
-tests. Greentea tests are implemented in two parts: target test and
-host test. Target test is a C application that is built for the
-target platform and executes on the target. Host test is a Python
-class derived from mbed_host_tests.BaseHostTest. Target communicates
-with the host over serial for the test data and sends back the result.
-
-Python tool mbedgt (Greentea) is responsible for flashing the test
-binary on to the target and dynamically loading this host test module.
-
-Greentea documentation can be found here:
-https://github.com/ARMmbed/greentea
-"""
-
-
-import re
-import os
-import binascii
-
-from mbed_host_tests import BaseHostTest, event_callback # type: ignore # pylint: disable=import-error
-
-
-class TestDataParserError(Exception):
-    """Indicates error in test data, read from .data file."""
-    pass
-
-
-class TestDataParser:
-    """
-    Parses test name, dependencies, test function name and test parameters
-    from the data file.
-    """
-
-    def __init__(self):
-        """
-        Constructor
-        """
-        self.tests = []
-
-    def parse(self, data_file):
-        """
-        Data file parser.
-
-        :param data_file: Data file path
-        """
-        with open(data_file, 'r') as data_f:
-            self.__parse(data_f)
-
-    @staticmethod
-    def __escaped_split(inp_str, split_char):
-        """
-        Splits inp_str on split_char except when escaped.
-
-        :param inp_str: String to split
-        :param split_char: Split character
-        :return: List of splits
-        """
-        split_colon_fn = lambda x: re.sub(r'\\' + split_char, split_char, x)
-        if len(split_char) > 1:
-            raise ValueError('Expected split character. Found string!')
-        out = list(map(split_colon_fn, re.split(r'(?<!\\)' + split_char, inp_str)))
-        out = [x for x in out if x]
-        return out
-
-    def __parse(self, data_f):
-        """
-        Parses data file using supplied file object.
-
-        :param data_f: Data file object
-        :return:
-        """
-        for line in data_f:
-            line = line.strip()
-            if not line:
-                continue
-            # Read test name
-            name = line
-
-            # Check dependencies
-            dependencies = []
-            line = next(data_f).strip()
-            match = re.search('depends_on:(.*)', line)
-            if match:
-                dependencies = [int(x) for x in match.group(1).split(':')]
-                line = next(data_f).strip()
-
-            # Read test vectors
-            line = line.replace('\\n', '\n')
-            parts = self.__escaped_split(line, ':')
-            function_name = int(parts[0])
-            args = parts[1:]
-            args_count = len(args)
-            if args_count % 2 != 0:
-                err_str_fmt = "Number of test arguments({}) should be even: {}"
-                raise TestDataParserError(err_str_fmt.format(args_count, line))
-            grouped_args = [(args[i * 2], args[(i * 2) + 1])
-                            for i in range(int(len(args)/2))]
-            self.tests.append((name, function_name, dependencies,
-                               grouped_args))
-
-    def get_test_data(self):
-        """
-        Returns test data.
-        """
-        return self.tests
-
-
-class MbedTlsTest(BaseHostTest):
-    """
-    Host test for Mbed TLS unit tests. This script is loaded at
-    run time by Greentea for executing Mbed TLS test suites. Each
-    communication from the target is received in this object as
-    an event, which is then handled by the event handler method
-    decorated by the associated event. Ex: @event_callback('GO').
-
-    Target test sends requests for dispatching next test. It reads
-    tests from the intermediate data file and sends test function
-    identifier, dependency identifiers, expression identifiers and
-    the test data in binary form. Target test checks dependencies
-    , evaluate integer constant expressions and dispatches the test
-    function with received test parameters. After test function is
-    finished, target sends the result. This class handles the result
-    event and prints verdict in the form that Greentea understands.
-
-    """
-    # status/error codes from suites/helpers.function
-    DEPENDENCY_SUPPORTED = 0
-    KEY_VALUE_MAPPING_FOUND = DEPENDENCY_SUPPORTED
-    DISPATCH_TEST_SUCCESS = DEPENDENCY_SUPPORTED
-
-    KEY_VALUE_MAPPING_NOT_FOUND = -1    # Expression Id not found.
-    DEPENDENCY_NOT_SUPPORTED = -2       # Dependency not supported.
-    DISPATCH_TEST_FN_NOT_FOUND = -3     # Test function not found.
-    DISPATCH_INVALID_TEST_DATA = -4     # Invalid parameter type.
-    DISPATCH_UNSUPPORTED_SUITE = -5     # Test suite not supported/enabled.
-
-    def __init__(self):
-        """
-        Constructor initialises test index to 0.
-        """
-        super(MbedTlsTest, self).__init__()
-        self.tests = []
-        self.test_index = -1
-        self.dep_index = 0
-        self.suite_passed = True
-        self.error_str = dict()
-        self.error_str[self.DEPENDENCY_SUPPORTED] = \
-            'DEPENDENCY_SUPPORTED'
-        self.error_str[self.KEY_VALUE_MAPPING_NOT_FOUND] = \
-            'KEY_VALUE_MAPPING_NOT_FOUND'
-        self.error_str[self.DEPENDENCY_NOT_SUPPORTED] = \
-            'DEPENDENCY_NOT_SUPPORTED'
-        self.error_str[self.DISPATCH_TEST_FN_NOT_FOUND] = \
-            'DISPATCH_TEST_FN_NOT_FOUND'
-        self.error_str[self.DISPATCH_INVALID_TEST_DATA] = \
-            'DISPATCH_INVALID_TEST_DATA'
-        self.error_str[self.DISPATCH_UNSUPPORTED_SUITE] = \
-            'DISPATCH_UNSUPPORTED_SUITE'
-
-    def setup(self):
-        """
-        Setup hook implementation. Reads test suite data file and parses out
-        tests.
-        """
-        binary_path = self.get_config_item('image_path')
-        script_dir = os.path.split(os.path.abspath(__file__))[0]
-        suite_name = os.path.splitext(os.path.basename(binary_path))[0]
-        data_file = ".".join((suite_name, 'datax'))
-        data_file = os.path.join(script_dir, '..', 'mbedtls',
-                                 suite_name, data_file)
-        if os.path.exists(data_file):
-            self.log("Running tests from %s" % data_file)
-            parser = TestDataParser()
-            parser.parse(data_file)
-            self.tests = parser.get_test_data()
-            self.print_test_info()
-        else:
-            self.log("Data file not found: %s" % data_file)
-            self.notify_complete(False)
-
-    def print_test_info(self):
-        """
-        Prints test summary read by Greentea to detect test cases.
-        """
-        self.log('{{__testcase_count;%d}}' % len(self.tests))
-        for name, _, _, _ in self.tests:
-            self.log('{{__testcase_name;%s}}' % name)
-
-    @staticmethod
-    def align_32bit(data_bytes):
-        """
-        4 byte aligns input byte array.
-
-        :return:
-        """
-        data_bytes += bytearray((4 - (len(data_bytes))) % 4)
-
-    @staticmethod
-    def hex_str_bytes(hex_str):
-        """
-        Converts Hex string representation to byte array
-
-        :param hex_str: Hex in string format.
-        :return: Output Byte array
-        """
-        if hex_str[0] != '"' or hex_str[len(hex_str) - 1] != '"':
-            raise TestDataParserError("HEX test parameter missing '\"':"
-                                      " %s" % hex_str)
-        hex_str = hex_str.strip('"')
-        if len(hex_str) % 2 != 0:
-            raise TestDataParserError("HEX parameter len should be mod of "
-                                      "2: %s" % hex_str)
-
-        data_bytes = binascii.unhexlify(hex_str)
-        return data_bytes
-
-    @staticmethod
-    def int32_to_big_endian_bytes(i):
-        """
-        Coverts i to byte array in big endian format.
-
-        :param i: Input integer
-        :return: Output bytes array in big endian or network order
-        """
-        data_bytes = bytearray([((i >> x) & 0xff) for x in [24, 16, 8, 0]])
-        return data_bytes
-
-    def test_vector_to_bytes(self, function_id, dependencies, parameters):
-        """
-        Converts test vector into a byte array that can be sent to the target.
-
-        :param function_id: Test Function Identifier
-        :param dependencies: Dependency list
-        :param parameters: Test function input parameters
-        :return: Byte array and its length
-        """
-        data_bytes = bytearray([len(dependencies)])
-        if dependencies:
-            data_bytes += bytearray(dependencies)
-        data_bytes += bytearray([function_id, len(parameters)])
-        for typ, param in parameters:
-            if typ in ('int', 'exp'):
-                i = int(param, 0)
-                data_bytes += b'I' if typ == 'int' else b'E'
-                self.align_32bit(data_bytes)
-                data_bytes += self.int32_to_big_endian_bytes(i)
-            elif typ == 'char*':
-                param = param.strip('"')
-                i = len(param) + 1  # + 1 for null termination
-                data_bytes += b'S'
-                self.align_32bit(data_bytes)
-                data_bytes += self.int32_to_big_endian_bytes(i)
-                data_bytes += bytearray(param, encoding='ascii')
-                data_bytes += b'\0'   # Null terminate
-            elif typ == 'hex':
-                binary_data = self.hex_str_bytes(param)
-                data_bytes += b'H'
-                self.align_32bit(data_bytes)
-                i = len(binary_data)
-                data_bytes += self.int32_to_big_endian_bytes(i)
-                data_bytes += binary_data
-        length = self.int32_to_big_endian_bytes(len(data_bytes))
-        return data_bytes, length
-
-    def run_next_test(self):
-        """
-        Fetch next test information and execute the test.
-
-        """
-        self.test_index += 1
-        self.dep_index = 0
-        if self.test_index < len(self.tests):
-            name, function_id, dependencies, args = self.tests[self.test_index]
-            self.run_test(name, function_id, dependencies, args)
-        else:
-            self.notify_complete(self.suite_passed)
-
-    def run_test(self, name, function_id, dependencies, args):
-        """
-        Execute the test on target by sending next test information.
-
-        :param name: Test name
-        :param function_id: function identifier
-        :param dependencies: Dependencies list
-        :param args: test parameters
-        :return:
-        """
-        self.log("Running: %s" % name)
-
-        param_bytes, length = self.test_vector_to_bytes(function_id,
-                                                        dependencies, args)
-        self.send_kv(
-            ''.join('{:02x}'.format(x) for x in length),
-            ''.join('{:02x}'.format(x) for x in param_bytes)
-        )
-
-    @staticmethod
-    def get_result(value):
-        """
-        Converts result from string type to integer
-        :param value: Result code in string
-        :return: Integer result code. Value is from the test status
-                 constants defined under the MbedTlsTest class.
-        """
-        try:
-            return int(value)
-        except ValueError:
-            ValueError("Result should return error number. "
-                       "Instead received %s" % value)
-
-    @event_callback('GO')
-    def on_go(self, _key, _value, _timestamp):
-        """
-        Sent by the target to start first test.
-
-        :param _key: Event key
-        :param _value: Value. ignored
-        :param _timestamp: Timestamp ignored.
-        :return:
-        """
-        self.run_next_test()
-
-    @event_callback("R")
-    def on_result(self, _key, value, _timestamp):
-        """
-        Handle result. Prints test start, finish required by Greentea
-        to detect test execution.
-
-        :param _key: Event key
-        :param value: Value. ignored
-        :param _timestamp: Timestamp ignored.
-        :return:
-        """
-        int_val = self.get_result(value)
-        name, _, _, _ = self.tests[self.test_index]
-        self.log('{{__testcase_start;%s}}' % name)
-        self.log('{{__testcase_finish;%s;%d;%d}}' % (name, int_val == 0,
-                                                     int_val != 0))
-        if int_val != 0:
-            self.suite_passed = False
-        self.run_next_test()
-
-    @event_callback("F")
-    def on_failure(self, _key, value, _timestamp):
-        """
-        Handles test execution failure. That means dependency not supported or
-        Test function not supported. Hence marking test as skipped.
-
-        :param _key: Event key
-        :param value: Value. ignored
-        :param _timestamp: Timestamp ignored.
-        :return:
-        """
-        int_val = self.get_result(value)
-        if int_val in self.error_str:
-            err = self.error_str[int_val]
-        else:
-            err = 'Unknown error'
-        # For skip status, do not write {{__testcase_finish;...}}
-        self.log("Error: %s" % err)
-        self.run_next_test()
diff --git a/tests/scripts/test_psa_compliance.py b/tests/scripts/test_psa_compliance.py
new file mode 100755
index 0000000..3b5205e
--- /dev/null
+++ b/tests/scripts/test_psa_compliance.py
@@ -0,0 +1,146 @@
+#!/usr/bin/env python3
+"""Run the PSA Cryto API compliance test suite.
+Clone the repo and check out the commit specified by PSA_ARCH_TEST_REPO and PSA_ARCH_TEST_REF,
+then complie and run the test suite. The clone is stored at <Mbed TLS root>/psa-arch-tests.
+Known defects in either the test suite or mbedtls - identified by their test number - are ignored,
+while unexpected failures AND successes are reported as errors,
+to help keep the list of known defects as up to date as possible.
+"""
+
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import re
+import shutil
+import subprocess
+import sys
+
+# PSA Compliance tests we expect to fail due to known defects in Mbed TLS (or the test suite)
+# The test numbers correspond to the numbers used by the console output of the test suite.
+# Test number 2xx corresponds to the files in the folder
+# psa-arch-tests/api-tests/dev_apis/crypto/test_c0xx
+EXPECTED_FAILURES = {
+    # Multipart AEAD is not supported in Mbed TLS 2.x.
+    252, 253, 254, 255, 256, 257, 258, 259, 260, 261,
+
+    # psa_hash_suspend() and psa_hash_resume() are not supported.
+    # - Tracked in issue #3274
+    262, 263
+}
+
+# We currently use a fork of ARM-software/psa-arch-tests, with a couple of downstream patches
+# that allow it to build with Mbed TLS 2, and fixes a couple of issues in the compliance test suite.
+# These fixes allow the tests numbered 216, 248 and 249 to complete successfully.
+#
+# Once all the fixes are upstreamed, this fork should be replaced with an upstream commit/tag.
+# - Tracked in issue #5145
+#
+# Web URL: https://github.com/bensze01/psa-arch-tests/tree/fixes-for-mbedtls-2
+PSA_ARCH_TESTS_REPO = 'https://github.com/bensze01/psa-arch-tests.git'
+PSA_ARCH_TESTS_REF = 'fixes-for-mbedtls-2'
+
+#pylint: disable=too-many-branches,too-many-statements
+def main():
+    mbedtls_dir = os.getcwd()
+
+    if not os.path.exists('library/libmbedcrypto.a'):
+        subprocess.check_call(['make', '-C', 'library', 'libmbedcrypto.a'])
+
+    psa_arch_tests_dir = 'psa-arch-tests'
+    os.makedirs(psa_arch_tests_dir, exist_ok=True)
+    try:
+        os.chdir(psa_arch_tests_dir)
+
+        # Reuse existing local clone
+        subprocess.check_call(['git', 'init'])
+        subprocess.check_call(['git', 'fetch', PSA_ARCH_TESTS_REPO, PSA_ARCH_TESTS_REF])
+        subprocess.check_call(['git', 'checkout', 'FETCH_HEAD'])
+
+        build_dir = 'api-tests/build'
+        try:
+            shutil.rmtree(build_dir)
+        except FileNotFoundError:
+            pass
+        os.mkdir(build_dir)
+        os.chdir(build_dir)
+
+        #pylint: disable=bad-continuation
+        subprocess.check_call([
+            'cmake', '..',
+                     '-GUnix Makefiles',
+                     '-DTARGET=tgt_dev_apis_stdc',
+                     '-DTOOLCHAIN=HOST_GCC',
+                     '-DSUITE=CRYPTO',
+                     '-DMISSING_CRYPTO_1_0=1',
+                     '-DPSA_CRYPTO_LIB_FILENAME={}/library/libmbedcrypto.a'.format(mbedtls_dir),
+                     '-DPSA_INCLUDE_PATHS={}/include'.format(mbedtls_dir)
+        ])
+        subprocess.check_call(['cmake', '--build', '.'])
+
+        proc = subprocess.Popen(['./psa-arch-tests-crypto'],
+                                bufsize=1, stdout=subprocess.PIPE, universal_newlines=True)
+
+        test_re = re.compile(
+            '^TEST: (?P<test_num>[0-9]*)|'
+            '^TEST RESULT: (?P<test_result>FAILED|PASSED)'
+        )
+        test = -1
+        unexpected_successes = set(EXPECTED_FAILURES)
+        expected_failures = []
+        unexpected_failures = []
+        for line in proc.stdout:
+            print(line, end='')
+            match = test_re.match(line)
+            if match is not None:
+                groupdict = match.groupdict()
+                test_num = groupdict['test_num']
+                if test_num is not None:
+                    test = int(test_num)
+                elif groupdict['test_result'] == 'FAILED':
+                    try:
+                        unexpected_successes.remove(test)
+                        expected_failures.append(test)
+                        print('Expected failure, ignoring')
+                    except KeyError:
+                        unexpected_failures.append(test)
+                        print('ERROR: Unexpected failure')
+                elif test in unexpected_successes:
+                    print('ERROR: Unexpected success')
+        proc.wait()
+
+        print()
+        print('***** test_psa_compliance.py report ******')
+        print()
+        print('Expected failures:', ', '.join(str(i) for i in expected_failures))
+        print('Unexpected failures:', ', '.join(str(i) for i in unexpected_failures))
+        print('Unexpected successes:', ', '.join(str(i) for i in sorted(unexpected_successes)))
+        print()
+        if unexpected_successes or unexpected_failures:
+            if unexpected_successes:
+                print('Unexpected successes encountered.')
+                print('Please remove the corresponding tests from '
+                      'EXPECTED_FAILURES in tests/scripts/compliance_test.py')
+                print()
+            print('FAILED')
+            return 1
+        else:
+            print('SUCCESS')
+            return 0
+    finally:
+        os.chdir(mbedtls_dir)
+
+if __name__ == '__main__':
+    sys.exit(main())
diff --git a/tests/src/helpers.c b/tests/src/helpers.c
index bf6c1d9..c53e4fc 100644
--- a/tests/src/helpers.c
+++ b/tests/src/helpers.c
@@ -113,6 +113,31 @@
     mbedtls_test_info.test = 0;
     mbedtls_test_info.line_no = 0;
     mbedtls_test_info.filename = 0;
+    memset( mbedtls_test_info.line1, 0, sizeof( mbedtls_test_info.line1 ) );
+    memset( mbedtls_test_info.line2, 0, sizeof( mbedtls_test_info.line2 ) );
+}
+
+int mbedtls_test_equal( const char *test, int line_no, const char* filename,
+                        unsigned long long value1, unsigned long long value2 )
+{
+    if( value1 == value2 )
+        return( 1 );
+    if( mbedtls_test_info.result == MBEDTLS_TEST_RESULT_FAILED )
+    {
+        /* We've already recorded the test as having failed. Don't
+         * overwrite any previous information about the failure. */
+        return( 0 );
+    }
+    mbedtls_test_fail( test, line_no, filename );
+    (void) mbedtls_snprintf( mbedtls_test_info.line1,
+                             sizeof( mbedtls_test_info.line1 ),
+                             "lhs = 0x%016llx = %lld",
+                             value1, (long long) value1 );
+    (void) mbedtls_snprintf( mbedtls_test_info.line2,
+                             sizeof( mbedtls_test_info.line2 ),
+                             "rhs = 0x%016llx = %lld",
+                             value2, (long long) value2 );
+    return( 0 );
 }
 
 int mbedtls_test_unhexify( unsigned char *obuf,
diff --git a/tests/src/psa_crypto_helpers.c b/tests/src/psa_crypto_helpers.c
index d9d841a..299b6d1 100644
--- a/tests/src/psa_crypto_helpers.c
+++ b/tests/src/psa_crypto_helpers.c
@@ -22,6 +22,7 @@
 
 #include <test/helpers.h>
 #include <test/macros.h>
+#include <psa_crypto_slot_management.h>
 #include <test/psa_crypto_helpers.h>
 
 #if defined(MBEDTLS_PSA_CRYPTO_C)
diff --git a/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c
index e4e55c9..fc58fbd 100644
--- a/tests/src/psa_exercise_key.c
+++ b/tests/src/psa_exercise_key.c
@@ -29,6 +29,7 @@
 #include <psa/crypto.h>
 
 #include <test/asn1_helpers.h>
+#include <psa_crypto_slot_management.h>
 #include <test/psa_crypto_helpers.h>
 
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
@@ -306,7 +307,7 @@
         psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
 
         /* If the policy allows signing with any hash, just pick one. */
-        if( PSA_ALG_IS_HASH_AND_SIGN( alg ) && hash_alg == PSA_ALG_ANY_HASH )
+        if( PSA_ALG_IS_SIGN_HASH( alg ) && hash_alg == PSA_ALG_ANY_HASH )
         {
     #if defined(KNOWN_SUPPORTED_HASH_ALG)
             hash_alg = KNOWN_SUPPORTED_HASH_ALG;
@@ -663,7 +664,7 @@
         TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
                                           MBEDTLS_ASN1_SEQUENCE |
                                           MBEDTLS_ASN1_CONSTRUCTED ), 0 );
-        TEST_EQUAL( p + len, end );
+        TEST_EQUAL( len, end - p );
         if( ! mbedtls_test_asn1_skip_integer( &p, end, 0, 0, 0 ) )
             goto exit;
         if( ! mbedtls_test_asn1_skip_integer( &p, end, bits, bits, 1 ) )
@@ -684,7 +685,7 @@
             goto exit;
         if( ! mbedtls_test_asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
             goto exit;
-        TEST_EQUAL( p, end );
+        TEST_EQUAL( p - end, 0 );
 
         TEST_ASSERT( exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE );
     }
@@ -716,12 +717,12 @@
                                           MBEDTLS_ASN1_SEQUENCE |
                                           MBEDTLS_ASN1_CONSTRUCTED ),
                     0 );
-        TEST_EQUAL( p + len, end );
+        TEST_EQUAL( len, end - p );
         if( ! mbedtls_test_asn1_skip_integer( &p, end, bits, bits, 1 ) )
             goto exit;
         if( ! mbedtls_test_asn1_skip_integer( &p, end, 2, bits, 1 ) )
             goto exit;
-        TEST_EQUAL( p, end );
+        TEST_EQUAL( p - end, 0 );
 
 
         TEST_ASSERT( exported_length <=
@@ -925,7 +926,7 @@
 {
     if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
     {
-        if( PSA_ALG_IS_HASH_AND_SIGN( alg ) )
+        if( PSA_ALG_IS_SIGN_HASH( alg ) )
         {
             if( PSA_ALG_SIGN_GET_HASH( alg ) )
                 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index f17f2fd..6f25cff 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -77,6 +77,14 @@
     O_LEGACY_CLI=false
 fi
 
+if [ -n "${OPENSSL_NEXT:-}" ]; then
+    O_NEXT_SRV="$OPENSSL_NEXT s_server -www -cert data_files/server5.crt -key data_files/server5.key"
+    O_NEXT_CLI="echo 'GET / HTTP/1.0' | $OPENSSL_NEXT s_client"
+else
+    O_NEXT_SRV=false
+    O_NEXT_CLI=false
+fi
+
 if [ -n "${GNUTLS_NEXT_SERV:-}" ]; then
     G_NEXT_SRV="$GNUTLS_NEXT_SERV --x509certfile data_files/server5.crt --x509keyfile data_files/server5.key"
 else
@@ -355,6 +363,19 @@
     fi
 }
 
+requires_openssl_next() {
+    if [ -z "${OPENSSL_NEXT_AVAILABLE:-}" ]; then
+        if which "${OPENSSL_NEXT:-}" >/dev/null 2>&1; then
+            OPENSSL_NEXT_AVAILABLE="YES"
+        else
+            OPENSSL_NEXT_AVAILABLE="NO"
+        fi
+    fi
+    if [ "$OPENSSL_NEXT_AVAILABLE" = "NO" ]; then
+        SKIP_NEXT="YES"
+    fi
+}
+
 # skip next test if IPv6 isn't available on this host
 requires_ipv6() {
     if [ -z "${HAS_IPV6:-}" ]; then
@@ -464,6 +485,32 @@
     fi
 }
 
+# True if the presence of the given pattern in a log definitely indicates
+# that the test has failed. False if the presence is inconclusive.
+#
+# Inputs:
+# * $1: pattern found in the logs
+# * $TIMES_LEFT: >0 if retrying is an option
+#
+# Outputs:
+# * $outcome: set to a retry reason if the pattern is inconclusive,
+#             unchanged otherwise.
+# * Return value: 1 if the pattern is inconclusive,
+#                 0 if the failure is definitive.
+log_pattern_presence_is_conclusive() {
+    # If we've run out of attempts, then don't retry no matter what.
+    if [ $TIMES_LEFT -eq 0 ]; then
+        return 0
+    fi
+    case $1 in
+        "resend")
+            # An undesired resend may have been caused by the OS dropping or
+            # delaying a packet at an inopportune time.
+            outcome="RETRY(resend)"
+            return 1;;
+    esac
+}
+
 # fail <message>
 fail() {
     record_outcome "FAIL" "$1"
@@ -538,6 +585,8 @@
 # Wait for process $2 named $3 to be listening on port $1. Print error to $4.
 if type lsof >/dev/null 2>/dev/null; then
     wait_app_start() {
+        newline='
+'
         START_TIME=$(date +%s)
         if [ "$DTLS" -eq 1 ]; then
             proto=UDP
@@ -545,7 +594,15 @@
             proto=TCP
         fi
         # Make a tight loop, server normally takes less than 1s to start.
-        while ! lsof -a -n -b -i "$proto:$1" -p "$2" >/dev/null 2>/dev/null; do
+        while true; do
+              SERVER_PIDS=$(lsof -a -n -b -i "$proto:$1" -F p)
+              # When we use a proxy, it will be listening on the same port we
+              # are checking for as well as the server and lsof will list both.
+              # If multiple PIDs are returned, each one will be on a separate
+              # line, each prepended with 'p'.
+             case ${newline}${SERVER_PIDS}${newline} in
+                  *${newline}p${2}${newline}*) break;;
+              esac
               if [ $(( $(date +%s) - $START_TIME )) -gt $DOG_DELAY ]; then
                   echo "$3 START TIMEOUT"
                   echo "$3 START TIMEOUT" >> $4
@@ -665,7 +722,7 @@
 # check if the given command uses dtls and sets global variable DTLS
 detect_dtls() {
     case "$1" in
-        *dtls=1*|-dtls|-u) DTLS=1;;
+        *dtls=1*|*-dtls*|*-u*) DTLS=1;;
         *) DTLS=0;;
     esac
 }
@@ -702,6 +759,267 @@
         fi
 }
 
+# Analyze the commands that will be used in a test.
+#
+# Analyze and possibly instrument $PXY_CMD, $CLI_CMD, $SRV_CMD to pass
+# extra arguments or go through wrappers.
+# Set $DTLS (0=TLS, 1=DTLS).
+analyze_test_commands() {
+    # update DTLS variable
+    detect_dtls "$SRV_CMD"
+
+    # if the test uses DTLS but no custom proxy, add a simple proxy
+    # as it provides timing info that's useful to debug failures
+    if [ -z "$PXY_CMD" ] && [ "$DTLS" -eq 1 ]; then
+        PXY_CMD="$P_PXY"
+        case " $SRV_CMD " in
+            *' server_addr=::1 '*)
+                PXY_CMD="$PXY_CMD server_addr=::1 listen_addr=::1";;
+        esac
+    fi
+
+    # update CMD_IS_GNUTLS variable
+    is_gnutls "$SRV_CMD"
+
+    # if the server uses gnutls but doesn't set priority, explicitly
+    # set the default priority
+    if [ "$CMD_IS_GNUTLS" -eq 1 ]; then
+        case "$SRV_CMD" in
+              *--priority*) :;;
+              *) SRV_CMD="$SRV_CMD --priority=NORMAL";;
+        esac
+    fi
+
+    # update CMD_IS_GNUTLS variable
+    is_gnutls "$CLI_CMD"
+
+    # if the client uses gnutls but doesn't set priority, explicitly
+    # set the default priority
+    if [ "$CMD_IS_GNUTLS" -eq 1 ]; then
+        case "$CLI_CMD" in
+              *--priority*) :;;
+              *) CLI_CMD="$CLI_CMD --priority=NORMAL";;
+        esac
+    fi
+
+    # fix client port
+    if [ -n "$PXY_CMD" ]; then
+        CLI_CMD=$( echo "$CLI_CMD" | sed s/+SRV_PORT/$PXY_PORT/g )
+    else
+        CLI_CMD=$( echo "$CLI_CMD" | sed s/+SRV_PORT/$SRV_PORT/g )
+    fi
+
+    # prepend valgrind to our commands if active
+    if [ "$MEMCHECK" -gt 0 ]; then
+        if is_polar "$SRV_CMD"; then
+            SRV_CMD="valgrind --leak-check=full $SRV_CMD"
+        fi
+        if is_polar "$CLI_CMD"; then
+            CLI_CMD="valgrind --leak-check=full $CLI_CMD"
+        fi
+    fi
+}
+
+# Check for failure conditions after a test case.
+#
+# Inputs from run_test:
+# * positional parameters: test options (see run_test documentation)
+# * $CLI_EXIT: client return code
+# * $CLI_EXPECT: expected client return code
+# * $SRV_RET: server return code
+# * $CLI_OUT, $SRV_OUT, $PXY_OUT: files containing client/server/proxy logs
+# * $TIMES_LEFT: if nonzero, a RETRY outcome is allowed
+#
+# Outputs:
+# * $outcome: one of PASS/RETRY*/FAIL
+check_test_failure() {
+    outcome=FAIL
+
+    if [ $TIMES_LEFT -gt 0 ] &&
+       grep '===CLIENT_TIMEOUT===' $CLI_OUT >/dev/null
+    then
+        outcome="RETRY(client-timeout)"
+        return
+    fi
+
+    # check if the client and server went at least to the handshake stage
+    # (useful to avoid tests with only negative assertions and non-zero
+    # expected client exit to incorrectly succeed in case of catastrophic
+    # failure)
+    if is_polar "$SRV_CMD"; then
+        if grep "Performing the SSL/TLS handshake" $SRV_OUT >/dev/null; then :;
+        else
+            fail "server or client failed to reach handshake stage"
+            return
+        fi
+    fi
+    if is_polar "$CLI_CMD"; then
+        if grep "Performing the SSL/TLS handshake" $CLI_OUT >/dev/null; then :;
+        else
+            fail "server or client failed to reach handshake stage"
+            return
+        fi
+    fi
+
+    # Check server exit code (only for Mbed TLS: GnuTLS and OpenSSL don't
+    # exit with status 0 when interrupted by a signal, and we don't really
+    # care anyway), in case e.g. the server reports a memory leak.
+    if [ $SRV_RET != 0 ] && is_polar "$SRV_CMD"; then
+        fail "Server exited with status $SRV_RET"
+        return
+    fi
+
+    # check client exit code
+    if [ \( "$CLI_EXPECT" = 0 -a "$CLI_EXIT" != 0 \) -o \
+         \( "$CLI_EXPECT" != 0 -a "$CLI_EXIT" = 0 \) ]
+    then
+        fail "bad client exit code (expected $CLI_EXPECT, got $CLI_EXIT)"
+        return
+    fi
+
+    # check other assertions
+    # lines beginning with == are added by valgrind, ignore them
+    # lines with 'Serious error when reading debug info', are valgrind issues as well
+    while [ $# -gt 0 ]
+    do
+        case $1 in
+            "-s")
+                if grep -v '^==' $SRV_OUT | grep -v 'Serious error when reading debug info' | grep "$2" >/dev/null; then :; else
+                    fail "pattern '$2' MUST be present in the Server output"
+                    return
+                fi
+                ;;
+
+            "-c")
+                if grep -v '^==' $CLI_OUT | grep -v 'Serious error when reading debug info' | grep "$2" >/dev/null; then :; else
+                    fail "pattern '$2' MUST be present in the Client output"
+                    return
+                fi
+                ;;
+
+            "-S")
+                if grep -v '^==' $SRV_OUT | grep -v 'Serious error when reading debug info' | grep "$2" >/dev/null; then
+                    if log_pattern_presence_is_conclusive "$2"; then
+                        fail "pattern '$2' MUST NOT be present in the Server output"
+                    fi
+                    return
+                fi
+                ;;
+
+            "-C")
+                if grep -v '^==' $CLI_OUT | grep -v 'Serious error when reading debug info' | grep "$2" >/dev/null; then
+                    if log_pattern_presence_is_conclusive "$2"; then
+                        fail "pattern '$2' MUST NOT be present in the Client output"
+                    fi
+                    return
+                fi
+                ;;
+
+                # The filtering in the following two options (-u and -U) do the following
+                #   - ignore valgrind output
+                #   - filter out everything but lines right after the pattern occurrences
+                #   - keep one of each non-unique line
+                #   - count how many lines remain
+                # A line with '--' will remain in the result from previous outputs, so the number of lines in the result will be 1
+                # if there were no duplicates.
+            "-U")
+                if [ $(grep -v '^==' $SRV_OUT | grep -v 'Serious error when reading debug info' | grep -A1 "$2" | grep -v "$2" | sort | uniq -d | wc -l) -gt 1 ]; then
+                    fail "lines following pattern '$2' must be unique in Server output"
+                    return
+                fi
+                ;;
+
+            "-u")
+                if [ $(grep -v '^==' $CLI_OUT | grep -v 'Serious error when reading debug info' | grep -A1 "$2" | grep -v "$2" | sort | uniq -d | wc -l) -gt 1 ]; then
+                    fail "lines following pattern '$2' must be unique in Client output"
+                    return
+                fi
+                ;;
+            "-F")
+                if ! $2 "$SRV_OUT"; then
+                    fail "function call to '$2' failed on Server output"
+                    return
+                fi
+                ;;
+            "-f")
+                if ! $2 "$CLI_OUT"; then
+                    fail "function call to '$2' failed on Client output"
+                    return
+                fi
+                ;;
+            "-g")
+                if ! eval "$2 '$SRV_OUT' '$CLI_OUT'"; then
+                    fail "function call to '$2' failed on Server and Client output"
+                    return
+                fi
+                ;;
+
+            *)
+                echo "Unknown test: $1" >&2
+                exit 1
+        esac
+        shift 2
+    done
+
+    # check valgrind's results
+    if [ "$MEMCHECK" -gt 0 ]; then
+        if is_polar "$SRV_CMD" && has_mem_err $SRV_OUT; then
+            fail "Server has memory errors"
+            return
+        fi
+        if is_polar "$CLI_CMD" && has_mem_err $CLI_OUT; then
+            fail "Client has memory errors"
+            return
+        fi
+    fi
+
+    # if we're here, everything is ok
+    outcome=PASS
+}
+
+# Run the current test case: start the server and if applicable the proxy, run
+# the client, wait for all processes to finish or time out.
+#
+# Inputs:
+# * $NAME: test case name
+# * $CLI_CMD, $SRV_CMD, $PXY_CMD: commands to run
+# * $CLI_OUT, $SRV_OUT, $PXY_OUT: files to contain client/server/proxy logs
+#
+# Outputs:
+# * $CLI_EXIT: client return code
+# * $SRV_RET: server return code
+do_run_test_once() {
+    # run the commands
+    if [ -n "$PXY_CMD" ]; then
+        printf "# %s\n%s\n" "$NAME" "$PXY_CMD" > $PXY_OUT
+        $PXY_CMD >> $PXY_OUT 2>&1 &
+        PXY_PID=$!
+        wait_proxy_start "$PXY_PORT" "$PXY_PID"
+    fi
+
+    check_osrv_dtls
+    printf '# %s\n%s\n' "$NAME" "$SRV_CMD" > $SRV_OUT
+    provide_input | $SRV_CMD >> $SRV_OUT 2>&1 &
+    SRV_PID=$!
+    wait_server_start "$SRV_PORT" "$SRV_PID"
+
+    printf '# %s\n%s\n' "$NAME" "$CLI_CMD" > $CLI_OUT
+    eval "$CLI_CMD" >> $CLI_OUT 2>&1 &
+    wait_client_done
+
+    sleep 0.05
+
+    # terminate the server (and the proxy)
+    kill $SRV_PID
+    wait $SRV_PID
+    SRV_RET=$?
+
+    if [ -n "$PXY_CMD" ]; then
+        kill $PXY_PID >/dev/null 2>&1
+        wait $PXY_PID
+    fi
+}
+
 # Usage: run_test name [-p proxy_cmd] srv_cmd cli_cmd cli_exit [option [...]]
 # Options:  -s pattern  pattern that must be present in server output
 #           -c pattern  pattern that must be present in client output
@@ -764,230 +1082,23 @@
         return
     fi
 
-    # update DTLS variable
-    detect_dtls "$SRV_CMD"
-
-    # if the test uses DTLS but no custom proxy, add a simple proxy
-    # as it provides timing info that's useful to debug failures
-    if [ -z "$PXY_CMD" ] && [ "$DTLS" -eq 1 ]; then
-        PXY_CMD="$P_PXY"
-        case " $SRV_CMD " in
-            *' server_addr=::1 '*)
-                PXY_CMD="$PXY_CMD server_addr=::1 listen_addr=::1";;
-        esac
-    fi
-
-    # update CMD_IS_GNUTLS variable
-    is_gnutls "$SRV_CMD"
-
-    # if the server uses gnutls but doesn't set priority, explicitly
-    # set the default priority
-    if [ "$CMD_IS_GNUTLS" -eq 1 ]; then
-        case "$SRV_CMD" in
-              *--priority*) :;;
-              *) SRV_CMD="$SRV_CMD --priority=NORMAL";;
-        esac
-    fi
-
-    # update CMD_IS_GNUTLS variable
-    is_gnutls "$CLI_CMD"
-
-    # if the client uses gnutls but doesn't set priority, explicitly
-    # set the default priority
-    if [ "$CMD_IS_GNUTLS" -eq 1 ]; then
-        case "$CLI_CMD" in
-              *--priority*) :;;
-              *) CLI_CMD="$CLI_CMD --priority=NORMAL";;
-        esac
-    fi
-
-    # fix client port
-    if [ -n "$PXY_CMD" ]; then
-        CLI_CMD=$( echo "$CLI_CMD" | sed s/+SRV_PORT/$PXY_PORT/g )
-    else
-        CLI_CMD=$( echo "$CLI_CMD" | sed s/+SRV_PORT/$SRV_PORT/g )
-    fi
-
-    # prepend valgrind to our commands if active
-    if [ "$MEMCHECK" -gt 0 ]; then
-        if is_polar "$SRV_CMD"; then
-            SRV_CMD="valgrind --leak-check=full $SRV_CMD"
-        fi
-        if is_polar "$CLI_CMD"; then
-            CLI_CMD="valgrind --leak-check=full $CLI_CMD"
-        fi
-    fi
+    analyze_test_commands "$@"
 
     TIMES_LEFT=2
     while [ $TIMES_LEFT -gt 0 ]; do
         TIMES_LEFT=$(( $TIMES_LEFT - 1 ))
 
-        # run the commands
-        if [ -n "$PXY_CMD" ]; then
-            printf "# %s\n%s\n" "$NAME" "$PXY_CMD" > $PXY_OUT
-            $PXY_CMD >> $PXY_OUT 2>&1 &
-            PXY_PID=$!
-            wait_proxy_start "$PXY_PORT" "$PXY_PID"
-        fi
+        do_run_test_once
 
-        check_osrv_dtls
-        printf '# %s\n%s\n' "$NAME" "$SRV_CMD" > $SRV_OUT
-        provide_input | $SRV_CMD >> $SRV_OUT 2>&1 &
-        SRV_PID=$!
-        wait_server_start "$SRV_PORT" "$SRV_PID"
-
-        printf '# %s\n%s\n' "$NAME" "$CLI_CMD" > $CLI_OUT
-        eval "$CLI_CMD" >> $CLI_OUT 2>&1 &
-        wait_client_done
-
-        sleep 0.05
-
-        # terminate the server (and the proxy)
-        kill $SRV_PID
-        wait $SRV_PID
-        SRV_RET=$?
-
-        if [ -n "$PXY_CMD" ]; then
-            kill $PXY_PID >/dev/null 2>&1
-            wait $PXY_PID
-        fi
-
-        # retry only on timeouts
-        if grep '===CLIENT_TIMEOUT===' $CLI_OUT >/dev/null; then
-            printf "RETRY "
-        else
-            TIMES_LEFT=0
-        fi
-    done
-
-    # check if the client and server went at least to the handshake stage
-    # (useful to avoid tests with only negative assertions and non-zero
-    # expected client exit to incorrectly succeed in case of catastrophic
-    # failure)
-    if is_polar "$SRV_CMD"; then
-        if grep "Performing the SSL/TLS handshake" $SRV_OUT >/dev/null; then :;
-        else
-            fail "server or client failed to reach handshake stage"
-            return
-        fi
-    fi
-    if is_polar "$CLI_CMD"; then
-        if grep "Performing the SSL/TLS handshake" $CLI_OUT >/dev/null; then :;
-        else
-            fail "server or client failed to reach handshake stage"
-            return
-        fi
-    fi
-
-    # Check server exit code (only for Mbed TLS: GnuTLS and OpenSSL don't
-    # exit with status 0 when interrupted by a signal, and we don't really
-    # care anyway), in case e.g. the server reports a memory leak.
-    if [ $SRV_RET != 0 ] && is_polar "$SRV_CMD"; then
-        fail "Server exited with status $SRV_RET"
-        return
-    fi
-
-    # check client exit code
-    if [ \( "$CLI_EXPECT" = 0 -a "$CLI_EXIT" != 0 \) -o \
-         \( "$CLI_EXPECT" != 0 -a "$CLI_EXIT" = 0 \) ]
-    then
-        fail "bad client exit code (expected $CLI_EXPECT, got $CLI_EXIT)"
-        return
-    fi
-
-    # check other assertions
-    # lines beginning with == are added by valgrind, ignore them
-    # lines with 'Serious error when reading debug info', are valgrind issues as well
-    while [ $# -gt 0 ]
-    do
-        case $1 in
-            "-s")
-                if grep -v '^==' $SRV_OUT | grep -v 'Serious error when reading debug info' | grep "$2" >/dev/null; then :; else
-                    fail "pattern '$2' MUST be present in the Server output"
-                    return
-                fi
-                ;;
-
-            "-c")
-                if grep -v '^==' $CLI_OUT | grep -v 'Serious error when reading debug info' | grep "$2" >/dev/null; then :; else
-                    fail "pattern '$2' MUST be present in the Client output"
-                    return
-                fi
-                ;;
-
-            "-S")
-                if grep -v '^==' $SRV_OUT | grep -v 'Serious error when reading debug info' | grep "$2" >/dev/null; then
-                    fail "pattern '$2' MUST NOT be present in the Server output"
-                    return
-                fi
-                ;;
-
-            "-C")
-                if grep -v '^==' $CLI_OUT | grep -v 'Serious error when reading debug info' | grep "$2" >/dev/null; then
-                    fail "pattern '$2' MUST NOT be present in the Client output"
-                    return
-                fi
-                ;;
-
-                # The filtering in the following two options (-u and -U) do the following
-                #   - ignore valgrind output
-                #   - filter out everything but lines right after the pattern occurrences
-                #   - keep one of each non-unique line
-                #   - count how many lines remain
-                # A line with '--' will remain in the result from previous outputs, so the number of lines in the result will be 1
-                # if there were no duplicates.
-            "-U")
-                if [ $(grep -v '^==' $SRV_OUT | grep -v 'Serious error when reading debug info' | grep -A1 "$2" | grep -v "$2" | sort | uniq -d | wc -l) -gt 1 ]; then
-                    fail "lines following pattern '$2' must be unique in Server output"
-                    return
-                fi
-                ;;
-
-            "-u")
-                if [ $(grep -v '^==' $CLI_OUT | grep -v 'Serious error when reading debug info' | grep -A1 "$2" | grep -v "$2" | sort | uniq -d | wc -l) -gt 1 ]; then
-                    fail "lines following pattern '$2' must be unique in Client output"
-                    return
-                fi
-                ;;
-            "-F")
-                if ! $2 "$SRV_OUT"; then
-                    fail "function call to '$2' failed on Server output"
-                    return
-                fi
-                ;;
-            "-f")
-                if ! $2 "$CLI_OUT"; then
-                    fail "function call to '$2' failed on Client output"
-                    return
-                fi
-                ;;
-            "-g")
-                if ! eval "$2 '$SRV_OUT' '$CLI_OUT'"; then
-                    fail "function call to '$2' failed on Server and Client output"
-                    return
-                fi
-                ;;
-
-            *)
-                echo "Unknown test: $1" >&2
-                exit 1
+        check_test_failure "$@"
+        case $outcome in
+            PASS) break;;
+            RETRY*) printf "$outcome ";;
+            FAIL) return;;
         esac
-        shift 2
     done
 
-    # check valgrind's results
-    if [ "$MEMCHECK" -gt 0 ]; then
-        if is_polar "$SRV_CMD" && has_mem_err $SRV_OUT; then
-            fail "Server has memory errors"
-            return
-        fi
-        if is_polar "$CLI_CMD" && has_mem_err $CLI_OUT; then
-            fail "Client has memory errors"
-            return
-        fi
-    fi
-
-    # if we're here, everything is ok
+    # If we get this far, the test case passed.
     record_outcome "PASS"
     if [ "$PRESERVE_LOGS" -gt 0 ]; then
         mv $SRV_OUT o-srv-${TESTS}.log
@@ -1212,17 +1323,24 @@
 
 # fix commands to use this port, force IPv4 while at it
 # +SRV_PORT will be replaced by either $SRV_PORT or $PXY_PORT later
+# Note: Using 'localhost' rather than 127.0.0.1 here is unwise, as on many
+# machines that will resolve to ::1, and we don't want ipv6 here.
 P_SRV="$P_SRV server_addr=127.0.0.1 server_port=$SRV_PORT"
 P_CLI="$P_CLI server_addr=127.0.0.1 server_port=+SRV_PORT"
 P_PXY="$P_PXY server_addr=127.0.0.1 server_port=$SRV_PORT listen_addr=127.0.0.1 listen_port=$PXY_PORT ${SEED:+"seed=$SEED"}"
 O_SRV="$O_SRV -accept $SRV_PORT"
-O_CLI="$O_CLI -connect localhost:+SRV_PORT"
+O_CLI="$O_CLI -connect 127.0.0.1:+SRV_PORT"
 G_SRV="$G_SRV -p $SRV_PORT"
 G_CLI="$G_CLI -p +SRV_PORT"
 
 if [ -n "${OPENSSL_LEGACY:-}" ]; then
     O_LEGACY_SRV="$O_LEGACY_SRV -accept $SRV_PORT -dhparam data_files/dhparams.pem"
-    O_LEGACY_CLI="$O_LEGACY_CLI -connect localhost:+SRV_PORT"
+    O_LEGACY_CLI="$O_LEGACY_CLI -connect 127.0.0.1:+SRV_PORT"
+fi
+
+if [ -n "${OPENSSL_NEXT:-}" ]; then
+    O_NEXT_SRV="$O_NEXT_SRV -accept $SRV_PORT"
+    O_NEXT_CLI="$O_NEXT_CLI -connect 127.0.0.1:+SRV_PORT"
 fi
 
 if [ -n "${GNUTLS_NEXT_SERV:-}" ]; then
@@ -2938,10 +3056,13 @@
             -c "parse new session ticket" \
             -c "a session has been resumed"
 
+# For reasons that aren't fully understood, this test randomly fails with high
+# probability with OpenSSL 1.0.2g on the CI, see #5012.
+requires_openssl_next
 run_test    "Session resume using tickets, DTLS: openssl client" \
             "$P_SRV dtls=1 debug_level=3 tickets=1" \
-            "( $O_CLI -dtls1 -sess_out $SESSION; \
-               $O_CLI -dtls1 -sess_in $SESSION; \
+            "( $O_NEXT_CLI -dtls1 -sess_out $SESSION; \
+               $O_NEXT_CLI -dtls1 -sess_in $SESSION; \
                rm -f $SESSION )" \
             0 \
             -s "found session ticket extension" \
@@ -3138,10 +3259,13 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+# For reasons that aren't fully understood, this test randomly fails with high
+# probability with OpenSSL 1.0.2g on the CI, see #5012.
+requires_openssl_next
 run_test    "Session resume using cache, DTLS: openssl client" \
             "$P_SRV dtls=1 debug_level=3 tickets=0" \
-            "( $O_CLI -dtls1 -sess_out $SESSION; \
-               $O_CLI -dtls1 -sess_in $SESSION; \
+            "( $O_NEXT_CLI -dtls1 -sess_out $SESSION; \
+               $O_NEXT_CLI -dtls1 -sess_in $SESSION; \
                rm -f $SESSION )" \
             0 \
             -s "found session ticket extension" \
diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function
index a5fd717..17926eb 100644
--- a/tests/suites/host_test.function
+++ b/tests/suites/host_test.function
@@ -778,6 +778,12 @@
                     mbedtls_fprintf( stdout, "line %d, %s",
                                      mbedtls_test_info.line_no,
                                      mbedtls_test_info.filename );
+                    if( mbedtls_test_info.line1[0] != 0 )
+                        mbedtls_fprintf( stdout, "\n  %s",
+                                         mbedtls_test_info.line1 );
+                    if( mbedtls_test_info.line2[0] != 0 )
+                        mbedtls_fprintf( stdout, "\n  %s",
+                                         mbedtls_test_info.line2 );
                 }
                 fflush( stdout );
             }
diff --git a/tests/suites/target_test.function b/tests/suites/target_test.function
deleted file mode 100644
index 637a79d..0000000
--- a/tests/suites/target_test.function
+++ /dev/null
@@ -1,449 +0,0 @@
-#line 2 "suites/target_test.function"
-
-#include "greentea-client/test_env.h"
-
-/**
- * \brief       Increments pointer and asserts that it does not overflow.
- *
- * \param p     Pointer to byte array
- * \param start Pointer to start of byte array
- * \param len   Length of byte array
- * \param step  Increment size
- *
- */
-#define INCR_ASSERT(p, start, len, step) do                     \
-{                                                               \
-    TEST_HELPER_ASSERT( ( p ) >= ( start ) );                               \
-    TEST_HELPER_ASSERT( sizeof( *( p ) ) == sizeof( *( start ) ) );         \
-    /* <= is checked to support use inside a loop where         \
-       pointer is incremented after reading data.       */      \
-    TEST_HELPER_ASSERT( (uint32_t)( ( ( p ) - ( start ) ) + ( step ) ) <= ( len ) );\
-    ( p ) += ( step );                                          \
-}                                                               \
-while( 0 )
-
-
-/**
- * \brief       4 byte align unsigned char pointer
- *
- * \param p     Pointer to byte array
- * \param start Pointer to start of byte array
- * \param len   Length of byte array
- *
- */
-#define ALIGN_32BIT(p, start, len) do               \
-{                                                   \
-    uint32_t align = ( - (uintptr_t)( p ) ) % 4;    \
-    INCR_ASSERT( ( p ), ( start ), ( len ), align );\
-}                                                   \
-while( 0 )
-
-
-/**
- * \brief       Verify dependencies. Dependency identifiers are
- *              encoded in the buffer as 8 bit unsigned integers.
- *
- * \param count     Number of dependencies.
- * \param dep_p     Pointer to buffer.
- *
- * \return          DEPENDENCY_SUPPORTED if success else DEPENDENCY_NOT_SUPPORTED.
- */
-int verify_dependencies( uint8_t count, uint8_t * dep_p )
-{
-    uint8_t i;
-    for ( i = 0; i < count; i++ )
-    {
-        if ( dep_check( (int)(dep_p[i]) ) != DEPENDENCY_SUPPORTED )
-            return( DEPENDENCY_NOT_SUPPORTED );
-    }
-    return( DEPENDENCY_SUPPORTED );
-}
-
-/**
- * \brief       Receives hex string on serial interface, and converts to a byte.
- *
- * \param none
- *
- * \return      unsigned int8
- */
-uint8_t receive_byte()
-{
-    uint8_t byte;
-    uint8_t c[3];
-    size_t len;
-
-    c[0] = greentea_getc();
-    c[1] = greentea_getc();
-    c[2] = '\0';
-
-    TEST_HELPER_ASSERT( mbedtls_test_unhexify( &byte, sizeof( byte ),
-                                               c, &len ) == 0 );
-    TEST_HELPER_ASSERT( len != 2 );
-
-    return( byte );
-}
-
-/**
- * \brief       Receives unsigned integer on serial interface.
- *              Integers are encoded in network order, and sent as hex ascii string.
- *
- * \param none
- *
- * \return      unsigned int
- */
-uint32_t receive_uint32()
-{
-    uint32_t value;
-    size_t len;
-    const uint8_t c_be[8] = { greentea_getc(),
-                              greentea_getc(),
-                              greentea_getc(),
-                              greentea_getc(),
-                              greentea_getc(),
-                              greentea_getc(),
-                              greentea_getc(),
-                              greentea_getc()
-                             };
-    const uint8_t c[9] = { c_be[6], c_be[7], c_be[4], c_be[5], c_be[2],
-                           c_be[3], c_be[0], c_be[1], '\0' };
-
-    TEST_HELPER_ASSERT( mbedtls_test_unhexify( (uint8_t*)&value, sizeof( value ),
-                                               c, &len ) == 0 );
-    TEST_HELPER_ASSERT( len != 8 );
-
-    return( value );
-}
-
-/**
- * \brief       Parses out an unsigned 32 int value from the byte array.
- *              Integers are encoded in network order.
- *
- * \param p     Pointer to byte array
- *
- * \return      unsigned int
- */
-uint32_t parse_uint32( uint8_t * p )
-{
-    uint32_t value;
-    value =  *p++ << 24;
-    value |= *p++ << 16;
-    value |= *p++ << 8;
-    value |= *p;
-    return( value );
-}
-
-
-/**
- * \brief       Receives test data on serial as greentea key,value pair:
- *              {{<length>;<byte array>}}
- *
- * \param data_len  Out pointer to hold received data length.
- *
- * \return      Byte array.
- */
-uint8_t * receive_data( uint32_t * data_len )
-{
-    uint32_t i = 0, errors = 0;
-    char c;
-    uint8_t * data = NULL;
-
-    /* Read opening braces */
-    i = 0;
-    while ( i < 2 )
-    {
-        c = greentea_getc();
-        /* Ignore any prevous CR LF characters */
-        if ( c == '\n' || c == '\r' )
-            continue;
-        i++;
-        if ( c != '{' )
-            return( NULL );
-    }
-
-    /* Read data length */
-    *data_len = receive_uint32();
-    data = (uint8_t *)malloc( *data_len );
-    TEST_HELPER_ASSERT( data != NULL );
-
-    greentea_getc(); // read ';' received after key i.e. *data_len
-
-    for( i = 0; i < *data_len; i++ )
-        data[i] = receive_byte();
-
-    /* Read closing braces */
-    for( i = 0; i < 2; i++ )
-    {
-        c = greentea_getc();
-        if ( c != '}' )
-        {
-            errors++;
-            break;
-        }
-    }
-
-    if ( errors )
-    {
-        free( data );
-        data = NULL;
-        *data_len = 0;
-    }
-
-    return( data );
-}
-
-/**
- * \brief       Parse the received byte array and count the number of arguments
- *              to the test function passed as type hex.
- *
- * \param count     Parameter count
- * \param data      Received Byte array
- * \param data_len  Byte array length
- *
- * \return      count of hex params
- */
-uint32_t find_hex_count( uint8_t count, uint8_t * data, uint32_t data_len )
-{
-    uint32_t i = 0, sz = 0;
-    char c;
-    uint8_t * p = NULL;
-    uint32_t hex_count = 0;
-
-    p = data;
-
-    for( i = 0; i < count; i++ )
-    {
-        c = (char)*p;
-        INCR_ASSERT( p, data, data_len, 1 );
-
-        /* Align p to 4 bytes for int, expression, string len or hex length */
-        ALIGN_32BIT( p, data, data_len );
-
-        /* Network to host conversion */
-        sz = (int32_t)parse_uint32( p );
-
-        INCR_ASSERT( p, data, data_len, sizeof( int32_t ) );
-
-        if ( c == 'H' || c == 'S' )
-        {
-            INCR_ASSERT( p, data, data_len, sz );
-            hex_count += ( c == 'H' )?1:0;
-        }
-    }
-
-    return( hex_count );
-}
-
-/**
- * \brief       Parses received byte array for test parameters.
- *
- * \param count     Parameter count
- * \param data      Received Byte array
- * \param data_len  Byte array length
- * \param error     Parsing error out variable.
- *
- * \return      Array of parsed parameters allocated on heap.
- *              Note: Caller has the responsibility to delete
- *                    the memory after use.
- */
-void ** parse_parameters( uint8_t count, uint8_t * data, uint32_t data_len,
-                          int * error )
-{
-    uint32_t i = 0, hex_count = 0;
-    char c;
-    void ** params = NULL;
-    void ** cur = NULL;
-    uint8_t * p = NULL;
-
-    hex_count = find_hex_count(count, data, data_len);
-
-    params = (void **)malloc( sizeof( void *) * ( count + hex_count ) );
-    TEST_HELPER_ASSERT( params != NULL );
-    cur = params;
-
-    p = data;
-
-    /* Parameters */
-    for( i = 0; i < count; i++ )
-    {
-        c = (char)*p;
-        INCR_ASSERT( p, data, data_len, 1 );
-
-        /* Align p to 4 bytes for int, expression, string len or hex length */
-        ALIGN_32BIT( p, data, data_len );
-
-        /* Network to host conversion */
-        *( (int32_t *)p ) = (int32_t)parse_uint32( p );
-
-        switch( c )
-        {
-            case 'E':
-                {
-                    if ( get_expression( *( (int32_t *)p ), (int32_t *)p ) )
-                    {
-                        *error = KEY_VALUE_MAPPING_NOT_FOUND;
-                        goto exit;
-                    }
-                } /* Intentional fall through */
-            case 'I':
-                {
-                    *cur++ = (void *)p;
-                    INCR_ASSERT( p, data, data_len, sizeof( int32_t ) );
-                }
-                break;
-            case 'H': /* Intentional fall through */
-            case 'S':
-                {
-                    uint32_t * sz = (uint32_t *)p;
-                    INCR_ASSERT( p, data, data_len, sizeof( int32_t ) );
-                    *cur++ = (void *)p;
-                    if ( c == 'H' )
-                        *cur++ = (void *)sz;
-                    INCR_ASSERT( p, data, data_len, ( *sz ) );
-                }
-                break;
-            default:
-                    {
-                        *error = DISPATCH_INVALID_TEST_DATA;
-                        goto exit;
-                    }
-                break;
-        }
-    }
-
-exit:
-    if ( *error )
-    {
-        free( params );
-        params = NULL;
-    }
-
-    return( params );
-}
-
-/**
- * \brief       Sends greentea key and int value pair to host.
- *
- * \param key   key string
- * \param value integer value
- *
- * \return      void
- */
-void send_key_integer( char * key, int value )
-{
-    char str[50];
-    snprintf( str, sizeof( str ), "%d", value );
-    greentea_send_kv( key, str );
-}
-
-/**
- * \brief       Sends test setup failure to the host.
- *
- * \param failure   Test set failure
- *
- * \return      void
- */
-void send_failure( int failure )
-{
-    send_key_integer( "F", failure );
-}
-
-/**
- * \brief       Sends test status to the host.
- *
- * \param status    Test status (PASS=0/FAIL=!0)
- *
- * \return      void
- */
-void send_status( int status )
-{
-    send_key_integer( "R", status );
-}
-
-
-/**
- * \brief       Embedded implementation of execute_tests().
- *              Ignores command line and received test data
- *              on serial.
- *
- * \param argc  not used
- * \param argv  not used
- *
- * \return      Program exit status.
- */
-int execute_tests( int args, const char ** argv )
-{
-    int ret = 0;
-    uint32_t data_len = 0;
-    uint8_t count = 0, function_id;
-    void ** params = NULL;
-    uint8_t * data = NULL, * p = NULL;
-
-    GREENTEA_SETUP( 800, "mbedtls_test" );
-    greentea_send_kv( "GO", " " );
-
-    while ( 1 )
-    {
-        ret = 0;
-        mbedtls_test_info_reset( );
-        data_len = 0;
-
-        data = receive_data( &data_len );
-        if ( data == NULL )
-            continue;
-        p = data;
-
-        do
-        {
-            /* Read dependency count */
-            count = *p;
-            TEST_HELPER_ASSERT( count < data_len );
-            INCR_ASSERT( p, data, data_len, sizeof( uint8_t ) );
-            ret = verify_dependencies( count, p );
-            if ( ret != DEPENDENCY_SUPPORTED )
-                break;
-
-            if ( count )
-                INCR_ASSERT( p, data, data_len, count );
-
-            /* Read function id */
-            function_id = *p;
-            INCR_ASSERT( p, data, data_len, sizeof( uint8_t ) );
-            if ( ( ret = check_test( function_id ) ) != DISPATCH_TEST_SUCCESS )
-                break;
-
-            /* Read number of parameters */
-            count = *p;
-            INCR_ASSERT( p, data, data_len, sizeof( uint8_t ) );
-
-            /* Parse parameters if present */
-            if ( count )
-            {
-                params = parse_parameters( count, p, data_len - ( p - data ), &ret );
-                if ( ret )
-                    break;
-            }
-
-            ret = dispatch_test( function_id, params );
-        }
-        while ( 0 );
-
-        if ( data )
-        {
-            free( data );
-            data = NULL;
-        }
-
-        if ( params )
-        {
-            free( params );
-            params = NULL;
-        }
-
-        if ( ret )
-            send_failure( ret );
-        else
-            send_status( mbedtls_test_info.result );
-    }
-    return( 0 );
-}
-
diff --git a/tests/suites/test_suite_aes.function b/tests/suites/test_suite_aes.function
index a90277d..5a64099 100644
--- a/tests/suites/test_suite_aes.function
+++ b/tests/suites/test_suite_aes.function
@@ -67,7 +67,7 @@
 
     mbedtls_aes_init( &ctx );
 
-    mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
+    TEST_ASSERT( mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 ) == 0 );
     TEST_ASSERT( mbedtls_aes_crypt_cbc( &ctx, MBEDTLS_AES_ENCRYPT, src_str->len, iv_str->x, src_str->x, output ) == cbc_result );
     if( cbc_result == 0 )
     {
@@ -92,7 +92,7 @@
     memset(output, 0x00, 100);
     mbedtls_aes_init( &ctx );
 
-    mbedtls_aes_setkey_dec( &ctx, key_str->x, key_str->len * 8 );
+    TEST_ASSERT( mbedtls_aes_setkey_dec( &ctx, key_str->x, key_str->len * 8 ) == 0 );
     TEST_ASSERT( mbedtls_aes_crypt_cbc( &ctx, MBEDTLS_AES_DECRYPT, src_str->len, iv_str->x, src_str->x, output ) == cbc_result );
     if( cbc_result == 0)
     {
@@ -244,7 +244,7 @@
     mbedtls_aes_init( &ctx );
 
 
-    mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
+    TEST_ASSERT( mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 ) == 0 );
     TEST_ASSERT( mbedtls_aes_crypt_cfb128( &ctx, MBEDTLS_AES_ENCRYPT, 16, &iv_offset, iv_str->x, src_str->x, output ) == 0 );
 
     TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
@@ -266,7 +266,7 @@
     mbedtls_aes_init( &ctx );
 
 
-    mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
+    TEST_ASSERT( mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 ) == 0 );
     TEST_ASSERT( mbedtls_aes_crypt_cfb128( &ctx, MBEDTLS_AES_DECRYPT, 16, &iv_offset, iv_str->x, src_str->x, output ) == 0 );
 
     TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
@@ -287,7 +287,7 @@
     mbedtls_aes_init( &ctx );
 
 
-    mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
+    TEST_ASSERT( mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 ) == 0 );
     TEST_ASSERT( mbedtls_aes_crypt_cfb8( &ctx, MBEDTLS_AES_ENCRYPT, src_str->len, iv_str->x, src_str->x, output ) == 0 );
 
     TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
@@ -309,7 +309,7 @@
     mbedtls_aes_init( &ctx );
 
 
-    mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
+    TEST_ASSERT( mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 ) == 0 );
     TEST_ASSERT( mbedtls_aes_crypt_cfb8( &ctx, MBEDTLS_AES_DECRYPT, src_str->len, iv_str->x, src_str->x, output ) == 0 );
 
     TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
diff --git a/tests/suites/test_suite_base64.data b/tests/suites/test_suite_base64.data
index 3a892f4..5556668 100644
--- a/tests/suites/test_suite_base64.data
+++ b/tests/suites/test_suite_base64.data
@@ -1,3 +1,33 @@
+mask_of_range empty (1..0)
+mask_of_range:1:0
+
+mask_of_range empty (255..0)
+mask_of_range:255:0
+
+mask_of_range empty (42..7)
+mask_of_range:42:7
+
+mask_of_range 0..0
+mask_of_range:0:0
+
+mask_of_range 42..42
+mask_of_range:42:42
+
+mask_of_range 255..255
+mask_of_range:255:255
+
+mask_of_range 0..255
+mask_of_range:0:255
+
+mask_of_range 'A'..'Z'
+mask_of_range:65:90
+
+enc_char (all digits)
+enc_chars:
+
+dec_value (all characters)
+dec_chars:
+
 Test case mbedtls_base64_encode #1 buffer just right
 mbedtls_base64_encode:"":"":0:0
 
diff --git a/tests/suites/test_suite_base64.function b/tests/suites/test_suite_base64.function
index be9b6e8..67fbb67 100644
--- a/tests/suites/test_suite_base64.function
+++ b/tests/suites/test_suite_base64.function
@@ -1,6 +1,13 @@
 /* BEGIN_HEADER */
 #include "mbedtls/base64.h"
+#include "base64_invasive.h"
 #include <test/constant_flow.h>
+
+#if defined(MBEDTLS_TEST_HOOKS)
+static const char base64_digits[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+#endif /* MBEDTLS_TEST_HOOKS */
+
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
@@ -8,6 +15,65 @@
  * END_DEPENDENCIES
  */
 
+/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
+void mask_of_range( int low_arg, int high_arg )
+{
+    unsigned char low = low_arg, high = high_arg;
+    unsigned c;
+    for( c = 0; c <= 0xff; c++ )
+    {
+        mbedtls_test_set_step( c );
+        TEST_CF_SECRET( &c, sizeof( c ) );
+        unsigned char m = mbedtls_base64_mask_of_range( low, high, c );
+        TEST_CF_PUBLIC( &c, sizeof( c ) );
+        TEST_CF_PUBLIC( &m, sizeof( m ) );
+        if( low <= c && c <= high )
+            TEST_EQUAL( m, 0xff );
+        else
+            TEST_EQUAL( m, 0 );
+    }
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
+void enc_chars( )
+{
+    for( unsigned value = 0; value < 64; value++ )
+    {
+        mbedtls_test_set_step( value );
+        TEST_CF_SECRET( &value, sizeof( value ) );
+        unsigned char digit = mbedtls_base64_enc_char( value );
+        TEST_CF_PUBLIC( &value, sizeof( value ) );
+        TEST_CF_PUBLIC( &digit, sizeof( digit ) );
+        TEST_EQUAL( digit, base64_digits[value] );
+    }
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
+void dec_chars( )
+{
+    char *p;
+    signed char expected;
+
+    for( unsigned c = 0; c <= 0xff; c++ )
+    {
+        mbedtls_test_set_step( c );
+        /* base64_digits is 0-terminated. sizeof()-1 excludes the trailing 0. */
+        p = memchr( base64_digits, c, sizeof( base64_digits ) - 1 );
+        if( p == NULL )
+            expected = -1;
+        else
+            expected = p - base64_digits;
+        TEST_CF_SECRET( &c, sizeof( c ) );
+        signed char actual = mbedtls_base64_dec_value( c );
+        TEST_CF_PUBLIC( &c, sizeof( c ) );
+        TEST_CF_PUBLIC( &actual, sizeof( actual ) );
+        TEST_EQUAL( actual, expected );
+    }
+}
+/* END_CASE */
+
 /* BEGIN_CASE */
 void mbedtls_base64_encode( char * src_string, char * dst_string,
                             int dst_buf_size, int result )
diff --git a/tests/suites/test_suite_cipher.aes.data b/tests/suites/test_suite_cipher.aes.data
index 4dbdd52..c8fbca2 100644
--- a/tests/suites/test_suite_cipher.aes.data
+++ b/tests/suites/test_suite_cipher.aes.data
@@ -1798,6 +1798,102 @@
 depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
 test_vec_crypt:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"5c9d844ed46f9885085e5d6a4f94c7d7":"014730f80ac625fe84f026c60bfd547d":0:1
 
+AES-128-ECB crypt Encrypt NIST KAT #1 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_ENCRYPT:"00000000000000000000000000000000":"":"80000000000000000000000000000000":"3ad78e726c1ec02b7ebfe92b23d9ec34":0:1
+
+AES-128-ECB crypt Encrypt NIST KAT #2 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_ENCRYPT:"ffffffffffffffffffffffffffffe000":"":"00000000000000000000000000000000":"323994cfb9da285a5d9642e1759b224a":0:1
+
+AES-128-ECB crypt Encrypt NIST KAT #3 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_ENCRYPT:"10a58869d74be5a374cf867cfb473859":"":"00000000000000000000000000000000":"6d251e6944b051e04eaa6fb4dbf78465":0:1
+
+AES-128-ECB crypt Encrypt NIST KAT #4 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_ENCRYPT:"00000000000000000000000000000000":"":"f34481ec3cc627bacd5dc3fb08f273e6":"0336763e966d92595a567cc9ce537f5e":0:1
+
+AES-128-ECB crypt Decrypt NIST KAT #1 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"00000000000000000000000000000000":"":"3ad78e726c1ec02b7ebfe92b23d9ec34":"80000000000000000000000000000000":0:1
+
+AES-128-ECB crypt Decrypt NIST KAT #2 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"ffffc000000000000000000000000000":"":"df556a33438db87bc41b1752c55e5e49":"00000000000000000000000000000000":0:1
+
+AES-128-ECB crypt Decrypt NIST KAT #3 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"10a58869d74be5a374cf867cfb473859":"":"6d251e6944b051e04eaa6fb4dbf78465":"00000000000000000000000000000000":0:1
+
+AES-128-ECB crypt Decrypt NIST KAT #4 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"00000000000000000000000000000000":"":"0336763e966d92595a567cc9ce537f5e":"f34481ec3cc627bacd5dc3fb08f273e6":0:1
+
+AES-192-ECB crypt Encrypt NIST KAT #1 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_ENCRYPT:"000000000000000000000000000000000000000000000000":"":"80000000000000000000000000000000":"6cd02513e8d4dc986b4afe087a60bd0c":0:1
+
+AES-192-ECB crypt Encrypt NIST KAT #2 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_ENCRYPT:"ff0000000000000000000000000000000000000000000000":"":"00000000000000000000000000000000":"833f71258d53036b02952c76c744f5a1":0:1
+
+AES-192-ECB crypt Encrypt NIST KAT #3 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_ENCRYPT:"e9f065d7c13573587f7875357dfbb16c53489f6a4bd0f7cd":"":"00000000000000000000000000000000":"0956259c9cd5cfd0181cca53380cde06":0:1
+
+AES-192-ECB crypt Encrypt NIST KAT #4 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_ENCRYPT:"000000000000000000000000000000000000000000000000":"":"1b077a6af4b7f98229de786d7516b639":"275cfc0413d8ccb70513c3859b1d0f72":0:1
+
+AES-192-ECB crypt Decrypt NIST KAT #1 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"000000000000000000000000000000000000000000000000":"":"6cd02513e8d4dc986b4afe087a60bd0c":"80000000000000000000000000000000":0:1
+
+AES-192-ECB crypt Decrypt NIST KAT #2 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"ffe000000000000000000000000000000000000000000000":"":"7ababc4b3f516c9aafb35f4140b548f9":"00000000000000000000000000000000":0:1
+
+AES-192-ECB crypt Decrypt NIST KAT #3 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"e9f065d7c13573587f7875357dfbb16c53489f6a4bd0f7cd":"":"0956259c9cd5cfd0181cca53380cde06":"00000000000000000000000000000000":0:1
+
+AES-192-ECB crypt Decrypt NIST KAT #4 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"000000000000000000000000000000000000000000000000":"":"275cfc0413d8ccb70513c3859b1d0f72":"1b077a6af4b7f98229de786d7516b639":0:1
+
+AES-256-ECB crypt Encrypt NIST KAT #1 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_ENCRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"":"80000000000000000000000000000000":"ddc6bf790c15760d8d9aeb6f9a75fd4e":0:1
+
+AES-256-ECB crypt Encrypt NIST KAT #2 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_ENCRYPT:"ff00000000000000000000000000000000000000000000000000000000000000":"":"00000000000000000000000000000000":"ec52a212f80a09df6317021bc2a9819e":0:1
+
+AES-256-ECB crypt Encrypt NIST KAT #3 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_ENCRYPT:"c47b0294dbbbee0fec4757f22ffeee3587ca4730c3d33b691df38bab076bc558":"":"00000000000000000000000000000000":"46f2fb342d6f0ab477476fc501242c5f":0:1
+
+AES-256-ECB crypt Encrypt NIST KAT #4 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_ENCRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"":"014730f80ac625fe84f026c60bfd547d":"5c9d844ed46f9885085e5d6a4f94c7d7":0:1
+
+AES-256-ECB crypt Decrypt NIST KAT #1 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"":"ddc6bf790c15760d8d9aeb6f9a75fd4e":"80000000000000000000000000000000":0:1
+
+AES-256-ECB crypt Decrypt NIST KAT #2 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"ffe0000000000000000000000000000000000000000000000000000000000000":"":"d1ccb9b1337002cbac42c520b5d67722":"00000000000000000000000000000000":0:1
+
+AES-256-ECB crypt Decrypt NIST KAT #3 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"c47b0294dbbbee0fec4757f22ffeee3587ca4730c3d33b691df38bab076bc558":"":"46f2fb342d6f0ab477476fc501242c5f":"00000000000000000000000000000000":0:1
+
+AES-256-ECB crypt Decrypt NIST KAT #4 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"":"5c9d844ed46f9885085e5d6a4f94c7d7":"014730f80ac625fe84f026c60bfd547d":0:1
+
 Cipher Corner Case behaviours
 depends_on:MBEDTLS_AES_C
 cipher_special_behaviours:
diff --git a/tests/suites/test_suite_des.function b/tests/suites/test_suite_des.function
index 5b24935..7256fb5 100644
--- a/tests/suites/test_suite_des.function
+++ b/tests/suites/test_suite_des.function
@@ -24,7 +24,7 @@
     mbedtls_des_init( &ctx );
 
 
-    mbedtls_des_setkey_enc( &ctx, key_str->x );
+    TEST_ASSERT( mbedtls_des_setkey_enc( &ctx, key_str->x ) == 0 );
     TEST_ASSERT( mbedtls_des_crypt_ecb( &ctx, src_str->x, output ) == 0 );
 
     TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
@@ -44,7 +44,7 @@
     mbedtls_des_init( &ctx );
 
 
-    mbedtls_des_setkey_dec( &ctx, key_str->x );
+    TEST_ASSERT( mbedtls_des_setkey_dec( &ctx, key_str->x ) == 0 );
     TEST_ASSERT( mbedtls_des_crypt_ecb( &ctx, src_str->x, output ) == 0 );
 
     TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
@@ -65,7 +65,7 @@
     mbedtls_des_init( &ctx );
 
 
-    mbedtls_des_setkey_enc( &ctx, key_str->x );
+    TEST_ASSERT( mbedtls_des_setkey_enc( &ctx, key_str->x ) == 0 );
     TEST_ASSERT( mbedtls_des_crypt_cbc( &ctx, MBEDTLS_DES_ENCRYPT, src_str->len, iv_str->x, src_str->x, output ) == cbc_result );
     if( cbc_result == 0 )
     {
@@ -91,7 +91,7 @@
     mbedtls_des_init( &ctx );
 
 
-    mbedtls_des_setkey_dec( &ctx, key_str->x );
+    TEST_ASSERT( mbedtls_des_setkey_dec( &ctx, key_str->x ) == 0 );
     TEST_ASSERT( mbedtls_des_crypt_cbc( &ctx, MBEDTLS_DES_DECRYPT, src_str->len, iv_str->x, src_str->x, output ) == cbc_result );
     if( cbc_result == 0 )
     {
@@ -117,9 +117,9 @@
 
 
     if( key_count == 2 )
-        mbedtls_des3_set2key_enc( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set2key_enc( &ctx, key_str->x ) == 0 );
     else if( key_count == 3 )
-        mbedtls_des3_set3key_enc( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set3key_enc( &ctx, key_str->x ) == 0 );
     else
         TEST_ASSERT( 0 );
 
@@ -144,9 +144,9 @@
 
 
     if( key_count == 2 )
-        mbedtls_des3_set2key_dec( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set2key_dec( &ctx, key_str->x ) == 0 );
     else if( key_count == 3 )
-        mbedtls_des3_set3key_dec( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set3key_dec( &ctx, key_str->x ) == 0 );
     else
         TEST_ASSERT( 0 );
 
@@ -172,9 +172,9 @@
 
 
     if( key_count == 2 )
-        mbedtls_des3_set2key_enc( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set2key_enc( &ctx, key_str->x ) == 0 );
     else if( key_count == 3 )
-        mbedtls_des3_set3key_enc( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set3key_enc( &ctx, key_str->x ) == 0 );
     else
         TEST_ASSERT( 0 );
 
@@ -205,9 +205,9 @@
 
 
     if( key_count == 2 )
-        mbedtls_des3_set2key_dec( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set2key_dec( &ctx, key_str->x ) == 0 );
     else if( key_count == 3 )
-        mbedtls_des3_set3key_dec( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set3key_dec( &ctx, key_str->x ) == 0 );
     else
         TEST_ASSERT( 0 );
 
diff --git a/tests/suites/test_suite_net.function b/tests/suites/test_suite_net.function
index f429fc9..513b723 100644
--- a/tests/suites/test_suite_net.function
+++ b/tests/suites/test_suite_net.function
@@ -9,11 +9,11 @@
 #endif
 
 #if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE)
-#include <sys/fcntl.h>
 #include <sys/resource.h>
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/types.h>
+#include <fcntl.h>
 #include <unistd.h>
 #endif
 
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index fb70707..87b271f 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -398,111 +398,111 @@
 
 PSA key policy: MAC, SIGN_HASH -> SIGN_HASH+MESSAGE
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS:PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: MAC, VERIFY_HASH -> VERIFY_HASH+MESSAGE
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_NOT_PERMITTED:PSA_SUCCESS
 
 PSA key policy: MAC, SIGN+VERIFY_HASH -> {SIGN,VERIFY}_{HASH,MESSAGE}
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS:PSA_SUCCESS
 
 PSA key policy: MAC, {SIGN,VERIFY}_{HASH,MESSAGE}
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS:PSA_SUCCESS
 
 PSA key policy: MAC, SIGN_MESSAGE
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS:PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: MAC, VERIFY_MESSAGE
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_NOT_PERMITTED:PSA_SUCCESS
 
 PSA key policy: MAC, SIGN+VERIFY_MESSAGE
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS:PSA_SUCCESS
 
 PSA key policy: MAC, neither sign nor verify
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:0:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_NOT_PERMITTED
+mac_key_policy:0:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_NOT_PERMITTED:PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: MAC, wrong algorithm
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_224):PSA_ERROR_NOT_PERMITTED
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_224):PSA_ERROR_NOT_PERMITTED:PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: MAC, alg=0 in policy
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_NOT_PERMITTED
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_NOT_PERMITTED:PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: MAC, ANY_HASH in policy is not meaningful
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_HMAC(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_NOT_PERMITTED
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_HMAC(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_NOT_PERMITTED:PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: HMAC, sign-verify, tag length > min-length policy
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 30):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 30):PSA_SUCCESS:PSA_SUCCESS
 
 PSA key policy: HMAC, sign-verify, tag length = min-length policy
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_SUCCESS:PSA_SUCCESS
 
 PSA key policy: HMAC, sign-verify, tag length < min-length policy
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 10):PSA_ERROR_NOT_PERMITTED
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 10):PSA_ERROR_NOT_PERMITTED:PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: CMAC, sign-verify, tag length > min-length policy
 depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_CMAC, 10):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 16):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_CMAC, 10):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 16):PSA_SUCCESS:PSA_SUCCESS
 
 PSA key policy: CMAC, sign-verify, tag length = min-length policy
 depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_CMAC, 10):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 10):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_CMAC, 10):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 10):PSA_SUCCESS:PSA_SUCCESS
 
 PSA key policy: CMAC, sign-verify, tag length < min-length policy
 depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_CMAC, 10):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 8):PSA_ERROR_NOT_PERMITTED
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_CMAC, 10):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 8):PSA_ERROR_NOT_PERMITTED:PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: HMAC, sign-verify, default tag length > min-length policy
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 31):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 31):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS:PSA_SUCCESS
 
 PSA key policy: HMAC, sign-verify, default tag length = min-length policy
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 32):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 32):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS:PSA_SUCCESS
 
 PSA key policy: HMAC, sign-verify, default tag length < min-length policy
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 33):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_NOT_PERMITTED
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 33):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_NOT_PERMITTED:PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: HMAC, sign-verify, min-length policy, unmatched base alg
 depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 20):PSA_ERROR_NOT_PERMITTED
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 20):PSA_ERROR_NOT_PERMITTED:PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: HMAC, sign-verify, min-length policy, unmatched base alg (different hash base)
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_224), 20):PSA_ERROR_NOT_PERMITTED
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_224), 20):PSA_ERROR_NOT_PERMITTED:PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: HMAC, sign-verify, min-length policy, unmatched base alg (different algorithm)
 depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 10):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_CMAC:PSA_ERROR_NOT_PERMITTED
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 10):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_CMAC:PSA_ERROR_NOT_PERMITTED:PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: HMAC, sign-verify, min-length policy used as algorithm
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_ERROR_INVALID_ARGUMENT
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_ERROR_INVALID_ARGUMENT:PSA_ERROR_INVALID_ARGUMENT
 
 PSA key policy: HMAC, sign-verify, tag length > exact-length policy
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 10):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_ERROR_NOT_PERMITTED
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 10):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_ERROR_NOT_PERMITTED:PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: HMAC, sign-verify, tag length = exact-length policy
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_SUCCESS:PSA_SUCCESS
 
 PSA key policy: HMAC, sign-verify, tag length < exact-length policy
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 10):PSA_ERROR_NOT_PERMITTED
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 10):PSA_ERROR_NOT_PERMITTED:PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: cipher, encrypt | decrypt
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
@@ -664,11 +664,19 @@
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_MD_C
 asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):32:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
-PSA key policy: asymmetric signature, wrong algorithm family
+PSA key policy: asymmetric signature, wrong alg family (PSS std/any salt)
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
+
+PSA key policy: asymmetric signature, wrong alg family (PSS any/std salt)
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
+
+PSA key policy: asymmetric signature, wrong alg family (RSA v15/PSS)
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
 asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
-PSA key policy: asymmetric signature, wildcard in policy, wrong algorithm family
+PSA key policy: asymmetric signature, wildcard in policy, wrong alg family
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
 asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
@@ -704,39 +712,47 @@
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_MD_C
 asymmetric_signature_key_policy:0:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):32:0
 
-PSA key policy: asymmetric signature for message, sign | verify
+PSA key policy: msg asymmetric signature, sign | verify
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
 asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):1:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
-PSA key policy: asymmetric signature for message, wrong algorithm family
+PSA key policy: msg asymmetric signature, wrong alg family (PSS std/any salt)
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
+
+PSA key policy: msg asymmetric signature, wrong alg family (PSS any/std salt)
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
+
+PSA key policy: msg asymmetric signature, wrong alg family (RSA v15/PSS)
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
 asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
-PSA key policy: asymmetric signature for message, wildcard in policy, wrong algorithm family
+PSA key policy: msg asymmetric signature, wildcard in policy, wrong alg family
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
 asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
-PSA key policy: asymmetric signature for message, wildcard in policy, ECDSA SHA-256
+PSA key policy: msg asymmetric signature, wildcard in policy, ECDSA SHA-256
 depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
 asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_ECDSA(PSA_ALG_SHA_256):32:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
-PSA key policy: asymmetric signature for message, wildcard in policy, PKCS#1v1.5 SHA-256
+PSA key policy: msg asymmetric signature, wildcard in policy, PKCS#1v1.5 SHA-256
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
 asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):32:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
-PSA key policy: asymmetric signature for message, wrong hash algorithm
+PSA key policy: msg asymmetric signature, wrong hash algorithm
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_SHA_384:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
 asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_384):0:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
-PSA key policy: asymmetric signature for message, alg=0 in policy
+PSA key policy: msg asymmetric signature, alg=0 in policy
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
 asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
-PSA key policy: asymmetric signature for message, sign but not verify
+PSA key policy: msg asymmetric signature, sign but not verify
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
 asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):1:PSA_KEY_USAGE_SIGN_MESSAGE
 
-PSA key policy: asymmetric signature for message, verify but not sign
+PSA key policy: msg asymmetric signature, verify but not sign
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
 asymmetric_signature_key_policy:PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):1:PSA_KEY_USAGE_VERIFY_MESSAGE
 
@@ -1523,6 +1539,7 @@
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
 cipher_encrypt_fail:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee223":PSA_ERROR_INVALID_ARGUMENT
 
+PSA symmetric encrypt: AES-ECB, 0 bytes, good
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
 cipher_encrypt_alg_without_iv:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":""
 
@@ -2110,6 +2127,22 @@
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
 aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 18 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
 
+PSA AEAD decrypt: AES-CCM, invalid nonce length 6
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c090693056":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD decrypt: AES-CCM, invalid nonce length 14
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd97200":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD decrypt: AES-CCM_8, invalid nonce length 6
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 8 ):"48c090693056":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD decrypt: AES-CCM_8, invalid nonce length 14
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 8 ):"48c0906930561e0ab0ef4cd97200":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
+
 PSA AEAD encrypt/decrypt, AES-GCM, 19 bytes #1
 depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
 aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":PSA_ALG_GCM:"000102030405060708090A0B0C0D0E0F":"000102030405060708090A0B":"0C0D0E0F101112131415161718191A1B1C1D1E":PSA_SUCCESS
@@ -2262,6 +2295,14 @@
 depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
 aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 2 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
 
+PSA AEAD decrypt: AES-GCM, nonce=0 (bad)
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD decrypt: AES-GCM, nonce=0 (bad), TAG=12
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
+aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 12 ):"":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"":PSA_ERROR_INVALID_ARGUMENT
+
 PSA AEAD decrypt: AES-GCM, invalid tag length 18
 depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
 aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 18 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
@@ -2366,6 +2407,18 @@
 depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
 aead_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"070000004041424344454647":"":"a0784d7a4716f3feb4f64e7f4b39bf04":"":PSA_SUCCESS
 
+PSA AEAD decrypt: ChaCha20-Poly1305 (nonce=8, not supported)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"0700000040414243":"":"a0784d7a4716f3feb4f64e7f4b39bf04":"":PSA_ERROR_NOT_SUPPORTED
+
+PSA AEAD decrypt: ChaCha20-Poly1305 (nonce=11, too short)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"0700000040414243444546":"":"a0784d7a4716f3feb4f64e7f4b39bf04":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD decrypt: ChaCha20-Poly1305 (nonce=13, too long)
+depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
+aead_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"07000000404142434445464700":"":"a0784d7a4716f3feb4f64e7f4b39bf04":"":PSA_ERROR_INVALID_ARGUMENT
+
 PSA AEAD encrypt/decrypt: invalid algorithm (CTR)
 depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
 aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CTR:"000102030405060708090A0B0C0D0E0F":"":"":PSA_ERROR_NOT_SUPPORTED
@@ -2390,6 +2443,10 @@
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
 signature_size:PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_ALG_RSA_PSS( PSA_ALG_SHA_256 ):128
 
+PSA signature size: RSA keypair, 1024 bits, PSS-any-salt
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
+signature_size:PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_ALG_RSA_PSS_ANY_SALT( PSA_ALG_SHA_256 ):128
+
 PSA signature size: RSA keypair, 1023 bits, PKCS#1 v1.5 raw
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
 signature_size:PSA_KEY_TYPE_RSA_KEY_PAIR:1023:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:128
@@ -2406,6 +2463,10 @@
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
 import_and_exercise_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256)
 
+PSA import/exercise RSA keypair, PSS-any-salt-SHA-256
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+import_and_exercise_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256)
+
 PSA import/exercise RSA public key, PKCS#1 v1.5 raw
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
 import_and_exercise_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:PSA_ALG_RSA_PKCS1V15_SIGN_RAW
@@ -2414,6 +2475,10 @@
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
 import_and_exercise_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256)
 
+PSA import/exercise RSA public key, PSS-any-salt-SHA-256
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+import_and_exercise_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256)
+
 PSA import/exercise: ECP SECP256R1 keypair, ECDSA
 depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
 import_and_exercise_key:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_ECDSA_ANY
@@ -2474,10 +2539,18 @@
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
 sign_hash_fail:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"":127:PSA_ERROR_INVALID_ARGUMENT
 
+PSA sign hash: RSA PSS-any-salt SHA-256, wrong hash length (0 bytes)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+sign_hash_fail:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):"":127:PSA_ERROR_INVALID_ARGUMENT
+
 PSA sign hash: RSA PSS SHA-256, wrong hash length (129 bytes)
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
 sign_hash_fail:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":127:PSA_ERROR_INVALID_ARGUMENT
 
+PSA sign hash: RSA PSS-any-salt SHA-256, wrong hash length (129 bytes)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+sign_hash_fail:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":127:PSA_ERROR_INVALID_ARGUMENT
+
 PSA sign hash: deterministic ECDSA SECP256R1 SHA-256, output buffer too small
 depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
 sign_hash_fail:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":63:PSA_ERROR_BUFFER_TOO_SMALL
@@ -2522,6 +2595,10 @@
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
 sign_verify_hash:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
 
+PSA sign/verify hash: RSA PSS-any-salt SHA-256, 32 bytes (hash size)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+sign_verify_hash:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
+
 PSA sign/verify hash: randomized ECDSA SECP256R1 SHA-256
 depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
 sign_verify_hash:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_ECDSA( PSA_ALG_SHA_256 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b"
@@ -2578,18 +2655,86 @@
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
 verify_hash_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"21a73664d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc7311":PSA_ERROR_INVALID_SIGNATURE
 
-PSA verify hash: RSA PSS SHA-256, good signature, 32 bytes (hash size)
+PSA verify hash: RSA-1024 PSS SHA-256, slen=0 (bad)
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
-verify_hash:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"1967ae568cc071dfebeeca76b11d40bd1ec5af241c50b3dcceff21f4536c0693a7179a8d5d163a7625fefd37c161127800edeebc24fa73ca772096827bd3f75e8ccf2c64f07b7171b5c99022a4d73b760f34a385ccff0bd5ed7997d2a29d2847acb0767f93a2a404bc046c97de66d95dc9f7646fdb216b627b2ea0de8afcefb7"
+verify_hash_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"abc4b612c6b71e13fa5965b2e25ee6adec5b1f211b2db158e9f3c4547d6cbef909a73dfb474b8caaf6c8fcafa10ec0bbadfd1883289ce33ad08ad533c61ea004fef4d9b76a1efc267efd066ae8918cb8e994faad30ff5e340e14c941926ba7ca9422b86e8055df1c1b90a5959a59cc7a5fc15cbd0d848cd40f7857b7629b668b":PSA_ERROR_INVALID_SIGNATURE
+
+PSA verify hash: RSA-1024 PSS-any-salt SHA-256, slen=0
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_hash:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"abc4b612c6b71e13fa5965b2e25ee6adec5b1f211b2db158e9f3c4547d6cbef909a73dfb474b8caaf6c8fcafa10ec0bbadfd1883289ce33ad08ad533c61ea004fef4d9b76a1efc267efd066ae8918cb8e994faad30ff5e340e14c941926ba7ca9422b86e8055df1c1b90a5959a59cc7a5fc15cbd0d848cd40f7857b7629b668b"
+
+PSA verify hash: RSA-1024 PSS SHA-256, slen=31 (bad)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_hash_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"797914eadbbe8293a7b0fe29d2db9fb246b519128d46d3ec93142a1a08a2992ba5325ad9b5ce55344b37996dbb81eb89628263cae4e3fc0e947dec0b8b0c7b0ee94bca02dd287f9cc619e2d88fb2279fb2a8f8301271c58009bb1223f3cfa730cb852947685678cfdef2968c82a9b8bffd8c0d518476b1ea2a5ad6c100045d8e":PSA_ERROR_INVALID_SIGNATURE
+
+PSA verify hash: RSA-1024 PSS-any-salt SHA-256, slen=31
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_hash:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"797914eadbbe8293a7b0fe29d2db9fb246b519128d46d3ec93142a1a08a2992ba5325ad9b5ce55344b37996dbb81eb89628263cae4e3fc0e947dec0b8b0c7b0ee94bca02dd287f9cc619e2d88fb2279fb2a8f8301271c58009bb1223f3cfa730cb852947685678cfdef2968c82a9b8bffd8c0d518476b1ea2a5ad6c100045d8e"
+
+PSA verify hash: RSA-1024 PSS SHA-256, slen=32
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_hash:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"6b201c50637962338d1b218c1d26f031205a0e3c47bc4c54856aa037e5a332d2981e80a51648e902e46046e5507a255c4c73f5ff40d5a54c0a11d2eca7804e1767b20ea12c945a23f5473181d379689c1ba634a2c47c0a8ec90c922ca6466ae9e9fb92871c9043b5858ae34828bceb4ead82db8f21a18ebe1d95b469bbdef1df"
+
+PSA verify hash: RSA-1024 PSS-any-salt SHA-256, slen=32
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_hash:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"6b201c50637962338d1b218c1d26f031205a0e3c47bc4c54856aa037e5a332d2981e80a51648e902e46046e5507a255c4c73f5ff40d5a54c0a11d2eca7804e1767b20ea12c945a23f5473181d379689c1ba634a2c47c0a8ec90c922ca6466ae9e9fb92871c9043b5858ae34828bceb4ead82db8f21a18ebe1d95b469bbdef1df"
+
+PSA verify hash: RSA-1024 PSS SHA-256, slen=94 (bad)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_hash_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"44a09fa66f1b2e790474960e90517e418747cfcd18423dff957516a598569d74f26ef1eae4a200d12d801e16fc6fde375330c79c0d8430825e0a7f69c664faefccfa25e7fbfc68af02af0f67fe4c49f68f6abc68c8f66d3fd77fc838961f4415827340c66e39c79ed7dae0738c08ce8272aebe50c72e31994b9b6db640b51800":PSA_ERROR_INVALID_SIGNATURE
+
+PSA verify hash: RSA-1024 PSS-any-salt SHA-256, slen=94
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_hash:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"44a09fa66f1b2e790474960e90517e418747cfcd18423dff957516a598569d74f26ef1eae4a200d12d801e16fc6fde375330c79c0d8430825e0a7f69c664faefccfa25e7fbfc68af02af0f67fe4c49f68f6abc68c8f66d3fd77fc838961f4415827340c66e39c79ed7dae0738c08ce8272aebe50c72e31994b9b6db640b51800"
+
+PSA verify hash: RSA-1024 PSS SHA-512, slen=61 (bad)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_512:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_hash_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_512):"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f":"23f5b30c8d612d8f31206c177ac2023c4f44754d03c7ff67daff99f24fa369b3e5f7c15b228a4417a1ff1c93fb8d645d619c2f4f559ac6c7f7bac20ba9df32353d19941265a4e74261adaf45d48682c0bc86cea6128f11ad172ff461fb1d97bded615861843996e2a98e7b8313b695519d001ae35305d6cbf3c0ee6c7ab06d1a":PSA_ERROR_INVALID_SIGNATURE
+
+PSA verify hash: RSA-1024 PSS-any-salt SHA-512, slen=61
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_512:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_hash:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_512):"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f":"23f5b30c8d612d8f31206c177ac2023c4f44754d03c7ff67daff99f24fa369b3e5f7c15b228a4417a1ff1c93fb8d645d619c2f4f559ac6c7f7bac20ba9df32353d19941265a4e74261adaf45d48682c0bc86cea6128f11ad172ff461fb1d97bded615861843996e2a98e7b8313b695519d001ae35305d6cbf3c0ee6c7ab06d1a"
+
+PSA verify hash: RSA-1024 PSS SHA-512, slen=62
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_512:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_hash:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_512):"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f":"6b215d77cf88b2d08be53b4f3ac6e72ebfbf7e0dc6c1e77b238cfb661c247a011b8746709fbefe4bc05d37343391683e9489d720ecbb7df37f4e36967918958996939461703465c2014a4c12faf875f8def70070e55b765b165c7e9c6f2eb05c98351b1e82219c31a2fb3ddce05f8988f552ff92f0b3471f63c0e53824c550a4"
+
+PSA verify hash: RSA-1024 PSS-any-salt SHA-512, slen=62
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_512:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_hash:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_512):"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f":"6b215d77cf88b2d08be53b4f3ac6e72ebfbf7e0dc6c1e77b238cfb661c247a011b8746709fbefe4bc05d37343391683e9489d720ecbb7df37f4e36967918958996939461703465c2014a4c12faf875f8def70070e55b765b165c7e9c6f2eb05c98351b1e82219c31a2fb3ddce05f8988f552ff92f0b3471f63c0e53824c550a4"
+
+PSA verify hash: RSA-528 PSS SHA-512, slen=0
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_512:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_hash:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"304a024300e31c246d46485984261fd174cab3d4357344602ecd793c47dbe54252d37bb350bc634359b19515542080e4724a4b672291be57c7648f51629eaef234e847d99cc65f0203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_512):"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f":"a14ad0fef77d36c28658a66129ee632e40e1032003eefe7fcda8e52b06675a051c80b2ca1cb99ed0762e90c9a48c434cd1063638eed7895a9c770e5435af750a1955"
+
+PSA verify hash: RSA-528 PSS-any-salt SHA-512, slen=0
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_512:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_hash:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"304a024300e31c246d46485984261fd174cab3d4357344602ecd793c47dbe54252d37bb350bc634359b19515542080e4724a4b672291be57c7648f51629eaef234e847d99cc65f0203010001":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_512):"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f":"a14ad0fef77d36c28658a66129ee632e40e1032003eefe7fcda8e52b06675a051c80b2ca1cb99ed0762e90c9a48c434cd1063638eed7895a9c770e5435af750a1955"
+
+PSA verify hash: RSA-520 PSS SHA-512 (hash too large)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_512:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_hash_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"3049024200d5a06f86e5b9d87428540165ca966fa8893a62e2a59d0bfd7617780bb039f9165a373a8e119d0766f8de556710f33f67019153bad8223775e797d451d48206f3bf0203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_512):"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f":"deaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddead42":PSA_ERROR_INVALID_ARGUMENT
+
+PSA verify hash: RSA-520 PSS-any-salt SHA-512 (hash too large)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_512:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_hash_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"3049024200d5a06f86e5b9d87428540165ca966fa8893a62e2a59d0bfd7617780bb039f9165a373a8e119d0766f8de556710f33f67019153bad8223775e797d451d48206f3bf0203010001":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_512):"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f":"deaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddead42":PSA_ERROR_INVALID_ARGUMENT
 
 PSA verify hash: RSA PSS SHA-256, wrong hash length (0 bytes)
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
 verify_hash_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"":"34c011b625c32d992f4ab8fcfa52b616ea66270b5b75a4fc71af712f9b8806bcdd374ce50eafcbb489562b93347885f93c2de1d404c45cacccefceb112ff6ffdfe4264f91d66320bbbe09304b851b8ad6280bbccc571eebcd49c7db5dfa399a6289e1978407904598751613d9870770cdd8507e3dc7b46851dbf05ae1df2988d":PSA_ERROR_INVALID_ARGUMENT
 
+PSA verify hash: RSA PSS-any-salt SHA-256, wrong hash length (0 bytes)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_hash_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):"":"34c011b625c32d992f4ab8fcfa52b616ea66270b5b75a4fc71af712f9b8806bcdd374ce50eafcbb489562b93347885f93c2de1d404c45cacccefceb112ff6ffdfe4264f91d66320bbbe09304b851b8ad6280bbccc571eebcd49c7db5dfa399a6289e1978407904598751613d9870770cdd8507e3dc7b46851dbf05ae1df2988d":PSA_ERROR_INVALID_ARGUMENT
+
 PSA verify hash: RSA PSS SHA-256, wrong hash length (129 bytes)
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
 verify_hash_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"1491cead330b4ad5b092f8351518141ac11d0888591572669c1e79d6e932c488acd62d44479b0e14cd91a048778bc02398a772ad6bdb4f7764780cf0afe70293d0cac86f2695a1dcb54568bb37d7086f9e86f95a6802d2ee5a4facaa762beff5261bb2816b62cb5af86404974c3f6b67985ac1fbfdf46d6de54f6e29d9274308":PSA_ERROR_INVALID_ARGUMENT
 
+PSA verify hash: RSA PSS-any-salt SHA-256, wrong hash length (129 bytes)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_hash_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"1491cead330b4ad5b092f8351518141ac11d0888591572669c1e79d6e932c488acd62d44479b0e14cd91a048778bc02398a772ad6bdb4f7764780cf0afe70293d0cac86f2695a1dcb54568bb37d7086f9e86f95a6802d2ee5a4facaa762beff5261bb2816b62cb5af86404974c3f6b67985ac1fbfdf46d6de54f6e29d9274308":PSA_ERROR_INVALID_ARGUMENT
+
 PSA verify hash: ECDSA SECP256R1, good
 depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
 verify_hash:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f"
@@ -2706,6 +2851,10 @@
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
 sign_verify_message:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"616263"
 
+PSA sign/verify message: RSA PSS-any-salt SHA-256
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+sign_verify_message:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):"616263"
+
 PSA sign/verify message: RSA PSS SHA-256, 0 bytes
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
 sign_verify_message:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):""
@@ -2770,22 +2919,46 @@
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
 verify_message:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"616263":"a73664d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc7311"
 
-PSA verify message: RSA PSS SHA-256, good signature, 0 bytes
+PSA verify message: RSA-1024 PSS SHA-256, slen=0 (bad)
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
-verify_message:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"":"50c06249deb97228e277b51d3e3542a6e5c140d6f6d1cb8a3dff53b5ce6e6fcb39d0767703174135208adf5d75399dd7525702b275153e7605ec38b65d33337bb9bbeb8c392ee22e3e9c0dafa43074a8205e17df2106bedd7bf6f1ada702aeb2ce04864c0ca9ec31964f9a957d8ebb9abc82454ad37c541e9b4d9842436c14a4"
+verify_message_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"616263":"abc4b612c6b71e13fa5965b2e25ee6adec5b1f211b2db158e9f3c4547d6cbef909a73dfb474b8caaf6c8fcafa10ec0bbadfd1883289ce33ad08ad533c61ea004fef4d9b76a1efc267efd066ae8918cb8e994faad30ff5e340e14c941926ba7ca9422b86e8055df1c1b90a5959a59cc7a5fc15cbd0d848cd40f7857b7629b668b":PSA_ERROR_INVALID_SIGNATURE
+
+PSA verify message: RSA-1024 PSS-any-salt SHA-256, slen=0
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_message:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):"616263":"abc4b612c6b71e13fa5965b2e25ee6adec5b1f211b2db158e9f3c4547d6cbef909a73dfb474b8caaf6c8fcafa10ec0bbadfd1883289ce33ad08ad533c61ea004fef4d9b76a1efc267efd066ae8918cb8e994faad30ff5e340e14c941926ba7ca9422b86e8055df1c1b90a5959a59cc7a5fc15cbd0d848cd40f7857b7629b668b"
+
+PSA verify message: RSA-1024 PSS SHA-256, slen=32
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_message:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"616263":"6b201c50637962338d1b218c1d26f031205a0e3c47bc4c54856aa037e5a332d2981e80a51648e902e46046e5507a255c4c73f5ff40d5a54c0a11d2eca7804e1767b20ea12c945a23f5473181d379689c1ba634a2c47c0a8ec90c922ca6466ae9e9fb92871c9043b5858ae34828bceb4ead82db8f21a18ebe1d95b469bbdef1df"
+
+PSA verify message: RSA-1024 PSS-any-salt SHA-256, slen=32
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_message:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):"616263":"6b201c50637962338d1b218c1d26f031205a0e3c47bc4c54856aa037e5a332d2981e80a51648e902e46046e5507a255c4c73f5ff40d5a54c0a11d2eca7804e1767b20ea12c945a23f5473181d379689c1ba634a2c47c0a8ec90c922ca6466ae9e9fb92871c9043b5858ae34828bceb4ead82db8f21a18ebe1d95b469bbdef1df"
 
 PSA verify message: RSA PSS SHA-256, good signature, 32 bytes (hash size)
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
 verify_message:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"6b65e1fdc900dce8a2b82130ae8ccfac27b6d0eb5f2c0c1085b80f34ceaaf064c8ff237e74a24a3c6fb7a842f172e5146315616281bbbeeae90febaab139a212decf1c68923f2a48e242b1fd72105e3a3f2329c30d78abe8673335ad08c5ba1aa515360bb5660050f1994bb08d3dd17e3407a379403bafa4e229b3c851283f6d"
 
+PSA verify message: RSA PSS-any-salt SHA-256, good signature, 32 bytes (hash size)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_message:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"6b65e1fdc900dce8a2b82130ae8ccfac27b6d0eb5f2c0c1085b80f34ceaaf064c8ff237e74a24a3c6fb7a842f172e5146315616281bbbeeae90febaab139a212decf1c68923f2a48e242b1fd72105e3a3f2329c30d78abe8673335ad08c5ba1aa515360bb5660050f1994bb08d3dd17e3407a379403bafa4e229b3c851283f6d"
+
 PSA verify message: RSA PSS SHA-256, good signature, 128 bytes (signature size)
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
 verify_message:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"29b65db0936b7fe408bda672077b0bc5e176177ba9a550fb548c292f7b4af1bb6475e0a979ba43dd644780801fabe5b62a1359cf7692918f30013e90c2362235765abc2078905d13b345dd689bf15e4e94ca51535d12f0675d5f13e9f254ba7696f0096d62deb023d106e9a96a5da3162bead6a745c8b9000868d2f9a447d5c5"
 
+PSA verify message: RSA-any-salt PSS SHA-256, good signature, 128 bytes (signature size)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_message:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"29b65db0936b7fe408bda672077b0bc5e176177ba9a550fb548c292f7b4af1bb6475e0a979ba43dd644780801fabe5b62a1359cf7692918f30013e90c2362235765abc2078905d13b345dd689bf15e4e94ca51535d12f0675d5f13e9f254ba7696f0096d62deb023d106e9a96a5da3162bead6a745c8b9000868d2f9a447d5c5"
+
 PSA verify message: RSA PSS SHA-256, good signature, 129 bytes
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
 verify_message:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"43286cc0fc599603fbb0cd1fd70c3a17b08d2adf4f90202dddfa4b9d74be8c720bbb1c714665466de6452d401ca061b68225785ff387c2615f03c81351cc3838cd3014a031a4f4c9f70bba06f504c6a9942ac2dbfed2329e590d526a9be26b4025a6d7c4151b4e795cfe756c9a8a5e8fa9228a6f5f6f427a5a070e5c0ea69830"
 
+PSA verify message: RSA PSS-any-salt SHA-256, good signature, 129 bytes
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_message:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"43286cc0fc599603fbb0cd1fd70c3a17b08d2adf4f90202dddfa4b9d74be8c720bbb1c714665466de6452d401ca061b68225785ff387c2615f03c81351cc3838cd3014a031a4f4c9f70bba06f504c6a9942ac2dbfed2329e590d526a9be26b4025a6d7c4151b4e795cfe756c9a8a5e8fa9228a6f5f6f427a5a070e5c0ea69830"
+
 PSA verify message: ECDSA SECP256R1 SHA-256, good
 depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ALG_SHA_256:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
 verify_message:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA(PSA_ALG_SHA_256):"616263":"0f8c19f5affea6d593a33e176aa52717bff8d5875165fc63e80a2d65580d295789db5ffb5397ba4c67834e2731ee268ea6f7e83846fbb02145b35442db18cf0b"
@@ -3073,7 +3246,7 @@
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
 # Whether we get NOT_PERMITTED or BAD_STATE for the output is an implementation
 # detail.
-derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_RAW_DATA:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ERROR_INVALID_ARGUMENT:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_TYPE_RAW_DATA:PSA_ERROR_NOT_PERMITTED
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_RAW_DATA:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ERROR_INVALID_ARGUMENT:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_TYPE_RAW_DATA:PSA_ERROR_BAD_STATE
 
 PSA key derivation: HKDF-SHA-256, direct secret, direct output
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
@@ -3406,19 +3579,19 @@
 
 PSA key derivation: HKDF SHA-256, request maximum capacity
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
-derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:"000102030405060708090a0b0c":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"f0f1f2f3f4f5f6f7f8f9":255 * 32:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865":""
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:"000102030405060708090a0b0c":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"f0f1f2f3f4f5f6f7f8f9":255 * PSA_HASH_LENGTH(PSA_ALG_SHA_256):"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865":""
 
 PSA key derivation: HKDF SHA-1, request maximum capacity
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_1
-derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_1):PSA_KEY_DERIVATION_INPUT_SALT:"":PSA_KEY_DERIVATION_INPUT_SECRET:"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":PSA_KEY_DERIVATION_INPUT_INFO:"":255 * 20:"2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48":""
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_1):PSA_KEY_DERIVATION_INPUT_SALT:"":PSA_KEY_DERIVATION_INPUT_SECRET:"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":PSA_KEY_DERIVATION_INPUT_INFO:"":255 * PSA_HASH_LENGTH(PSA_ALG_SHA_1):"2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48":""
 
 PSA key derivation: HKDF SHA-256, request too much capacity
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
-derive_set_capacity:PSA_ALG_HKDF(PSA_ALG_SHA_256):255 * 32 + 1:PSA_ERROR_INVALID_ARGUMENT
+derive_set_capacity:PSA_ALG_HKDF(PSA_ALG_SHA_256):255 * PSA_HASH_LENGTH(PSA_ALG_SHA_256) + 1:PSA_ERROR_INVALID_ARGUMENT
 
 PSA key derivation: HKDF SHA-1, request too much capacity
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_1
-derive_set_capacity:PSA_ALG_HKDF(PSA_ALG_SHA_1):255 * 20 + 1:PSA_ERROR_INVALID_ARGUMENT
+derive_set_capacity:PSA_ALG_HKDF(PSA_ALG_SHA_1):255 * PSA_HASH_LENGTH(PSA_ALG_SHA_1) + 1:PSA_ERROR_INVALID_ARGUMENT
 
 PSA key derivation: over capacity 42: output 42+1
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
@@ -3438,19 +3611,19 @@
 
 PSA key derivation: HKDF SHA-256, read maximum capacity minus 1
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
-derive_full:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * 32 - 1
+derive_full:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * PSA_HASH_LENGTH(PSA_ALG_SHA_256) - 1
 
 PSA key derivation: HKDF SHA-256, read maximum capacity
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
-derive_full:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * 32
+derive_full:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * PSA_HASH_LENGTH(PSA_ALG_SHA_256)
 
 PSA key derivation: TLS 1.2 PRF SHA-256, read maximum capacity minus 1
 depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF
-derive_full:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * 32 - 1
+derive_full:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * PSA_HASH_LENGTH(PSA_ALG_SHA_256) - 1
 
 PSA key derivation: TLS 1.2 PRF SHA-256, read maximum capacity
 depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF
-derive_full:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * 32
+derive_full:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * PSA_HASH_LENGTH(PSA_ALG_SHA_256)
 
 PSA key derivation: HKDF SHA-256, exercise AES128-CTR
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_AES
@@ -3681,7 +3854,7 @@
 
 PSA generate key: bad type (RSA public key)
 depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY
-generate_key:PSA_KEY_TYPE_RSA_PUBLIC_KEY:512:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_NOT_SUPPORTED:0
+generate_key:PSA_KEY_TYPE_RSA_PUBLIC_KEY:512:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT:0
 
 PSA generate key: raw data, 0 bits: invalid argument
 # The spec allows either INVALID_ARGUMENT or NOT_SUPPORTED
@@ -3744,6 +3917,10 @@
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_GENPRIME:MBEDTLS_MD_C
 generate_key:PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_SUCCESS:0
 
+PSA generate key: RSA, 1024 bits, good, sign (PSS-any-salt SHA-256)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_GENPRIME:MBEDTLS_MD_C
+generate_key:PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):PSA_SUCCESS:0
+
 PSA generate key: RSA, 512 bits, good, encrypt (PKCS#1 v1.5)
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_GENPRIME
 generate_key:PSA_KEY_TYPE_RSA_KEY_PAIR:512:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_SUCCESS:0
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index c2c94c1..9ed1424 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -853,7 +853,8 @@
                      int key_type_arg,
                      data_t *key_data,
                      int exercise_alg_arg,
-                     int expected_status_arg )
+                     int expected_status_sign_arg,
+                     int expected_status_verify_arg )
 {
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
@@ -863,7 +864,8 @@
     psa_algorithm_t exercise_alg = exercise_alg_arg;
     psa_key_usage_t policy_usage = policy_usage_arg;
     psa_status_t status;
-    psa_status_t expected_status = expected_status_arg;
+    psa_status_t expected_status_sign = expected_status_sign_arg;
+    psa_status_t expected_status_verify = expected_status_verify_arg;
     unsigned char mac[PSA_MAC_MAX_SIZE];
 
     PSA_ASSERT( psa_crypto_init( ) );
@@ -879,19 +881,30 @@
                 mbedtls_test_update_key_usage_flags( policy_usage ) );
 
     status = psa_mac_sign_setup( &operation, key, exercise_alg );
-    if( ( policy_usage & PSA_KEY_USAGE_SIGN_HASH ) == 0 )
-        TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
+    TEST_EQUAL( status, expected_status_sign );
+
+    /* Calculate the MAC, one-shot case. */
+    uint8_t input[128] = {0};
+    size_t mac_len;
+    TEST_EQUAL( psa_mac_compute( key, exercise_alg,
+                                 input, 128,
+                                 mac, PSA_MAC_MAX_SIZE, &mac_len ),
+                expected_status_sign );
+
+    /* Verify correct MAC, one-shot case. */
+    status = psa_mac_verify( key, exercise_alg, input, 128,
+                                mac, mac_len );
+
+    if( expected_status_sign != PSA_SUCCESS && expected_status_verify == PSA_SUCCESS )
+        TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
     else
-        TEST_EQUAL( status, expected_status );
+        TEST_EQUAL( status, expected_status_verify );
 
     psa_mac_abort( &operation );
 
     memset( mac, 0, sizeof( mac ) );
     status = psa_mac_verify_setup( &operation, key, exercise_alg );
-    if( ( policy_usage & PSA_KEY_USAGE_VERIFY_HASH ) == 0 )
-        TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
-    else
-        TEST_EQUAL( status, expected_status );
+    TEST_EQUAL( status, expected_status_verify );
 
 exit:
     psa_mac_abort( &operation );
@@ -1146,7 +1159,7 @@
     else
         TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
 
-    if( PSA_ALG_IS_HASH_AND_SIGN( exercise_alg ) &&
+    if( PSA_ALG_IS_SIGN_HASH( exercise_alg ) &&
         PSA_ALG_IS_HASH( PSA_ALG_SIGN_GET_HASH( exercise_alg ) ) )
     {
         status = psa_sign_message( key, exercise_alg,
@@ -4451,7 +4464,7 @@
     if( output_key_type != PSA_KEY_TYPE_NONE )
     {
         psa_reset_key_attributes( &attributes );
-        psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA );
+        psa_set_key_type( &attributes, output_key_type );
         psa_set_key_bits( &attributes, 8 );
         actual_output_status =
             psa_key_derivation_output_key( &attributes, &operation,
diff --git a/tests/suites/test_suite_psa_crypto_generate_key.function b/tests/suites/test_suite_psa_crypto_generate_key.function
new file mode 100644
index 0000000..dbe9a0e
--- /dev/null
+++ b/tests/suites/test_suite_psa_crypto_generate_key.function
@@ -0,0 +1,49 @@
+/* BEGIN_HEADER */
+
+#include "psa/crypto.h"
+#include "test/psa_crypto_helpers.h"
+
+#define INVALID_KEY_ID mbedtls_svc_key_id_make( 0, 0xfedcba98 )
+
+/* END_HEADER */
+
+/* BEGIN_DEPENDENCIES
+ * depends_on:MBEDTLS_PSA_CRYPTO_C
+ * END_DEPENDENCIES
+ */
+
+/* BEGIN_CASE */
+void generate_key( int key_type_arg, int bits_arg, int expected_status_arg)
+{
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    mbedtls_svc_key_id_t key_id = INVALID_KEY_ID;
+
+    // key lifetiem, usage flags, algorithm are irrelevant for this test
+    psa_key_type_t key_type = key_type_arg;
+    size_t bits = bits_arg;
+    psa_status_t expected_status = expected_status_arg;
+
+    PSA_ASSERT( psa_crypto_init( ) );
+    psa_set_key_type( &attributes, key_type );
+    psa_set_key_bits( &attributes, bits );
+    TEST_EQUAL( psa_generate_key( &attributes, &key_id ),
+                expected_status );
+
+    // Verify attributes of the created key on success
+    if ( expected_status == PSA_SUCCESS )
+    {
+        psa_reset_key_attributes(&attributes);
+        PSA_ASSERT( psa_get_key_attributes( key_id, &attributes ) );
+        TEST_EQUAL( psa_get_key_lifetime( &attributes ), PSA_KEY_LIFETIME_VOLATILE );
+        TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
+        TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
+        TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
+        TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
+    }
+
+exit:
+    psa_reset_key_attributes(&attributes);
+    psa_destroy_key( key_id );
+    PSA_DONE( );
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_psa_crypto_generate_key.generated.data b/tests/suites/test_suite_psa_crypto_generate_key.generated.data
new file mode 100644
index 0000000..7199c68
--- /dev/null
+++ b/tests/suites/test_suite_psa_crypto_generate_key.generated.data
@@ -0,0 +1,342 @@
+# Automatically generated by generate_psa_tests.py. Do not edit!
+
+PSA AES 128-bit
+depends_on:PSA_WANT_KEY_TYPE_AES
+generate_key:PSA_KEY_TYPE_AES:128:PSA_SUCCESS:
+
+PSA AES 192-bit
+depends_on:PSA_WANT_KEY_TYPE_AES
+generate_key:PSA_KEY_TYPE_AES:192:PSA_SUCCESS:
+
+PSA AES 256-bit
+depends_on:PSA_WANT_KEY_TYPE_AES
+generate_key:PSA_KEY_TYPE_AES:256:PSA_SUCCESS:
+
+PSA ARC4 8-bit
+depends_on:PSA_WANT_KEY_TYPE_ARC4
+generate_key:PSA_KEY_TYPE_ARC4:8:PSA_SUCCESS:
+
+PSA ARC4 128-bit
+depends_on:PSA_WANT_KEY_TYPE_ARC4
+generate_key:PSA_KEY_TYPE_ARC4:128:PSA_SUCCESS:
+
+PSA ARC4 2048-bit
+depends_on:PSA_WANT_KEY_TYPE_ARC4
+generate_key:PSA_KEY_TYPE_ARC4:2048:PSA_SUCCESS:
+
+PSA ARIA 128-bit
+depends_on:PSA_WANT_KEY_TYPE_ARIA
+generate_key:PSA_KEY_TYPE_ARIA:128:PSA_SUCCESS:
+
+PSA ARIA 192-bit
+depends_on:PSA_WANT_KEY_TYPE_ARIA
+generate_key:PSA_KEY_TYPE_ARIA:192:PSA_SUCCESS:
+
+PSA ARIA 256-bit
+depends_on:PSA_WANT_KEY_TYPE_ARIA
+generate_key:PSA_KEY_TYPE_ARIA:256:PSA_SUCCESS:
+
+PSA CAMELLIA 128-bit
+depends_on:PSA_WANT_KEY_TYPE_CAMELLIA
+generate_key:PSA_KEY_TYPE_CAMELLIA:128:PSA_SUCCESS:
+
+PSA CAMELLIA 192-bit
+depends_on:PSA_WANT_KEY_TYPE_CAMELLIA
+generate_key:PSA_KEY_TYPE_CAMELLIA:192:PSA_SUCCESS:
+
+PSA CAMELLIA 256-bit
+depends_on:PSA_WANT_KEY_TYPE_CAMELLIA
+generate_key:PSA_KEY_TYPE_CAMELLIA:256:PSA_SUCCESS:
+
+PSA CHACHA20 256-bit
+depends_on:PSA_WANT_KEY_TYPE_CHACHA20
+generate_key:PSA_KEY_TYPE_CHACHA20:256:PSA_SUCCESS:
+
+PSA DERIVE 120-bit
+depends_on:PSA_WANT_KEY_TYPE_DERIVE
+generate_key:PSA_KEY_TYPE_DERIVE:120:PSA_SUCCESS:
+
+PSA DERIVE 128-bit
+depends_on:PSA_WANT_KEY_TYPE_DERIVE
+generate_key:PSA_KEY_TYPE_DERIVE:128:PSA_SUCCESS:
+
+PSA DES 64-bit
+depends_on:PSA_WANT_KEY_TYPE_DES
+generate_key:PSA_KEY_TYPE_DES:64:PSA_SUCCESS:
+
+PSA DES 128-bit
+depends_on:PSA_WANT_KEY_TYPE_DES
+generate_key:PSA_KEY_TYPE_DES:128:PSA_SUCCESS:
+
+PSA DES 192-bit
+depends_on:PSA_WANT_KEY_TYPE_DES
+generate_key:PSA_KEY_TYPE_DES:192:PSA_SUCCESS:
+
+PSA HMAC 128-bit
+depends_on:PSA_WANT_KEY_TYPE_HMAC
+generate_key:PSA_KEY_TYPE_HMAC:128:PSA_SUCCESS:
+
+PSA HMAC 160-bit
+depends_on:PSA_WANT_KEY_TYPE_HMAC
+generate_key:PSA_KEY_TYPE_HMAC:160:PSA_SUCCESS:
+
+PSA HMAC 224-bit
+depends_on:PSA_WANT_KEY_TYPE_HMAC
+generate_key:PSA_KEY_TYPE_HMAC:224:PSA_SUCCESS:
+
+PSA HMAC 256-bit
+depends_on:PSA_WANT_KEY_TYPE_HMAC
+generate_key:PSA_KEY_TYPE_HMAC:256:PSA_SUCCESS:
+
+PSA HMAC 384-bit
+depends_on:PSA_WANT_KEY_TYPE_HMAC
+generate_key:PSA_KEY_TYPE_HMAC:384:PSA_SUCCESS:
+
+PSA HMAC 512-bit
+depends_on:PSA_WANT_KEY_TYPE_HMAC
+generate_key:PSA_KEY_TYPE_HMAC:512:PSA_SUCCESS:
+
+PSA RAW_DATA 8-bit
+depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
+generate_key:PSA_KEY_TYPE_RAW_DATA:8:PSA_SUCCESS:
+
+PSA RAW_DATA 40-bit
+depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
+generate_key:PSA_KEY_TYPE_RAW_DATA:40:PSA_SUCCESS:
+
+PSA RAW_DATA 128-bit
+depends_on:PSA_WANT_KEY_TYPE_RAW_DATA
+generate_key:PSA_KEY_TYPE_RAW_DATA:128:PSA_SUCCESS:
+
+PSA RSA_KEY_PAIR 1024-bit
+depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_GENPRIME
+generate_key:PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_SUCCESS:
+
+PSA RSA_KEY_PAIR 1536-bit
+depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_GENPRIME
+generate_key:PSA_KEY_TYPE_RSA_KEY_PAIR:1536:PSA_SUCCESS:
+
+PSA RSA_PUBLIC_KEY 1024-bit
+generate_key:PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA RSA_PUBLIC_KEY 1536-bit
+generate_key:PSA_KEY_TYPE_RSA_PUBLIC_KEY:1536:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_KEY_PAIR(BRAINPOOL_P_R1) 160-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_BRAINPOOL_P_R1_160:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):160:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(BRAINPOOL_P_R1) 192-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_BRAINPOOL_P_R1_192:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):192:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(BRAINPOOL_P_R1) 224-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_BRAINPOOL_P_R1_224:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):224:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(BRAINPOOL_P_R1) 256-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_BRAINPOOL_P_R1_256
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):256:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(BRAINPOOL_P_R1) 320-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_BRAINPOOL_P_R1_320:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):320:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(BRAINPOOL_P_R1) 384-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_BRAINPOOL_P_R1_384
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):384:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(BRAINPOOL_P_R1) 512-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_BRAINPOOL_P_R1_512
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):512:PSA_SUCCESS:
+
+PSA ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 160-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):160:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 192-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):192:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 224-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):224:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 256-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):256:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 320-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):320:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 384-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):384:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 512-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):512:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_KEY_PAIR(MONTGOMERY) 255-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_MONTGOMERY_255
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY):255:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(MONTGOMERY) 448-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_MONTGOMERY_448
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY):448:PSA_SUCCESS:
+
+PSA ECC_PUBLIC_KEY(MONTGOMERY) 255-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_MONTGOMERY):255:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(MONTGOMERY) 448-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_MONTGOMERY):448:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_KEY_PAIR(SECP_K1) 192-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_K1_192
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_K1):192:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(SECP_K1) 224-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_K1_224
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_K1):224:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(SECP_K1) 256-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_K1_256
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_K1):256:PSA_SUCCESS:
+
+PSA ECC_PUBLIC_KEY(SECP_K1) 192-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_K1):192:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(SECP_K1) 224-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_K1):224:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(SECP_K1) 256-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_K1):256:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_KEY_PAIR(SECP_R1) 225-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_225:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):225:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(SECP_R1) 256-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(SECP_R1) 384-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_384
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):384:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(SECP_R1) 521-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_521
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):521:PSA_SUCCESS:
+
+PSA ECC_PUBLIC_KEY(SECP_R1) 225-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):225:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(SECP_R1) 256-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):256:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(SECP_R1) 384-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):384:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(SECP_R1) 521-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):521:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_KEY_PAIR(SECP_R2) 160-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R2_160:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R2):160:PSA_SUCCESS:
+
+PSA ECC_PUBLIC_KEY(SECP_R2) 160-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R2):160:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_KEY_PAIR(SECT_K1) 163-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECT_K1_163:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECT_K1):163:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(SECT_K1) 233-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECT_K1_233:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECT_K1):233:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(SECT_K1) 239-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECT_K1_239:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECT_K1):239:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(SECT_K1) 283-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECT_K1_283:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECT_K1):283:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(SECT_K1) 409-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECT_K1_409:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECT_K1):409:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(SECT_K1) 571-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECT_K1_571:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECT_K1):571:PSA_SUCCESS:
+
+PSA ECC_PUBLIC_KEY(SECT_K1) 163-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_K1):163:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(SECT_K1) 233-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_K1):233:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(SECT_K1) 239-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_K1):239:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(SECT_K1) 283-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_K1):283:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(SECT_K1) 409-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_K1):409:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(SECT_K1) 571-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_K1):571:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_KEY_PAIR(SECT_R1) 163-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECT_R1_163:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECT_R1):163:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(SECT_R1) 233-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECT_R1_233:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECT_R1):233:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(SECT_R1) 283-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECT_R1_283:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECT_R1):283:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(SECT_R1) 409-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECT_R1_409:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECT_R1):409:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(SECT_R1) 571-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECT_R1_571:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECT_R1):571:PSA_SUCCESS:
+
+PSA ECC_PUBLIC_KEY(SECT_R1) 163-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_R1):163:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(SECT_R1) 233-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_R1):233:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(SECT_R1) 283-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_R1):283:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(SECT_R1) 409-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_R1):409:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(SECT_R1) 571-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_R1):571:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_KEY_PAIR(SECT_R2) 163-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECT_R2_163:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECT_R2):163:PSA_SUCCESS:
+
+PSA ECC_PUBLIC_KEY(SECT_R2) 163-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_R2):163:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_KEY_PAIR(TWISTED_EDWARDS) 255-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_TWISTED_EDWARDS_255:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_TWISTED_EDWARDS):255:PSA_SUCCESS:
+
+PSA ECC_KEY_PAIR(TWISTED_EDWARDS) 448-bit
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_TWISTED_EDWARDS_448:DEPENDENCY_NOT_IMPLEMENTED_YET
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_TWISTED_EDWARDS):448:PSA_SUCCESS:
+
+PSA ECC_PUBLIC_KEY(TWISTED_EDWARDS) 255-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_TWISTED_EDWARDS):255:PSA_ERROR_INVALID_ARGUMENT:
+
+PSA ECC_PUBLIC_KEY(TWISTED_EDWARDS) 448-bit
+generate_key:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_TWISTED_EDWARDS):448:PSA_ERROR_INVALID_ARGUMENT:
+
+# End of automatically generated file.
diff --git a/tests/suites/test_suite_psa_crypto_metadata.data b/tests/suites/test_suite_psa_crypto_metadata.data
index 526f0f7..72a11ab 100644
--- a/tests/suites/test_suite_psa_crypto_metadata.data
+++ b/tests/suites/test_suite_psa_crypto_metadata.data
@@ -36,7 +36,7 @@
 
 MAC: HMAC-MD2
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_MD2
-hmac_algorithm:PSA_ALG_HMAC( PSA_ALG_MD2 ):16:64
+hmac_algorithm:PSA_ALG_HMAC( PSA_ALG_MD2 ):16:16
 
 MAC: HMAC-MD4
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_MD4
@@ -146,6 +146,18 @@
 depends_on:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_CCM
 aead_algorithm:PSA_ALG_CCM:ALG_IS_AEAD_ON_BLOCK_CIPHER:16:PSA_KEY_TYPE_AES:256
 
+AEAD: CCM-ARIA-128
+depends_on:PSA_WANT_KEY_TYPE_ARIA:PSA_WANT_ALG_CCM
+aead_algorithm:PSA_ALG_CCM:ALG_IS_AEAD_ON_BLOCK_CIPHER:16:PSA_KEY_TYPE_ARIA:128
+
+AEAD: CCM-ARIA-192
+depends_on:PSA_WANT_KEY_TYPE_ARIA:PSA_WANT_ALG_CCM
+aead_algorithm:PSA_ALG_CCM:ALG_IS_AEAD_ON_BLOCK_CIPHER:16:PSA_KEY_TYPE_ARIA:192
+
+AEAD: CCM-ARIA-256
+depends_on:PSA_WANT_KEY_TYPE_ARIA:PSA_WANT_ALG_CCM
+aead_algorithm:PSA_ALG_CCM:ALG_IS_AEAD_ON_BLOCK_CIPHER:16:PSA_KEY_TYPE_ARIA:256
+
 AEAD: CCM-CAMELLIA-128
 depends_on:PSA_WANT_KEY_TYPE_CAMELLIA:PSA_WANT_ALG_CCM
 aead_algorithm:PSA_ALG_CCM:ALG_IS_AEAD_ON_BLOCK_CIPHER:16:PSA_KEY_TYPE_CAMELLIA:128
@@ -170,6 +182,18 @@
 depends_on:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_GCM
 aead_algorithm:PSA_ALG_GCM:ALG_IS_AEAD_ON_BLOCK_CIPHER:16:PSA_KEY_TYPE_AES:256
 
+AEAD: GCM-ARIA-128
+depends_on:PSA_WANT_KEY_TYPE_ARIA:PSA_WANT_ALG_GCM
+aead_algorithm:PSA_ALG_GCM:ALG_IS_AEAD_ON_BLOCK_CIPHER:16:PSA_KEY_TYPE_ARIA:128
+
+AEAD: GCM-ARIA-192
+depends_on:PSA_WANT_KEY_TYPE_ARIA:PSA_WANT_ALG_GCM
+aead_algorithm:PSA_ALG_GCM:ALG_IS_AEAD_ON_BLOCK_CIPHER:16:PSA_KEY_TYPE_ARIA:192
+
+AEAD: GCM-ARIA-256
+depends_on:PSA_WANT_KEY_TYPE_ARIA:PSA_WANT_ALG_GCM
+aead_algorithm:PSA_ALG_GCM:ALG_IS_AEAD_ON_BLOCK_CIPHER:16:PSA_KEY_TYPE_ARIA:256
+
 AEAD: GCM-CAMELLIA-128
 depends_on:PSA_WANT_KEY_TYPE_CAMELLIA:PSA_WANT_ALG_GCM
 aead_algorithm:PSA_ALG_GCM:ALG_IS_AEAD_ON_BLOCK_CIPHER:16:PSA_KEY_TYPE_CAMELLIA:128
@@ -188,27 +212,31 @@
 
 Asymmetric signature: RSA PKCS#1 v1.5 raw
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN
-asymmetric_signature_algorithm:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:ALG_IS_RSA_PKCS1V15_SIGN | ALG_IS_HASH_AND_SIGN
+asymmetric_signature_algorithm:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:ALG_IS_RSA_PKCS1V15_SIGN | ALG_IS_SIGN_HASH
 
 Asymmetric signature: RSA PKCS#1 v1.5 SHA-256
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256
-asymmetric_signature_algorithm:PSA_ALG_RSA_PKCS1V15_SIGN( PSA_ALG_SHA_256 ):ALG_IS_RSA_PKCS1V15_SIGN | ALG_IS_HASH_AND_SIGN
+asymmetric_signature_algorithm:PSA_ALG_RSA_PKCS1V15_SIGN( PSA_ALG_SHA_256 ):ALG_IS_RSA_PKCS1V15_SIGN | ALG_IS_SIGN_HASH | ALG_IS_HASH_AND_SIGN
 
 Asymmetric signature: RSA PSS SHA-256
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256
-asymmetric_signature_algorithm:PSA_ALG_RSA_PSS( PSA_ALG_SHA_256 ):ALG_IS_RSA_PSS | ALG_IS_HASH_AND_SIGN
+asymmetric_signature_algorithm:PSA_ALG_RSA_PSS( PSA_ALG_SHA_256 ):ALG_IS_RSA_PSS | ALG_IS_RSA_PSS_STANDARD_SALT | ALG_IS_SIGN_HASH | ALG_IS_HASH_AND_SIGN
+
+Asymmetric signature: RSA PSS-any-salt SHA-256
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256
+asymmetric_signature_algorithm:PSA_ALG_RSA_PSS_ANY_SALT( PSA_ALG_SHA_256 ):ALG_IS_RSA_PSS | ALG_IS_RSA_PSS_ANY_SALT | ALG_IS_SIGN_HASH | ALG_IS_HASH_AND_SIGN
 
 Asymmetric signature: randomized ECDSA (no hashing)
 depends_on:PSA_WANT_ALG_ECDSA
-asymmetric_signature_algorithm:PSA_ALG_ECDSA_ANY:ALG_IS_ECDSA | ALG_IS_RANDOMIZED_ECDSA | ALG_IS_HASH_AND_SIGN
+asymmetric_signature_algorithm:PSA_ALG_ECDSA_ANY:ALG_IS_ECDSA | ALG_IS_RANDOMIZED_ECDSA | ALG_IS_SIGN_HASH
 
 Asymmetric signature: SHA-256 + randomized ECDSA
 depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256
-asymmetric_signature_algorithm:PSA_ALG_ECDSA( PSA_ALG_SHA_256 ):ALG_IS_ECDSA | ALG_IS_RANDOMIZED_ECDSA | ALG_IS_HASH_AND_SIGN
+asymmetric_signature_algorithm:PSA_ALG_ECDSA( PSA_ALG_SHA_256 ):ALG_IS_ECDSA | ALG_IS_RANDOMIZED_ECDSA | ALG_IS_SIGN_HASH | ALG_IS_HASH_AND_SIGN
 
 Asymmetric signature: SHA-256 + deterministic ECDSA using SHA-256
 depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256
-asymmetric_signature_algorithm:PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):ALG_IS_ECDSA | ALG_IS_DETERMINISTIC_ECDSA | ALG_ECDSA_IS_DETERMINISTIC | ALG_IS_HASH_AND_SIGN
+asymmetric_signature_algorithm:PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):ALG_IS_ECDSA | ALG_IS_DETERMINISTIC_ECDSA | ALG_ECDSA_IS_DETERMINISTIC | ALG_IS_SIGN_HASH | ALG_IS_HASH_AND_SIGN
 
 Asymmetric signature: pure EdDSA
 depends_on:PSA_WANT_ALG_EDDSA
@@ -216,11 +244,11 @@
 
 Asymmetric signature: Ed25519ph
 depends_on:PSA_WANT_ALG_EDDSA
-asymmetric_signature_algorithm:PSA_ALG_ED25519PH:ALG_IS_HASH_EDDSA | ALG_IS_HASH_AND_SIGN
+asymmetric_signature_algorithm:PSA_ALG_ED25519PH:ALG_IS_HASH_EDDSA | ALG_IS_SIGN_HASH | ALG_IS_HASH_AND_SIGN
 
 Asymmetric signature: Ed448ph
 depends_on:PSA_WANT_ALG_EDDSA
-asymmetric_signature_algorithm:PSA_ALG_ED448PH:ALG_IS_HASH_EDDSA | ALG_IS_HASH_AND_SIGN
+asymmetric_signature_algorithm:PSA_ALG_ED448PH:ALG_IS_HASH_EDDSA | ALG_IS_SIGN_HASH | ALG_IS_HASH_AND_SIGN
 
 Asymmetric signature: RSA PKCS#1 v1.5 with wildcard hash
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN
@@ -228,7 +256,11 @@
 
 Asymmetric signature: RSA PSS with wildcard hash
 depends_on:PSA_WANT_ALG_RSA_PSS
-asymmetric_signature_wildcard:PSA_ALG_RSA_PSS( PSA_ALG_ANY_HASH ):ALG_IS_RSA_PSS
+asymmetric_signature_wildcard:PSA_ALG_RSA_PSS( PSA_ALG_ANY_HASH ):ALG_IS_RSA_PSS | ALG_IS_RSA_PSS_STANDARD_SALT
+
+Asymmetric signature: RSA PSS-any-salt with wildcard hash
+depends_on:PSA_WANT_ALG_RSA_PSS
+asymmetric_signature_wildcard:PSA_ALG_RSA_PSS_ANY_SALT( PSA_ALG_ANY_HASH ):ALG_IS_RSA_PSS | ALG_IS_RSA_PSS_ANY_SALT
 
 Asymmetric signature: randomized ECDSA with wildcard hash
 depends_on:PSA_WANT_ALG_ECDSA
@@ -308,6 +340,10 @@
 depends_on:PSA_WANT_KEY_TYPE_AES
 block_cipher_key_type:PSA_KEY_TYPE_AES:16
 
+Block cipher key type: ARIA
+depends_on:PSA_WANT_KEY_TYPE_ARIA
+block_cipher_key_type:PSA_KEY_TYPE_ARIA:16
+
 Block cipher key type: DES
 depends_on:PSA_WANT_KEY_TYPE_DES
 block_cipher_key_type:PSA_KEY_TYPE_DES:8
diff --git a/tests/suites/test_suite_psa_crypto_metadata.function b/tests/suites/test_suite_psa_crypto_metadata.function
index 7bf1e28..f2ba16a 100644
--- a/tests/suites/test_suite_psa_crypto_metadata.function
+++ b/tests/suites/test_suite_psa_crypto_metadata.function
@@ -22,25 +22,29 @@
 #define ALG_IS_STREAM_CIPHER            ( 1u << 3 )
 #define ALG_IS_RSA_PKCS1V15_SIGN        ( 1u << 4 )
 #define ALG_IS_RSA_PSS                  ( 1u << 5 )
-#define ALG_IS_DSA                      ( 1u << 6 )
-#define ALG_DSA_IS_DETERMINISTIC        ( 1u << 7 )
-#define ALG_IS_DETERMINISTIC_DSA        ( 1u << 8 )
-#define ALG_IS_RANDOMIZED_DSA           ( 1u << 9 )
-#define ALG_IS_ECDSA                    ( 1u << 10 )
-#define ALG_ECDSA_IS_DETERMINISTIC      ( 1u << 11 )
-#define ALG_IS_DETERMINISTIC_ECDSA      ( 1u << 12 )
-#define ALG_IS_RANDOMIZED_ECDSA         ( 1u << 13 )
-#define ALG_IS_HASH_EDDSA               ( 1u << 14 )
-#define ALG_IS_HASH_AND_SIGN            ( 1u << 15 )
-#define ALG_IS_RSA_OAEP                 ( 1u << 16 )
-#define ALG_IS_HKDF                     ( 1u << 17 )
-#define ALG_IS_FFDH                     ( 1u << 18 )
-#define ALG_IS_ECDH                     ( 1u << 19 )
-#define ALG_IS_WILDCARD                 ( 1u << 20 )
-#define ALG_IS_RAW_KEY_AGREEMENT        ( 1u << 21 )
-#define ALG_IS_AEAD_ON_BLOCK_CIPHER     ( 1u << 22 )
-#define ALG_IS_TLS12_PRF                ( 1u << 23 )
-#define ALG_IS_TLS12_PSK_TO_MS          ( 1u << 24 )
+#define ALG_IS_RSA_PSS_ANY_SALT         ( 1u << 6 )
+#define ALG_IS_RSA_PSS_STANDARD_SALT    ( 1u << 7 )
+#define ALG_IS_DSA                      ( 1u << 8 )
+#define ALG_DSA_IS_DETERMINISTIC        ( 1u << 9 )
+#define ALG_IS_DETERMINISTIC_DSA        ( 1u << 10 )
+#define ALG_IS_RANDOMIZED_DSA           ( 1u << 11 )
+#define ALG_IS_ECDSA                    ( 1u << 12 )
+#define ALG_ECDSA_IS_DETERMINISTIC      ( 1u << 13 )
+#define ALG_IS_DETERMINISTIC_ECDSA      ( 1u << 14 )
+#define ALG_IS_RANDOMIZED_ECDSA         ( 1u << 15 )
+#define ALG_IS_HASH_EDDSA               ( 1u << 16 )
+#define ALG_IS_SIGN_HASH                ( 1u << 17 )
+#define ALG_IS_HASH_AND_SIGN            ( 1u << 18 )
+#define ALG_IS_RSA_OAEP                 ( 1u << 19 )
+#define ALG_IS_HKDF                     ( 1u << 20 )
+#define ALG_IS_FFDH                     ( 1u << 21 )
+#define ALG_IS_ECDH                     ( 1u << 22 )
+#define ALG_IS_WILDCARD                 ( 1u << 23 )
+#define ALG_IS_RAW_KEY_AGREEMENT        ( 1u << 24 )
+#define ALG_IS_AEAD_ON_BLOCK_CIPHER     ( 1u << 25 )
+#define ALG_IS_TLS12_PRF                ( 1u << 26 )
+#define ALG_IS_TLS12_PSK_TO_MS          ( 1u << 27 )
+#define ALG_FLAG_MASK_PLUS_ONE          ( 1u << 28 ) /* must be last! */
 
 /* Flags for key type classification macros. There is a flag for every
  * key type classification macro PSA_KEY_TYPE_IS_xxx except for some that
@@ -49,26 +53,43 @@
 #define KEY_TYPE_IS_VENDOR_DEFINED      ( 1u << 0 )
 #define KEY_TYPE_IS_UNSTRUCTURED        ( 1u << 1 )
 #define KEY_TYPE_IS_PUBLIC_KEY          ( 1u << 2 )
-#define KEY_TYPE_IS_KEY_PAIR             ( 1u << 3 )
+#define KEY_TYPE_IS_KEY_PAIR            ( 1u << 3 )
 #define KEY_TYPE_IS_RSA                 ( 1u << 4 )
 #define KEY_TYPE_IS_DSA                 ( 1u << 5 )
 #define KEY_TYPE_IS_ECC                 ( 1u << 6 )
 #define KEY_TYPE_IS_DH                  ( 1u << 7 )
+#define KEY_TYPE_FLAG_MASK_PLUS_ONE     ( 1u << 8 ) /* must be last! */
 
 /* Flags for lifetime classification macros. There is a flag for every
  * lifetime classification macro PSA_KEY_LIFETIME_IS_xxx. The name of the
  * flag is the name of the classification macro without the PSA_ prefix. */
 #define KEY_LIFETIME_IS_VOLATILE        ( 1u << 0 )
 #define KEY_LIFETIME_IS_READ_ONLY       ( 1u << 1 )
+#define KEY_LIFETIME_FLAG_MASK_PLUS_ONE ( 1u << 2 ) /* must be last! */
 
-#define TEST_CLASSIFICATION_MACRO( flag, alg, flags ) \
-    do                                                \
-    {                                                 \
-        if( ( flags ) & ( flag ) )                    \
-            TEST_ASSERT( PSA_##flag( alg ) );         \
-        else                                          \
-            TEST_ASSERT( ! PSA_##flag( alg ) );       \
-    }                                                 \
+/* Check that in the value of flags, the bit flag (which should be a macro
+ * expanding to a number of the form 1 << k) is set if and only if
+ * PSA_##flag(alg) is true.
+ *
+ * Only perform this check if cond is true. Typically cond is 1, but it can
+ * be different if the value of the flag bit is only specified under specific
+ * conditions.
+ *
+ * Unconditionally mask flag into the ambient variable
+ * classification_flags_tested.
+ */
+#define TEST_CLASSIFICATION_MACRO( cond, flag, alg, flags )     \
+    do                                                          \
+    {                                                           \
+        if( cond )                                              \
+        {                                                       \
+            if( ( flags ) & ( flag ) )                          \
+                TEST_ASSERT( PSA_##flag( alg ) );               \
+            else                                                \
+                TEST_ASSERT( ! PSA_##flag( alg ) );             \
+        }                                                       \
+        classification_flags_tested |= ( flag );                \
+    }                                                           \
     while( 0 )
 
 /* Check the parity of value.
@@ -95,44 +116,55 @@
 
 void algorithm_classification( psa_algorithm_t alg, unsigned flags )
 {
-    TEST_CLASSIFICATION_MACRO( ALG_IS_VENDOR_DEFINED, alg, flags );
-    TEST_CLASSIFICATION_MACRO( ALG_IS_HMAC, alg, flags );
-    TEST_CLASSIFICATION_MACRO( ALG_IS_BLOCK_CIPHER_MAC, alg, flags );
-    TEST_CLASSIFICATION_MACRO( ALG_IS_STREAM_CIPHER, alg, flags );
-    TEST_CLASSIFICATION_MACRO( ALG_IS_RSA_PKCS1V15_SIGN, alg, flags );
-    TEST_CLASSIFICATION_MACRO( ALG_IS_RSA_PSS, alg, flags );
-    TEST_CLASSIFICATION_MACRO( ALG_IS_DSA, alg, flags );
-    if ( PSA_ALG_IS_DSA( alg ) )
-        TEST_CLASSIFICATION_MACRO( ALG_DSA_IS_DETERMINISTIC, alg, flags );
-    TEST_CLASSIFICATION_MACRO( ALG_IS_DETERMINISTIC_DSA, alg, flags );
-    TEST_CLASSIFICATION_MACRO( ALG_IS_RANDOMIZED_DSA, alg, flags );
-    TEST_CLASSIFICATION_MACRO( ALG_IS_ECDSA, alg, flags );
-    if ( PSA_ALG_IS_ECDSA( alg ) )
-        TEST_CLASSIFICATION_MACRO( ALG_ECDSA_IS_DETERMINISTIC, alg, flags );
-    TEST_CLASSIFICATION_MACRO( ALG_IS_DETERMINISTIC_ECDSA, alg, flags );
-    TEST_CLASSIFICATION_MACRO( ALG_IS_RANDOMIZED_ECDSA, alg, flags );
-    TEST_CLASSIFICATION_MACRO( ALG_IS_HASH_EDDSA, alg, flags );
-    TEST_CLASSIFICATION_MACRO( ALG_IS_HASH_AND_SIGN, alg, flags );
-    TEST_CLASSIFICATION_MACRO( ALG_IS_RSA_OAEP, alg, flags );
-    TEST_CLASSIFICATION_MACRO( ALG_IS_HKDF, alg, flags );
-    TEST_CLASSIFICATION_MACRO( ALG_IS_WILDCARD, alg, flags );
-    TEST_CLASSIFICATION_MACRO( ALG_IS_ECDH, alg, flags );
-    TEST_CLASSIFICATION_MACRO( ALG_IS_FFDH, alg, flags );
-    TEST_CLASSIFICATION_MACRO( ALG_IS_RAW_KEY_AGREEMENT, alg, flags );
-    TEST_CLASSIFICATION_MACRO( ALG_IS_AEAD_ON_BLOCK_CIPHER, alg, flags );
+    unsigned classification_flags_tested = 0;
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_VENDOR_DEFINED, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_HMAC, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_BLOCK_CIPHER_MAC, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_STREAM_CIPHER, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RSA_PKCS1V15_SIGN, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RSA_PSS, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RSA_PSS_ANY_SALT, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RSA_PSS_STANDARD_SALT, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_DSA, alg, flags );
+    TEST_CLASSIFICATION_MACRO( PSA_ALG_IS_DSA( alg ),
+                               ALG_DSA_IS_DETERMINISTIC, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_DETERMINISTIC_DSA, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RANDOMIZED_DSA, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_ECDSA, alg, flags );
+    TEST_CLASSIFICATION_MACRO( PSA_ALG_IS_ECDSA( alg ),
+                               ALG_ECDSA_IS_DETERMINISTIC, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_DETERMINISTIC_ECDSA, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RANDOMIZED_ECDSA, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_HASH_EDDSA, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_SIGN_HASH, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_HASH_AND_SIGN, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RSA_OAEP, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_HKDF, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_WILDCARD, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_ECDH, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_FFDH, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RAW_KEY_AGREEMENT, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_AEAD_ON_BLOCK_CIPHER, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_TLS12_PRF, alg, flags );
+    TEST_CLASSIFICATION_MACRO( 1, ALG_IS_TLS12_PSK_TO_MS, alg, flags );
+    TEST_EQUAL( classification_flags_tested, ALG_FLAG_MASK_PLUS_ONE - 1 );
 exit: ;
 }
 
 void key_type_classification( psa_key_type_t type, unsigned flags )
 {
+    unsigned classification_flags_tested = 0;
+
     /* Macros tested based on the test case parameter */
-    TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_VENDOR_DEFINED, type, flags );
-    TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_UNSTRUCTURED, type, flags );
-    TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_PUBLIC_KEY, type, flags );
-    TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_KEY_PAIR, type, flags );
-    TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_RSA, type, flags );
-    TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_ECC, type, flags );
-    TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_DH, type, flags );
+    TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_VENDOR_DEFINED, type, flags );
+    TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_UNSTRUCTURED, type, flags );
+    TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_PUBLIC_KEY, type, flags );
+    TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_KEY_PAIR, type, flags );
+    TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_RSA, type, flags );
+    TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_DSA, type, flags );
+    TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_ECC, type, flags );
+    TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_DH, type, flags );
+    TEST_EQUAL( classification_flags_tested, KEY_TYPE_FLAG_MASK_PLUS_ONE - 1 );
 
     /* Macros with derived semantics */
     TEST_EQUAL( PSA_KEY_TYPE_IS_ASYMMETRIC( type ),
@@ -348,6 +380,7 @@
     TEST_ASSERT( PSA_ALG_IS_HASH( hash_alg ) );
     TEST_EQUAL( PSA_ALG_HMAC( hash_alg ), alg );
 
+    TEST_ASSERT( block_size == PSA_HASH_BLOCK_LENGTH( alg ) );
     TEST_ASSERT( block_size <= PSA_HMAC_MAX_HASH_BLOCK_SIZE );
 
     test_mac_algorithm( alg_arg, ALG_IS_HMAC, length,
@@ -482,7 +515,9 @@
 /* BEGIN_CASE */
 void asymmetric_signature_wildcard( int alg_arg, int classification_flags )
 {
-    classification_flags |= ALG_IS_HASH_AND_SIGN | ALG_IS_WILDCARD;
+    classification_flags |= ALG_IS_WILDCARD;
+    classification_flags |= ALG_IS_SIGN_HASH;
+    classification_flags |= ALG_IS_HASH_AND_SIGN;
     test_asymmetric_signature_algorithm( alg_arg, classification_flags );
     /* Any failure of this test function comes from
      * asymmetric_signature_algorithm. Pacify -Werror=unused-label. */
@@ -665,9 +700,12 @@
     psa_key_persistence_t persistence = persistence_arg;
     psa_key_location_t location = location_arg;
     unsigned flags = classification_flags;
+    unsigned classification_flags_tested = 0;
 
-    TEST_CLASSIFICATION_MACRO( KEY_LIFETIME_IS_VOLATILE, lifetime, flags );
-    TEST_CLASSIFICATION_MACRO( KEY_LIFETIME_IS_READ_ONLY, lifetime, flags );
+    TEST_CLASSIFICATION_MACRO( 1, KEY_LIFETIME_IS_VOLATILE, lifetime, flags );
+    TEST_CLASSIFICATION_MACRO( 1, KEY_LIFETIME_IS_READ_ONLY, lifetime, flags );
+    TEST_EQUAL( classification_flags_tested,
+                KEY_LIFETIME_FLAG_MASK_PLUS_ONE - 1 );
 
     TEST_EQUAL( PSA_KEY_LIFETIME_GET_PERSISTENCE( lifetime ), persistence );
     TEST_EQUAL( PSA_KEY_LIFETIME_GET_LOCATION( lifetime ), location );
diff --git a/tests/suites/test_suite_psa_crypto_not_supported.generated.data b/tests/suites/test_suite_psa_crypto_not_supported.generated.data
index e39c8ed..b5c8a52 100644
--- a/tests/suites/test_suite_psa_crypto_not_supported.generated.data
+++ b/tests/suites/test_suite_psa_crypto_not_supported.generated.data
@@ -48,6 +48,30 @@
 depends_on:!PSA_WANT_KEY_TYPE_ARC4
 generate_not_supported:PSA_KEY_TYPE_ARC4:2048
 
+PSA import ARIA 128-bit not supported
+depends_on:!PSA_WANT_KEY_TYPE_ARIA
+import_not_supported:PSA_KEY_TYPE_ARIA:"48657265006973206b6579a064617461"
+
+PSA generate ARIA 128-bit not supported
+depends_on:!PSA_WANT_KEY_TYPE_ARIA
+generate_not_supported:PSA_KEY_TYPE_ARIA:128
+
+PSA import ARIA 192-bit not supported
+depends_on:!PSA_WANT_KEY_TYPE_ARIA
+import_not_supported:PSA_KEY_TYPE_ARIA:"48657265006973206b6579a0646174614865726500697320"
+
+PSA generate ARIA 192-bit not supported
+depends_on:!PSA_WANT_KEY_TYPE_ARIA
+generate_not_supported:PSA_KEY_TYPE_ARIA:192
+
+PSA import ARIA 256-bit not supported
+depends_on:!PSA_WANT_KEY_TYPE_ARIA
+import_not_supported:PSA_KEY_TYPE_ARIA:"48657265006973206b6579a06461746148657265006973206b6579a064617461"
+
+PSA generate ARIA 256-bit not supported
+depends_on:!PSA_WANT_KEY_TYPE_ARIA
+generate_not_supported:PSA_KEY_TYPE_ARIA:256
+
 PSA import CAMELLIA 128-bit not supported
 depends_on:!PSA_WANT_KEY_TYPE_CAMELLIA
 import_not_supported:PSA_KEY_TYPE_CAMELLIA:"48657265006973206b6579a064617461"
@@ -172,16 +196,10 @@
 depends_on:!PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY
 import_not_supported:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001"
 
-PSA generate RSA_PUBLIC_KEY 1024-bit never supported
-generate_not_supported:PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024
-
 PSA import RSA_PUBLIC_KEY 1536-bit not supported
 depends_on:!PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY
 import_not_supported:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"3081c90281c100c870feb6ca6b1d2bd9f2dd99e20f1fe2d7e5192de662229dbe162bd1ba66336a7182903ca0b72796cd441c83d24bcdc3e9a2f5e4399c8a043f1c3ddf04754a66d4cfe7b3671a37dd31a9b4c13bfe06ee90f9d94ddaa06de67a52ac863e68f756736ceb014405a6160579640f831dddccc34ad0b05070e3f9954a58d1815813e1b83bcadba814789c87f1ef2ba5d738b793ec456a67360eea1b5faf1c7cc7bf24f3b2a9d0f8958b1096e0f0c335f8888d0c63a51c3c0337214fa3f5efdf6dcc350203010001"
 
-PSA generate RSA_PUBLIC_KEY 1536-bit never supported
-generate_not_supported:PSA_KEY_TYPE_RSA_PUBLIC_KEY:1536
-
 PSA import ECC_KEY_PAIR(BRAINPOOL_P_R1) 160-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_BRAINPOOL_P_R1_160:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"69502c4fdaf48d4fa617bdd24498b0406d0eeaac"
@@ -298,51 +316,30 @@
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_BRAINPOOL_P_R1_160:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"04d4b9186816358e2f9c59cf70748cb70641b22fbab65473db4b4e22a361ed7e3de7e8a8ddc4130c5c"
 
-PSA generate ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 160-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):160
-
 PSA import ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 192-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_BRAINPOOL_P_R1_192:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"043fdd168c179ff5363dd71dcd58de9617caad791ae0c37328be9ca0bfc79cebabf6a95d1c52df5b5f3c8b1a2441cf6c88"
 
-PSA generate ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 192-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):192
-
 PSA import ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 224-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_BRAINPOOL_P_R1_224:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"045fbea378fc8583b3837e3f21a457c31eaf20a54e18eb11d104b3adc47f9d1c97eb9ea4ac21740d70d88514b98bf0bc31addac1d19c4ab3cc"
 
-PSA generate ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 224-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):224
-
 PSA import ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 256-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_BRAINPOOL_P_R1_256
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"04768c8cae4abca6306db0ed81b0c4a6215c378066ec6d616c146e13f1c7df809b96ab6911c27d8a02339f0926840e55236d3d1efbe2669d090e4c4c660fada91d"
 
-PSA generate ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 256-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):256
-
 PSA import ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 320-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_BRAINPOOL_P_R1_320:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"049caed8fb4742956cc2ad12a9a1c995e21759ef26a07bc2054136d3d2f28bb331a70e26c4c687275ab1f434be7871e115d2350c0c5f61d4d06d2bcdb67f5cb63fdb794e5947c87dc6849a58694e37e6cd"
 
-PSA generate ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 320-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):320
-
 PSA import ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 384-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_BRAINPOOL_P_R1_384
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"04719f9d093a627e0d350385c661cebf00c61923566fe9006a3107af1d871bc6bb68985fd722ea32be316f8e783b7cd1957785f66cfc0cb195dd5c99a8e7abaa848553a584dfd2b48e76d445fe00dd8be59096d877d4696d23b4bc8db14724e66a"
 
-PSA generate ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 384-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):384
-
 PSA import ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 512-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_BRAINPOOL_P_R1_512
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"0438b7ec92b61c5c6c7fbc28a4ec759d48fcd4e2e374defd5c4968a54dbef7510e517886fbfc38ea39aa529359d70a7156c35d3cbac7ce776bdb251dd64bce71234424ee7049eed072f0dbc4d79996e175d557e263763ae97095c081e73e7db2e38adc3d4c9a0487b1ede876dc1fca61c902e9a1d8722b8612928f18a24845591a"
 
-PSA generate ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 512-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):512
-
 PSA import ECC_PUBLIC_KEY(BRAINPOOL_P_R1) 160-bit curve not supported
 depends_on:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:!PSA_WANT_ECC_BRAINPOOL_P_R1_160:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"04d4b9186816358e2f9c59cf70748cb70641b22fbab65473db4b4e22a361ed7e3de7e8a8ddc4130c5c"
@@ -407,16 +404,10 @@
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_MONTGOMERY_255
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_MONTGOMERY):"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a"
 
-PSA generate ECC_PUBLIC_KEY(MONTGOMERY) 255-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_MONTGOMERY):255
-
 PSA import ECC_PUBLIC_KEY(MONTGOMERY) 448-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_MONTGOMERY_448
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_MONTGOMERY):"c0d3a5a2b416a573dc9909f92f134ac01323ab8f8e36804e578588ba2d09fe7c3e737f771ca112825b548a0ffded6d6a2fd09a3e77dec30e"
 
-PSA generate ECC_PUBLIC_KEY(MONTGOMERY) 448-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_MONTGOMERY):448
-
 PSA import ECC_PUBLIC_KEY(MONTGOMERY) 255-bit curve not supported
 depends_on:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:!PSA_WANT_ECC_MONTGOMERY_255
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_MONTGOMERY):"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a"
@@ -477,23 +468,14 @@
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECP_K1_192
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_K1):"0426b7bb38da649ac2138fc050c6548b32553dab68afebc36105d325b75538c12323cb0764789ecb992671beb2b6bef2f5"
 
-PSA generate ECC_PUBLIC_KEY(SECP_K1) 192-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_K1):192
-
 PSA import ECC_PUBLIC_KEY(SECP_K1) 224-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECP_K1_224
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_K1):"042cc7335f4b76042bed44ef45959a62aa215f7a5ff0c8111b8c44ed654ee71c1918326ad485b2d599fe2a6eab096ee26d977334d2bac6d61d"
 
-PSA generate ECC_PUBLIC_KEY(SECP_K1) 224-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_K1):224
-
 PSA import ECC_PUBLIC_KEY(SECP_K1) 256-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECP_K1_256
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_K1):"045c39154579efd667adc73a81015a797d2c8682cdfbd3c3553c4a185d481cdc50e42a0e1cbc3ca29a32a645e927f54beaed14c9dbbf8279d725f5495ca924b24d"
 
-PSA generate ECC_PUBLIC_KEY(SECP_K1) 256-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_K1):256
-
 PSA import ECC_PUBLIC_KEY(SECP_K1) 192-bit curve not supported
 depends_on:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:!PSA_WANT_ECC_SECP_K1_192
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_K1):"0426b7bb38da649ac2138fc050c6548b32553dab68afebc36105d325b75538c12323cb0764789ecb992671beb2b6bef2f5"
@@ -574,30 +556,18 @@
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECP_R1_225:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"046f00eadaa949fee3e9e1c7fa1247eecec86a0dce46418b9bd3117b981d4bd0ae7a990de912f9d060d6cb531a42d22e394ac29e81804bf160"
 
-PSA generate ECC_PUBLIC_KEY(SECP_R1) 225-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):225
-
 PSA import ECC_PUBLIC_KEY(SECP_R1) 256-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECP_R1_256
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45"
 
-PSA generate ECC_PUBLIC_KEY(SECP_R1) 256-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):256
-
 PSA import ECC_PUBLIC_KEY(SECP_R1) 384-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECP_R1_384
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04d9c662b50ba29ca47990450e043aeaf4f0c69b15676d112f622a71c93059af999691c5680d2b44d111579db12f4a413a2ed5c45fcfb67b5b63e00b91ebe59d09a6b1ac2c0c4282aa12317ed5914f999bc488bb132e8342cc36f2ca5e3379c747"
 
-PSA generate ECC_PUBLIC_KEY(SECP_R1) 384-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):384
-
 PSA import ECC_PUBLIC_KEY(SECP_R1) 521-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECP_R1_521
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04001de142d54f69eb038ee4b7af9d3ca07736fd9cf719eb354d69879ee7f3c136fb0fbf9f08f86be5fa128ec1a051d3e6c643e85ada8ffacf3663c260bd2c844b6f5600cee8e48a9e65d09cadd89f235dee05f3b8a646be715f1f67d5b434e0ff23a1fc07ef7740193e40eeff6f3bcdfd765aa9155033524fe4f205f5444e292c4c2f6ac1"
 
-PSA generate ECC_PUBLIC_KEY(SECP_R1) 521-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):521
-
 PSA import ECC_PUBLIC_KEY(SECP_R1) 225-bit curve not supported
 depends_on:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:!PSA_WANT_ECC_SECP_R1_225:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"046f00eadaa949fee3e9e1c7fa1247eecec86a0dce46418b9bd3117b981d4bd0ae7a990de912f9d060d6cb531a42d22e394ac29e81804bf160"
@@ -634,9 +604,6 @@
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECP_R2_160:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R2):"049570d541398665adb5cfa16f5af73b3196926bbd4b876bdb80f8eab20d0f540c22f4de9c140f6d7b"
 
-PSA generate ECC_PUBLIC_KEY(SECP_R2) 160-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R2):160
-
 PSA import ECC_PUBLIC_KEY(SECP_R2) 160-bit curve not supported
 depends_on:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:!PSA_WANT_ECC_SECP_R2_160:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R2):"049570d541398665adb5cfa16f5af73b3196926bbd4b876bdb80f8eab20d0f540c22f4de9c140f6d7b"
@@ -741,44 +708,26 @@
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECT_K1_163:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_K1):"0406f88f90b4b65950f06ce433afdb097e320f433dc2062b8a65db8fafd3c110f46bc45663fbf021ee7eb9"
 
-PSA generate ECC_PUBLIC_KEY(SECT_K1) 163-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_K1):163
-
 PSA import ECC_PUBLIC_KEY(SECT_K1) 233-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECT_K1_233:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_K1):"0401e9d7189189f773bd8f71be2c10774ba18842434dfa9312595ea545104400f45a9d5675647513ba75b079fe66a29daac2ec86a6a5d4e75c5f290c1f"
 
-PSA generate ECC_PUBLIC_KEY(SECT_K1) 233-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_K1):233
-
 PSA import ECC_PUBLIC_KEY(SECT_K1) 239-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECT_K1_239:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_K1):"04068d76b9f4508762c2379db9ee8b87ad8d86d9535132ffba3b5680440cfa28eb133d4232faf1c9aba96af11aefe634a551440800d5f8185105d3072d"
 
-PSA generate ECC_PUBLIC_KEY(SECT_K1) 239-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_K1):239
-
 PSA import ECC_PUBLIC_KEY(SECT_K1) 283-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECT_K1_283:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_K1):"0405f48374debceaadb46ba385fd92048fcc5b9af1a1c90408bf94a68b9378df1cbfdfb6fb026a96bea06d8f181bf10c020adbcc88b6ecff96bdc564a9649c247cede601c4be63afc3"
 
-PSA generate ECC_PUBLIC_KEY(SECT_K1) 283-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_K1):283
-
 PSA import ECC_PUBLIC_KEY(SECT_K1) 409-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECT_K1_409:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_K1):"04012c587f69f68b308ba6dcb238797f4e22290ca939ae806604e2b5ab4d9caef5a74a98fd87c4f88d292dd39d92e556e16c6ecc3c019a105826eef507cd9a04119f54d5d850b3720b3792d5d03410e9105610f7e4b420166ed45604a7a1f229d80975ba6be2060e8b"
 
-PSA generate ECC_PUBLIC_KEY(SECT_K1) 409-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_K1):409
-
 PSA import ECC_PUBLIC_KEY(SECT_K1) 571-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECT_K1_571:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_K1):"04050172a7fd7adf98e4e2ed2742faa5cd12731a15fb0dbbdf75b1c3cc771a4369af6f2fa00e802735650881735759ea9c79961ded18e0daa0ac59afb1d513b5bbda9962e435f454fc020b4afe1445c2302ada07d295ec2580f8849b2dfa7f956b09b4cbe4c88d3b1c217049f75d3900d36df0fa12689256b58dd2ef784ebbeb0564600cf47a841485f8cf897a68accd5a"
 
-PSA generate ECC_PUBLIC_KEY(SECT_K1) 571-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_K1):571
-
 PSA import ECC_PUBLIC_KEY(SECT_K1) 163-bit curve not supported
 depends_on:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:!PSA_WANT_ECC_SECT_K1_163:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_K1):"0406f88f90b4b65950f06ce433afdb097e320f433dc2062b8a65db8fafd3c110f46bc45663fbf021ee7eb9"
@@ -887,37 +836,22 @@
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECT_R1_163:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_R1):"0400465eeb9e7258b11e33c02266bfe834b20bcb118700772796ee4704ec67651bd447e3011959a79a04cb"
 
-PSA generate ECC_PUBLIC_KEY(SECT_R1) 163-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_R1):163
-
 PSA import ECC_PUBLIC_KEY(SECT_R1) 233-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECT_R1_233:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_R1):"0400cd68c8af4430c92ec7a7048becfdf00a6bae8d1b4c37286f2d336f2a0e017eca3748f4ad6d435c85867aa014eea1bd6d9d005bbd8319cab629001d"
 
-PSA generate ECC_PUBLIC_KEY(SECT_R1) 233-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_R1):233
-
 PSA import ECC_PUBLIC_KEY(SECT_R1) 283-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECT_R1_283:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_R1):"04052f9ff887254c2d1440ba9e30f13e2185ba53c373b2c410dae21cf8c167f796c08134f601cbc4c570bffbc2433082cf4d9eb5ba173ecb8caec15d66a02673f60807b2daa729b765"
 
-PSA generate ECC_PUBLIC_KEY(SECT_R1) 283-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_R1):283
-
 PSA import ECC_PUBLIC_KEY(SECT_R1) 409-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECT_R1_409:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_R1):"0401aa25466b1d291846db365957b25431591e50d9c109fe2106e93bb369775896925b15a7bfec397406ab4fe6f6b1a13bf8fdcb9300fa5500a813228676b0a6c572ed96b0f4aec7e87832e7e20f17ca98ecdfd36f59c82bddb8665f1f357a73900e827885ec9e1f22"
 
-PSA generate ECC_PUBLIC_KEY(SECT_R1) 409-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_R1):409
-
 PSA import ECC_PUBLIC_KEY(SECT_R1) 571-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECT_R1_571:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_R1):"040708f3403ee9948114855c17572152a08f8054d486defef5f29cbffcfb7cfd9280746a1ac5f751a6ad902ec1e0525120e9be56f03437af196fbe60ee7856e3542ab2cf87880632d80290e39b1a2bd03c6bbf6225511c567bd2ff41d2325dc58346f2b60b1feee4dc8b2af2296c2dc52b153e0556b5d24152b07f690c3fa24e4d1d19efbdeb1037833a733654d2366c74"
 
-PSA generate ECC_PUBLIC_KEY(SECT_R1) 571-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_R1):571
-
 PSA import ECC_PUBLIC_KEY(SECT_R1) 163-bit curve not supported
 depends_on:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:!PSA_WANT_ECC_SECT_R1_163:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_R1):"0400465eeb9e7258b11e33c02266bfe834b20bcb118700772796ee4704ec67651bd447e3011959a79a04cb"
@@ -958,9 +892,6 @@
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECT_R2_163:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_R2):"0403692601144c32a6cfa369ae20ae5d43c1c764678c037bafe80c6fd2e42b7ced96171d9c5367fd3dca6f"
 
-PSA generate ECC_PUBLIC_KEY(SECT_R2) 163-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_R2):163
-
 PSA import ECC_PUBLIC_KEY(SECT_R2) 163-bit curve not supported
 depends_on:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:!PSA_WANT_ECC_SECT_R2_163:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECT_R2):"0403692601144c32a6cfa369ae20ae5d43c1c764678c037bafe80c6fd2e42b7ced96171d9c5367fd3dca6f"
@@ -1001,16 +932,10 @@
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_TWISTED_EDWARDS_255:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_TWISTED_EDWARDS):"d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"
 
-PSA generate ECC_PUBLIC_KEY(TWISTED_EDWARDS) 255-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_TWISTED_EDWARDS):255
-
 PSA import ECC_PUBLIC_KEY(TWISTED_EDWARDS) 448-bit type not supported
 depends_on:!PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_TWISTED_EDWARDS_448:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_TWISTED_EDWARDS):"5fd7449b59b461fd2ce787ec616ad46a1da1342485a70e1f8a0ea75d80e96778edf124769b46c7061bd6783df1e50f6cd1fa1abeafe8256180"
 
-PSA generate ECC_PUBLIC_KEY(TWISTED_EDWARDS) 448-bit type never supported
-generate_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_TWISTED_EDWARDS):448
-
 PSA import ECC_PUBLIC_KEY(TWISTED_EDWARDS) 255-bit curve not supported
 depends_on:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:!PSA_WANT_ECC_TWISTED_EDWARDS_255:DEPENDENCY_NOT_IMPLEMENTED_YET
 import_not_supported:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_TWISTED_EDWARDS):"d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"
diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal.data b/tests/suites/test_suite_psa_crypto_se_driver_hal.data
index a57e9b3..2bcf4e4 100644
--- a/tests/suites/test_suite_psa_crypto_se_driver_hal.data
+++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.data
@@ -78,6 +78,21 @@
 Key import smoke test: AES-GCM
 import_key_smoke:PSA_KEY_TYPE_AES:PSA_ALG_GCM:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 
+Key import smoke test: ARIA-CTR
+import_key_smoke:PSA_KEY_TYPE_ARIA:PSA_ALG_CTR:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+
+Key import smoke test: ARIA-CBC
+import_key_smoke:PSA_KEY_TYPE_ARIA:PSA_ALG_CBC_NO_PADDING:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+
+Key import smoke test: ARIA-CMAC
+import_key_smoke:PSA_KEY_TYPE_ARIA:PSA_ALG_CMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+
+Key import smoke test: ARIA-CCM
+import_key_smoke:PSA_KEY_TYPE_ARIA:PSA_ALG_CCM:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+
+Key import smoke test: ARIA-GCM
+import_key_smoke:PSA_KEY_TYPE_ARIA:PSA_ALG_GCM:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+
 Key import smoke test: CAMELLIA-CTR
 import_key_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_CTR:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 
diff --git a/tests/suites/test_suite_psa_crypto_slot_management.data b/tests/suites/test_suite_psa_crypto_slot_management.data
index 68b196d..1477734 100644
--- a/tests/suites/test_suite_psa_crypto_slot_management.data
+++ b/tests/suites/test_suite_psa_crypto_slot_management.data
@@ -160,7 +160,7 @@
 create_fail:PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_ID_USER_MAX + 1:PSA_ERROR_INVALID_ARGUMENT
 
 Open not supported
-depends_on:!MBEDTLS_PSA_CRYPTO_STORAGE_C
+depends_on:!MBEDTLS_PSA_CRYPTO_STORAGE_C:!MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS
 open_fail:1:PSA_ERROR_NOT_SUPPORTED
 
 Create not supported
diff --git a/tests/suites/test_suite_psa_crypto_storage_format.current.data b/tests/suites/test_suite_psa_crypto_storage_format.current.data
index ec74aba..737b4a7 100644
--- a/tests/suites/test_suite_psa_crypto_storage_format.current.data
+++ b/tests/suites/test_suite_psa_crypto_storage_format.current.data
@@ -120,6 +120,18 @@
 depends_on:PSA_WANT_KEY_TYPE_ARC4
 key_storage_save:0x0001:PSA_KEY_TYPE_ARC4:2048:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a064617461":"505341004b4559000000000001000000022000080100000000000000000000000001000048657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a064617461"
 
+PSA storage save: type: ARIA 128-bit
+depends_on:PSA_WANT_KEY_TYPE_ARIA
+key_storage_save:0x0001:PSA_KEY_TYPE_ARIA:128:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a064617461":"505341004b4559000000000001000000062480000100000000000000000000001000000048657265006973206b6579a064617461"
+
+PSA storage save: type: ARIA 192-bit
+depends_on:PSA_WANT_KEY_TYPE_ARIA
+key_storage_save:0x0001:PSA_KEY_TYPE_ARIA:192:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a0646174614865726500697320":"505341004b45590000000000010000000624c0000100000000000000000000001800000048657265006973206b6579a0646174614865726500697320"
+
+PSA storage save: type: ARIA 256-bit
+depends_on:PSA_WANT_KEY_TYPE_ARIA
+key_storage_save:0x0001:PSA_KEY_TYPE_ARIA:256:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a06461746148657265006973206b6579a064617461":"505341004b4559000000000001000000062400010100000000000000000000002000000048657265006973206b6579a06461746148657265006973206b6579a064617461"
+
 PSA storage save: type: CAMELLIA 128-bit
 depends_on:PSA_WANT_KEY_TYPE_CAMELLIA
 key_storage_save:0x0001:PSA_KEY_TYPE_CAMELLIA:128:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a064617461":"505341004b4559000000000001000000032480000100000000000000000000001000000048657265006973206b6579a064617461"
@@ -1552,6 +1564,86 @@
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_KEY_TYPE_RAW_DATA
 key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH):"4c":"505341004b4559000000000001000000011008000100000000000000ff030006010000004c"
 
+PSA storage save: alg: RSA_PSS_ANY_SALT(MD2)
+depends_on:PSA_WANT_ALG_MD2:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_MD2):0x0000:"4b":"505341004b455900000000000100000001100800010000000113000600000000010000004b"
+
+PSA storage save: alg2: RSA_PSS_ANY_SALT(MD2)
+depends_on:PSA_WANT_ALG_MD2:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_MD2):"4c":"505341004b455900000000000100000001100800010000000000000001130006010000004c"
+
+PSA storage save: alg: RSA_PSS_ANY_SALT(MD4)
+depends_on:PSA_WANT_ALG_MD4:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_MD4):0x0000:"4b":"505341004b455900000000000100000001100800010000000213000600000000010000004b"
+
+PSA storage save: alg2: RSA_PSS_ANY_SALT(MD4)
+depends_on:PSA_WANT_ALG_MD4:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_MD4):"4c":"505341004b455900000000000100000001100800010000000000000002130006010000004c"
+
+PSA storage save: alg: RSA_PSS_ANY_SALT(MD5)
+depends_on:PSA_WANT_ALG_MD5:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_MD5):0x0000:"4b":"505341004b455900000000000100000001100800010000000313000600000000010000004b"
+
+PSA storage save: alg2: RSA_PSS_ANY_SALT(MD5)
+depends_on:PSA_WANT_ALG_MD5:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_MD5):"4c":"505341004b455900000000000100000001100800010000000000000003130006010000004c"
+
+PSA storage save: alg: RSA_PSS_ANY_SALT(RIPEMD160)
+depends_on:PSA_WANT_ALG_RIPEMD160:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_RIPEMD160):0x0000:"4b":"505341004b455900000000000100000001100800010000000413000600000000010000004b"
+
+PSA storage save: alg2: RSA_PSS_ANY_SALT(RIPEMD160)
+depends_on:PSA_WANT_ALG_RIPEMD160:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_RIPEMD160):"4c":"505341004b455900000000000100000001100800010000000000000004130006010000004c"
+
+PSA storage save: alg: RSA_PSS_ANY_SALT(SHA_1)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_ALG_SHA_1:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_1):0x0000:"4b":"505341004b455900000000000100000001100800010000000513000600000000010000004b"
+
+PSA storage save: alg2: RSA_PSS_ANY_SALT(SHA_1)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_ALG_SHA_1:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_1):"4c":"505341004b455900000000000100000001100800010000000000000005130006010000004c"
+
+PSA storage save: alg: RSA_PSS_ANY_SALT(SHA_224)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_224):0x0000:"4b":"505341004b455900000000000100000001100800010000000813000600000000010000004b"
+
+PSA storage save: alg2: RSA_PSS_ANY_SALT(SHA_224)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_224):"4c":"505341004b455900000000000100000001100800010000000000000008130006010000004c"
+
+PSA storage save: alg: RSA_PSS_ANY_SALT(SHA_256)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):0x0000:"4b":"505341004b455900000000000100000001100800010000000913000600000000010000004b"
+
+PSA storage save: alg2: RSA_PSS_ANY_SALT(SHA_256)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):"4c":"505341004b455900000000000100000001100800010000000000000009130006010000004c"
+
+PSA storage save: alg: RSA_PSS_ANY_SALT(SHA_384)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_ALG_SHA_384:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_384):0x0000:"4b":"505341004b455900000000000100000001100800010000000a13000600000000010000004b"
+
+PSA storage save: alg2: RSA_PSS_ANY_SALT(SHA_384)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_ALG_SHA_384:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_384):"4c":"505341004b45590000000000010000000110080001000000000000000a130006010000004c"
+
+PSA storage save: alg: RSA_PSS_ANY_SALT(SHA_512)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_ALG_SHA_512:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_512):0x0000:"4b":"505341004b455900000000000100000001100800010000000b13000600000000010000004b"
+
+PSA storage save: alg2: RSA_PSS_ANY_SALT(SHA_512)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_ALG_SHA_512:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_512):"4c":"505341004b45590000000000010000000110080001000000000000000b130006010000004c"
+
+PSA storage save: alg: RSA_PSS_ANY_SALT(ANY_HASH)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH):0x0000:"4b":"505341004b45590000000000010000000110080001000000ff13000600000000010000004b"
+
+PSA storage save: alg2: RSA_PSS_ANY_SALT(ANY_HASH)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH):"4c":"505341004b4559000000000001000000011008000100000000000000ff130006010000004c"
+
 PSA storage save: alg: SHA3_224
 depends_on:PSA_WANT_ALG_SHA3_224:PSA_WANT_KEY_TYPE_RAW_DATA
 key_storage_save:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_SHA3_224:0x0000:"4b":"505341004b455900000000000100000001100800010000001000000200000000010000004b"
diff --git a/tests/suites/test_suite_psa_crypto_storage_format.v0.data b/tests/suites/test_suite_psa_crypto_storage_format.v0.data
index 3dedaf1..c6be0a9 100644
--- a/tests/suites/test_suite_psa_crypto_storage_format.v0.data
+++ b/tests/suites/test_suite_psa_crypto_storage_format.v0.data
@@ -200,6 +200,18 @@
 depends_on:PSA_WANT_KEY_TYPE_ARC4
 key_storage_read:0x0001:PSA_KEY_TYPE_ARC4:2048:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a064617461":"505341004b4559000000000001000000022000080100000000000000000000000001000048657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a06461746148657265006973206b6579a064617461":TEST_FLAG_EXERCISE
 
+PSA storage read: type: ARIA 128-bit
+depends_on:PSA_WANT_KEY_TYPE_ARIA
+key_storage_read:0x0001:PSA_KEY_TYPE_ARIA:128:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a064617461":"505341004b4559000000000001000000062480000100000000000000000000001000000048657265006973206b6579a064617461":TEST_FLAG_EXERCISE
+
+PSA storage read: type: ARIA 192-bit
+depends_on:PSA_WANT_KEY_TYPE_ARIA
+key_storage_read:0x0001:PSA_KEY_TYPE_ARIA:192:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a0646174614865726500697320":"505341004b45590000000000010000000624c0000100000000000000000000001800000048657265006973206b6579a0646174614865726500697320":TEST_FLAG_EXERCISE
+
+PSA storage read: type: ARIA 256-bit
+depends_on:PSA_WANT_KEY_TYPE_ARIA
+key_storage_read:0x0001:PSA_KEY_TYPE_ARIA:256:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a06461746148657265006973206b6579a064617461":"505341004b4559000000000001000000062400010100000000000000000000002000000048657265006973206b6579a06461746148657265006973206b6579a064617461":TEST_FLAG_EXERCISE
+
 PSA storage read: type: CAMELLIA 128-bit
 depends_on:PSA_WANT_KEY_TYPE_CAMELLIA
 key_storage_read:0x0001:PSA_KEY_TYPE_CAMELLIA:128:PSA_KEY_USAGE_EXPORT:0x0000:0x0000:"48657265006973206b6579a064617461":"505341004b4559000000000001000000032480000100000000000000000000001000000048657265006973206b6579a064617461":TEST_FLAG_EXERCISE
@@ -1632,6 +1644,86 @@
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_KEY_TYPE_RAW_DATA
 key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH):"4c":"505341004b4559000000000001000000011008000100000000000000ff030006010000004c":0
 
+PSA storage read: alg: RSA_PSS_ANY_SALT(MD2)
+depends_on:PSA_WANT_ALG_MD2:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_MD2):0x0000:"4b":"505341004b455900000000000100000001100800010000000113000600000000010000004b":0
+
+PSA storage read: alg2: RSA_PSS_ANY_SALT(MD2)
+depends_on:PSA_WANT_ALG_MD2:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_MD2):"4c":"505341004b455900000000000100000001100800010000000000000001130006010000004c":0
+
+PSA storage read: alg: RSA_PSS_ANY_SALT(MD4)
+depends_on:PSA_WANT_ALG_MD4:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_MD4):0x0000:"4b":"505341004b455900000000000100000001100800010000000213000600000000010000004b":0
+
+PSA storage read: alg2: RSA_PSS_ANY_SALT(MD4)
+depends_on:PSA_WANT_ALG_MD4:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_MD4):"4c":"505341004b455900000000000100000001100800010000000000000002130006010000004c":0
+
+PSA storage read: alg: RSA_PSS_ANY_SALT(MD5)
+depends_on:PSA_WANT_ALG_MD5:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_MD5):0x0000:"4b":"505341004b455900000000000100000001100800010000000313000600000000010000004b":0
+
+PSA storage read: alg2: RSA_PSS_ANY_SALT(MD5)
+depends_on:PSA_WANT_ALG_MD5:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_MD5):"4c":"505341004b455900000000000100000001100800010000000000000003130006010000004c":0
+
+PSA storage read: alg: RSA_PSS_ANY_SALT(RIPEMD160)
+depends_on:PSA_WANT_ALG_RIPEMD160:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_RIPEMD160):0x0000:"4b":"505341004b455900000000000100000001100800010000000413000600000000010000004b":0
+
+PSA storage read: alg2: RSA_PSS_ANY_SALT(RIPEMD160)
+depends_on:PSA_WANT_ALG_RIPEMD160:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_RIPEMD160):"4c":"505341004b455900000000000100000001100800010000000000000004130006010000004c":0
+
+PSA storage read: alg: RSA_PSS_ANY_SALT(SHA_1)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_ALG_SHA_1:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_1):0x0000:"4b":"505341004b455900000000000100000001100800010000000513000600000000010000004b":0
+
+PSA storage read: alg2: RSA_PSS_ANY_SALT(SHA_1)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_ALG_SHA_1:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_1):"4c":"505341004b455900000000000100000001100800010000000000000005130006010000004c":0
+
+PSA storage read: alg: RSA_PSS_ANY_SALT(SHA_224)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_224):0x0000:"4b":"505341004b455900000000000100000001100800010000000813000600000000010000004b":0
+
+PSA storage read: alg2: RSA_PSS_ANY_SALT(SHA_224)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_224):"4c":"505341004b455900000000000100000001100800010000000000000008130006010000004c":0
+
+PSA storage read: alg: RSA_PSS_ANY_SALT(SHA_256)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):0x0000:"4b":"505341004b455900000000000100000001100800010000000913000600000000010000004b":0
+
+PSA storage read: alg2: RSA_PSS_ANY_SALT(SHA_256)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):"4c":"505341004b455900000000000100000001100800010000000000000009130006010000004c":0
+
+PSA storage read: alg: RSA_PSS_ANY_SALT(SHA_384)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_ALG_SHA_384:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_384):0x0000:"4b":"505341004b455900000000000100000001100800010000000a13000600000000010000004b":0
+
+PSA storage read: alg2: RSA_PSS_ANY_SALT(SHA_384)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_ALG_SHA_384:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_384):"4c":"505341004b45590000000000010000000110080001000000000000000a130006010000004c":0
+
+PSA storage read: alg: RSA_PSS_ANY_SALT(SHA_512)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_ALG_SHA_512:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_512):0x0000:"4b":"505341004b455900000000000100000001100800010000000b13000600000000010000004b":0
+
+PSA storage read: alg2: RSA_PSS_ANY_SALT(SHA_512)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_ALG_SHA_512:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_512):"4c":"505341004b45590000000000010000000110080001000000000000000b130006010000004c":0
+
+PSA storage read: alg: RSA_PSS_ANY_SALT(ANY_HASH)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH):0x0000:"4b":"505341004b45590000000000010000000110080001000000ff13000600000000010000004b":0
+
+PSA storage read: alg2: RSA_PSS_ANY_SALT(ANY_HASH)
+depends_on:PSA_WANT_ALG_RSA_PSS_ANY_SALT:PSA_WANT_KEY_TYPE_RAW_DATA
+key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0x0000:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH):"4c":"505341004b4559000000000001000000011008000100000000000000ff130006010000004c":0
+
 PSA storage read: alg: SHA3_224
 depends_on:PSA_WANT_ALG_SHA3_224:PSA_WANT_KEY_TYPE_RAW_DATA
 key_storage_read:0x0001:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:PSA_ALG_SHA3_224:0x0000:"4b":"505341004b455900000000000100000001100800010000001000000200000000010000004b":0
diff --git a/visualc/VS2010/load_roots.vcxproj b/visualc/VS2010/load_roots.vcxproj
new file mode 100644
index 0000000..1eed657
--- /dev/null
+++ b/visualc/VS2010/load_roots.vcxproj
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="utf-8"?>

+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+  <ItemGroup Label="ProjectConfigurations">

+    <ProjectConfiguration Include="Debug|Win32">

+      <Configuration>Debug</Configuration>

+      <Platform>Win32</Platform>

+    </ProjectConfiguration>

+    <ProjectConfiguration Include="Debug|x64">

+      <Configuration>Debug</Configuration>

+      <Platform>x64</Platform>

+    </ProjectConfiguration>

+    <ProjectConfiguration Include="Release|Win32">

+      <Configuration>Release</Configuration>

+      <Platform>Win32</Platform>

+    </ProjectConfiguration>

+    <ProjectConfiguration Include="Release|x64">

+      <Configuration>Release</Configuration>

+      <Platform>x64</Platform>

+    </ProjectConfiguration>

+  </ItemGroup>

+  <ItemGroup>

+    <ClCompile Include="..\..\programs\x509\load_roots.c" />

+  </ItemGroup>

+  <ItemGroup>

+    <ProjectReference Include="mbedTLS.vcxproj">

+      <Project>{46cf2d25-6a36-4189-b59c-e4815388e554}</Project>

+      <LinkLibraryDependencies>true</LinkLibraryDependencies>

+    </ProjectReference>

+  </ItemGroup>

+  <PropertyGroup Label="Globals">

+    <ProjectGuid>{65EB85E6-C928-689F-8335-126F78025220}</ProjectGuid>

+    <Keyword>Win32Proj</Keyword>

+    <RootNamespace>load_roots</RootNamespace>

+  </PropertyGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseDebugLibraries>true</UseDebugLibraries>

+    <CharacterSet>Unicode</CharacterSet>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseDebugLibraries>true</UseDebugLibraries>

+    <CharacterSet>Unicode</CharacterSet>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseDebugLibraries>false</UseDebugLibraries>

+    <WholeProgramOptimization>true</WholeProgramOptimization>

+    <CharacterSet>Unicode</CharacterSet>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseDebugLibraries>false</UseDebugLibraries>

+    <WholeProgramOptimization>true</WholeProgramOptimization>

+    <CharacterSet>Unicode</CharacterSet>

+  </PropertyGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

+  <ImportGroup Label="ExtensionSettings">

+  </ImportGroup>

+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+  </ImportGroup>

+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+  </ImportGroup>

+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+  </ImportGroup>

+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+  </ImportGroup>

+  <PropertyGroup Label="UserMacros" />

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

+    <LinkIncremental>true</LinkIncremental>

+    <IntDir>$(Configuration)\$(TargetName)\</IntDir>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

+    <LinkIncremental>true</LinkIncremental>

+    <IntDir>$(Configuration)\$(TargetName)\</IntDir>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

+    <LinkIncremental>false</LinkIncremental>

+    <IntDir>$(Configuration)\$(TargetName)\</IntDir>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

+    <LinkIncremental>false</LinkIncremental>

+    <IntDir>$(Configuration)\$(TargetName)\</IntDir>

+  </PropertyGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

+    <ClCompile>

+      <WarningLevel>Level3</WarningLevel>

+      <Optimization>Disabled</Optimization>

+      <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <AdditionalIncludeDirectories>

+../../include;../../3rdparty/everest/include/;../../3rdparty/everest/include/everest;../../3rdparty/everest/include/everest/vs2010;../../3rdparty/everest/include/everest/kremlib;../../tests/include      </AdditionalIncludeDirectories>

+    </ClCompile>

+    <Link>

+      <SubSystem>Console</SubSystem>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>

+      <AdditionalLibraryDirectories>Debug</AdditionalLibraryDirectories>

+    </Link>

+    <ProjectReference>

+      <LinkLibraryDependencies>false</LinkLibraryDependencies>

+    </ProjectReference>

+  </ItemDefinitionGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

+    <ClCompile>

+      <WarningLevel>Level3</WarningLevel>

+      <Optimization>Disabled</Optimization>

+      <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <AdditionalIncludeDirectories>

+../../include;../../3rdparty/everest/include/;../../3rdparty/everest/include/everest;../../3rdparty/everest/include/everest/vs2010;../../3rdparty/everest/include/everest/kremlib;../../tests/include      </AdditionalIncludeDirectories>

+    </ClCompile>

+    <Link>

+      <SubSystem>Console</SubSystem>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>

+      <AdditionalLibraryDirectories>Debug</AdditionalLibraryDirectories>

+    </Link>

+    <ProjectReference>

+      <LinkLibraryDependencies>false</LinkLibraryDependencies>

+    </ProjectReference>

+  </ItemDefinitionGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

+    <ClCompile>

+      <WarningLevel>Level3</WarningLevel>

+      <Optimization>MaxSpeed</Optimization>

+      <FunctionLevelLinking>true</FunctionLevelLinking>

+      <IntrinsicFunctions>true</IntrinsicFunctions>

+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <AdditionalIncludeDirectories>

+../../include;../../3rdparty/everest/include/;../../3rdparty/everest/include/everest;../../3rdparty/everest/include/everest/vs2010;../../3rdparty/everest/include/everest/kremlib;../../tests/include      </AdditionalIncludeDirectories>

+    </ClCompile>

+    <Link>

+      <SubSystem>Console</SubSystem>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+      <EnableCOMDATFolding>true</EnableCOMDATFolding>

+      <OptimizeReferences>true</OptimizeReferences>

+      <AdditionalLibraryDirectories>Release</AdditionalLibraryDirectories>

+      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>

+    </Link>

+  </ItemDefinitionGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

+    <ClCompile>

+      <WarningLevel>Level3</WarningLevel>

+      <Optimization>MaxSpeed</Optimization>

+      <FunctionLevelLinking>true</FunctionLevelLinking>

+      <IntrinsicFunctions>true</IntrinsicFunctions>

+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <AdditionalIncludeDirectories>

+../../include;../../3rdparty/everest/include/;../../3rdparty/everest/include/everest;../../3rdparty/everest/include/everest/vs2010;../../3rdparty/everest/include/everest/kremlib;../../tests/include      </AdditionalIncludeDirectories>

+    </ClCompile>

+    <Link>

+      <SubSystem>Console</SubSystem>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+      <EnableCOMDATFolding>true</EnableCOMDATFolding>

+      <OptimizeReferences>true</OptimizeReferences>

+      <AdditionalLibraryDirectories>Release</AdditionalLibraryDirectories>

+      <AdditionalDependencies>%(AdditionalDependencies);</AdditionalDependencies>

+    </Link>

+  </ItemDefinitionGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+  <ImportGroup Label="ExtensionTargets">

+  </ImportGroup>

+</Project>

diff --git a/visualc/VS2010/mbedTLS.sln b/visualc/VS2010/mbedTLS.sln
index d1e884e..3624735 100644
--- a/visualc/VS2010/mbedTLS.sln
+++ b/visualc/VS2010/mbedTLS.sln
@@ -253,6 +253,11 @@
 		{46CF2D25-6A36-4189-B59C-E4815388E554} = {46CF2D25-6A36-4189-B59C-E4815388E554}

 	EndProjectSection

 EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "load_roots", "load_roots.vcxproj", "{65EB85E6-C928-689F-8335-126F78025220}"

+	ProjectSection(ProjectDependencies) = postProject

+		{46CF2D25-6A36-4189-B59C-E4815388E554} = {46CF2D25-6A36-4189-B59C-E4815388E554}

+	EndProjectSection

+EndProject

 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "req_app", "req_app.vcxproj", "{486B1375-5CFA-C2D2-DD89-C9F497BADCB3}"

 	ProjectSection(ProjectDependencies) = postProject

 		{46CF2D25-6A36-4189-B59C-E4815388E554} = {46CF2D25-6A36-4189-B59C-E4815388E554}

@@ -674,6 +679,14 @@
 		{DB904B85-AD31-B7FB-114F-88760CC485F2}.Release|Win32.Build.0 = Release|Win32

 		{DB904B85-AD31-B7FB-114F-88760CC485F2}.Release|x64.ActiveCfg = Release|x64

 		{DB904B85-AD31-B7FB-114F-88760CC485F2}.Release|x64.Build.0 = Release|x64

+		{65EB85E6-C928-689F-8335-126F78025220}.Debug|Win32.ActiveCfg = Debug|Win32

+		{65EB85E6-C928-689F-8335-126F78025220}.Debug|Win32.Build.0 = Debug|Win32

+		{65EB85E6-C928-689F-8335-126F78025220}.Debug|x64.ActiveCfg = Debug|x64

+		{65EB85E6-C928-689F-8335-126F78025220}.Debug|x64.Build.0 = Debug|x64

+		{65EB85E6-C928-689F-8335-126F78025220}.Release|Win32.ActiveCfg = Release|Win32

+		{65EB85E6-C928-689F-8335-126F78025220}.Release|Win32.Build.0 = Release|Win32

+		{65EB85E6-C928-689F-8335-126F78025220}.Release|x64.ActiveCfg = Release|x64

+		{65EB85E6-C928-689F-8335-126F78025220}.Release|x64.Build.0 = Release|x64

 		{486B1375-5CFA-C2D2-DD89-C9F497BADCB3}.Debug|Win32.ActiveCfg = Debug|Win32

 		{486B1375-5CFA-C2D2-DD89-C9F497BADCB3}.Debug|Win32.Build.0 = Debug|Win32

 		{486B1375-5CFA-C2D2-DD89-C9F497BADCB3}.Debug|x64.ActiveCfg = Debug|x64

diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj
index cd68bb0..5d5b1d3 100644
--- a/visualc/VS2010/mbedTLS.vcxproj
+++ b/visualc/VS2010/mbedTLS.vcxproj
@@ -253,6 +253,7 @@
     <ClInclude Include="..\..\tests\include\test\drivers\signature.h" />

     <ClInclude Include="..\..\tests\include\test\drivers\size.h" />

     <ClInclude Include="..\..\tests\include\test\drivers\test_driver.h" />

+    <ClInclude Include="..\..\library\base64_invasive.h" />

     <ClInclude Include="..\..\library\check_crypto_config.h" />

     <ClInclude Include="..\..\library\common.h" />

     <ClInclude Include="..\..\library\ecp_invasive.h" />