Merge pull request #10287 from davidhorstmann-arm/update-4.x-lts-timeline-3.6

[Backport 3.6] Update note about the first 4.x LTS
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c981ef7..c3eb9c1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -40,12 +40,12 @@
 if(TEST_CPP)
     project("Mbed TLS"
         LANGUAGES C CXX
-        VERSION 3.6.3
+        VERSION 3.6.4
     )
 else()
     project("Mbed TLS"
         LANGUAGES C
-        VERSION 3.6.3
+        VERSION 3.6.4
     )
 endif()
 
@@ -476,7 +476,7 @@
     write_basic_package_version_file(
         "cmake/MbedTLSConfigVersion.cmake"
             COMPATIBILITY SameMajorVersion
-            VERSION 3.6.3)
+            VERSION 3.6.4)
 
     install(
         FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfig.cmake"
diff --git a/ChangeLog b/ChangeLog
index 5cadd2b..4d4bbdb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,115 @@
 Mbed TLS ChangeLog (Sorted per branch, date)
 
+= Mbed TLS 3.6.4 branch released 2025-06-30
+
+Features
+   * Add the function mbedtls_ssl_export_keying_material() which allows the
+     client and server to extract additional shared symmetric keys from an SSL
+     session, according to the TLS-Exporter specification in RFC 8446 and 5705.
+     This requires MBEDTLS_SSL_KEYING_MATERIAL_EXPORT to be defined in
+     mbedtls_config.h.
+
+Security
+   * Fix a buffer overread in mbedtls_lms_import_public_key() when the input is
+     less than 3 bytes. Reported by Linh Le and Ngan Nguyen from Calif.
+     CVE-2025-49601
+   * Fix a vulnerability in LMS verification through which an adversary could
+     get an invalid signature accepted if they could cause a hash accelerator
+     to fail. Found and reported by Linh Le and Ngan Nguyen from Calif.
+     CVE-2025-49600
+   * On x86/amd64 platforms, with some compilers, when the library is
+     compiled with support for both AESNI and software AES and AESNI is
+     available in hardware, an adversary with fine control over which
+     threads make progress in a multithreaded program could force software
+     AES to be used for some time when the program starts. This could allow
+     the adversary to conduct timing attacks and potentially recover the
+     key. In particular, this attacker model may be possible against an SGX
+     enclave.
+     The same vulnerability affects GCM acceleration, which could allow
+     a similarly powerful adversary to craft GCM forgeries.
+     CVE-2025-52496
+   * Fix possible use-after-free or double-free in code calling
+     mbedtls_x509_string_to_names(). This was caused by the function calling
+     mbedtls_asn1_free_named_data_list() on its head argument, while the
+     documentation did no suggest it did, making it likely for callers relying
+     on the documented behaviour to still hold pointers to memory blocks after
+     they were free()d, resulting in high risk of use-after-free or double-free,
+     with consequences ranging up to arbitrary code execution.
+     In particular, the two sample programs x509/cert_write and x509/cert_req
+     were affected (use-after-free if the san string contains more than one DN).
+     Code that does not call mbedtls_string_to_names() directly is not affected.
+     Found by Linh Le and Ngan Nguyen from Calif.
+     CVE-2025-47917
+   * Fix a bug in mbedtls_asn1_store_named_data() where it would sometimes leave
+     an item in the output list in an inconsistent state with val.p == NULL but
+     val.len > 0. This impacts applications that call this function directly,
+     or indirectly via mbedtls_x509_string_to_names() or one of the
+     mbedtls_x509write_{crt,csr}_set_{subject,issuer}_name() functions. The
+     inconsistent state of the output could then cause a NULL dereference either
+     inside the same call to mbedtls_x509_string_to_names(), or in subsequent
+     users of the output structure, such as mbedtls_x509_write_names(). This
+     only affects applications that create (as opposed to consume) X.509
+     certificates, CSRs or CRLs, or that call mbedtls_asn1_store_named_data()
+     directly. Found by Linh Le and Ngan Nguyen from Calif.
+     CVE-2025-48965
+   * Fix an integer underflow that could occur when parsing malformed PEM
+     keys, which could be used by an attacker capable of feeding encrypted
+     PEM keys to a user. This could cause a crash or information disclosure.
+     Found and reported by Linh Le and Ngan Nguyen from Calif.
+     CVE-2025-52497
+   * Fix a timing side channel in the implementation of PKCS#7 padding
+     which would allow an attacker who can request decryption of arbitrary
+     ciphertexts to recover the plaintext through a timing oracle attack.
+     Reported by Ka Lok Wu from Stony Brook University and Doria Tang from
+     The Chinese University of Hong Kong.
+     CVE-2025-49087
+
+Bugfix
+   * Fix failures of PSA multipart or interruptible operations when the
+     library or the application is built with a compiler where
+     "union foo x = {0}" does not initialize non-default members of the
+     union, such as GCC 15 and some versions of Clang 18. This affected MAC
+     multipart operations, MAC-based key derivation operations, interruptible
+     signature, interruptible verification, and potentially other operations
+     when using third-party drivers. This also affected one-shot MAC
+     operations using the built-in implementation. Fixes #9814.
+   * On entry to PSA driver entry points that set up a multipart operation
+     ("xxx_setup"), the operation object is supposed to be all-bits-zero.
+     This was sometimes not the case when an operation object is reused,
+     or with compilers where "union foo x = {0}" does not initialize
+     non-default members of the union. The PSA core now ensures that this
+     guarantee is met in all cases. Fixes #9975.
+   * Resolved build issue with C++ projects using Mbed TLS 3.6 when compiling
+     with the MSVC toolset v142 and earlier. Fixes mbedtls issue #7087.
+   * Silence spurious -Wunterminated-string-initialization warnings introduced
+     by GCC 15. Fixes #9944.
+   * Fix a sloppy check in LMS public key import, which could lead to accepting
+     keys with a different LMS or LM-OTS types on some platforms. Specifically,
+     this could happen on platforms where enum types are smaller than 32 bits
+     and compiler optimization is enabled. Found and reported by Linh Le and
+     Ngan Nguyen from Calif.
+   * Fix a race condition on x86/amd64 platforms in AESNI support detection
+     that could lead to using software AES in some threads at the very
+     beginning of a multithreaded program. Reported by Solar Designer.
+     Fixes #9840.
+   * Fix mbedtls_base64_decode() on inputs that did not have the correct
+     number of trailing equal signs, or had 4*k+1 digits. They were accepted
+     as long as they had at most two trailing equal signs. They are now
+     rejected. Furthermore, before, on inputs with too few equal signs, the
+     function reported the correct size in *olen when it returned
+     MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL, but truncated the output to the
+     last multiple of 3 bytes.
+   * When calling mbedtls_asn1_write_raw_buffer() with NULL, 0 as the last two
+     arguments, undefined behaviour would be triggered, in the form of a call to
+     memcpy(..., NULL, 0). This was harmless in practice, but could trigger
+     complains from sanitizers or static analyzers.
+
+Changes
+   * The function mbedtls_x509_string_to_names() now requires its head argument
+     to point to NULL on entry. This makes it likely that existing risky uses of
+     this function (see the entry in the Security section) will be detected and
+     fixed.
+
 = Mbed TLS 3.6.3 branch released 2025-03-24
 
 Default behavior changes
diff --git a/ChangeLog.d/add-tls-exporter.txt b/ChangeLog.d/add-tls-exporter.txt
deleted file mode 100644
index 1aea653..0000000
--- a/ChangeLog.d/add-tls-exporter.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Features
-   * Add the function mbedtls_ssl_export_keying_material() which allows the
-     client and server to extract additional shared symmetric keys from an SSL
-     session, according to the TLS-Exporter specification in RFC 8446 and 5705.
-     This requires MBEDTLS_SSL_KEYING_MATERIAL_EXPORT to be defined in
-     mbedtls_config.h.
diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h
index f903d3f..200db75 100644
--- a/doxygen/input/doc_mainpage.h
+++ b/doxygen/input/doc_mainpage.h
@@ -10,7 +10,7 @@
  */
 
 /**
- * @mainpage Mbed TLS v3.6.3 API Documentation
+ * @mainpage Mbed TLS v3.6.4 API Documentation
  *
  * This documentation describes the internal structure of Mbed TLS.  It was
  * automatically generated from specially formatted comment blocks in
diff --git a/doxygen/mbedtls.doxyfile b/doxygen/mbedtls.doxyfile
index 0acead9..2918f45 100644
--- a/doxygen/mbedtls.doxyfile
+++ b/doxygen/mbedtls.doxyfile
@@ -1,4 +1,4 @@
-PROJECT_NAME           = "Mbed TLS v3.6.3"
+PROJECT_NAME           = "Mbed TLS v3.6.4"
 OUTPUT_DIRECTORY       = ../apidoc/
 FULL_PATH_NAMES        = NO
 OPTIMIZE_OUTPUT_FOR_C  = YES
diff --git a/framework b/framework
index 1e7b5d5..2a3e2c5 160000
--- a/framework
+++ b/framework
@@ -1 +1 @@
-Subproject commit 1e7b5d54d3823b65fd4755bcf60f9ca39cfcbca3
+Subproject commit 2a3e2c5ea053c14b745dbdf41f609b1edc6a72fa
diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h
index 8367cd3..1e1c063 100644
--- a/include/mbedtls/bignum.h
+++ b/include/mbedtls/bignum.h
@@ -12,6 +12,7 @@
 #include "mbedtls/private_access.h"
 
 #include "mbedtls/build_info.h"
+#include "mbedtls/platform_util.h"
 
 #include <stddef.h>
 #include <stdint.h>
@@ -928,7 +929,7 @@
  *                 be relevant in applications like deterministic ECDSA.
  */
 int mbedtls_mpi_fill_random(mbedtls_mpi *X, size_t size,
-                            int (*f_rng)(void *, unsigned char *, size_t),
+                            mbedtls_f_rng_t *f_rng,
                             void *p_rng);
 
 /** Generate a random number uniformly in a range.
@@ -966,7 +967,7 @@
 int mbedtls_mpi_random(mbedtls_mpi *X,
                        mbedtls_mpi_sint min,
                        const mbedtls_mpi *N,
-                       int (*f_rng)(void *, unsigned char *, size_t),
+                       mbedtls_f_rng_t *f_rng,
                        void *p_rng);
 
 /**
@@ -1030,7 +1031,7 @@
  * \return         Another negative error code on other kinds of failure.
  */
 int mbedtls_mpi_is_prime_ext(const mbedtls_mpi *X, int rounds,
-                             int (*f_rng)(void *, unsigned char *, size_t),
+                             mbedtls_f_rng_t *f_rng,
                              void *p_rng);
 /**
  * \brief Flags for mbedtls_mpi_gen_prime()
@@ -1063,7 +1064,7 @@
  *                 \c 3 and #MBEDTLS_MPI_MAX_BITS.
  */
 int mbedtls_mpi_gen_prime(mbedtls_mpi *X, size_t nbits, int flags,
-                          int (*f_rng)(void *, unsigned char *, size_t),
+                          mbedtls_f_rng_t *f_rng,
                           void *p_rng);
 
 #if defined(MBEDTLS_SELF_TEST)
diff --git a/include/mbedtls/build_info.h b/include/mbedtls/build_info.h
index e70c4d7..e18e823 100644
--- a/include/mbedtls/build_info.h
+++ b/include/mbedtls/build_info.h
@@ -26,16 +26,16 @@
  */
 #define MBEDTLS_VERSION_MAJOR  3
 #define MBEDTLS_VERSION_MINOR  6
-#define MBEDTLS_VERSION_PATCH  3
+#define MBEDTLS_VERSION_PATCH  4
 
 /**
  * The single version number has the following structure:
  *    MMNNPP00
  *    Major version | Minor version | Patch version
  */
-#define MBEDTLS_VERSION_NUMBER         0x03060300
-#define MBEDTLS_VERSION_STRING         "3.6.3"
-#define MBEDTLS_VERSION_STRING_FULL    "Mbed TLS 3.6.3"
+#define MBEDTLS_VERSION_NUMBER         0x03060400
+#define MBEDTLS_VERSION_STRING         "3.6.4"
+#define MBEDTLS_VERSION_STRING_FULL    "Mbed TLS 3.6.4"
 
 /* Macros for build-time platform detection */
 
diff --git a/include/mbedtls/dhm.h b/include/mbedtls/dhm.h
index fcba3d2..bbfe6ea 100644
--- a/include/mbedtls/dhm.h
+++ b/include/mbedtls/dhm.h
@@ -183,7 +183,7 @@
  */
 int mbedtls_dhm_make_params(mbedtls_dhm_context *ctx, int x_size,
                             unsigned char *output, size_t *olen,
-                            int (*f_rng)(void *, unsigned char *, size_t),
+                            mbedtls_f_rng_t *f_rng,
                             void *p_rng);
 
 /**
@@ -250,7 +250,7 @@
  */
 int mbedtls_dhm_make_public(mbedtls_dhm_context *ctx, int x_size,
                             unsigned char *output, size_t olen,
-                            int (*f_rng)(void *, unsigned char *, size_t),
+                            mbedtls_f_rng_t *f_rng,
                             void *p_rng);
 
 /**
@@ -281,7 +281,7 @@
  */
 int mbedtls_dhm_calc_secret(mbedtls_dhm_context *ctx,
                             unsigned char *output, size_t output_size, size_t *olen,
-                            int (*f_rng)(void *, unsigned char *, size_t),
+                            mbedtls_f_rng_t *f_rng,
                             void *p_rng);
 
 /**
diff --git a/include/mbedtls/ecdh.h b/include/mbedtls/ecdh.h
index a6a5069..a919ad2 100644
--- a/include/mbedtls/ecdh.h
+++ b/include/mbedtls/ecdh.h
@@ -189,7 +189,7 @@
  *                  \c MBEDTLS_MPI_XXX error code on failure.
  */
 int mbedtls_ecdh_gen_public(mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
-                            int (*f_rng)(void *, unsigned char *, size_t),
+                            mbedtls_f_rng_t *f_rng,
                             void *p_rng);
 
 /**
@@ -225,7 +225,7 @@
  */
 int mbedtls_ecdh_compute_shared(mbedtls_ecp_group *grp, mbedtls_mpi *z,
                                 const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
-                                int (*f_rng)(void *, unsigned char *, size_t),
+                                mbedtls_f_rng_t *f_rng,
                                 void *p_rng);
 
 /**
@@ -290,7 +290,7 @@
  */
 int mbedtls_ecdh_make_params(mbedtls_ecdh_context *ctx, size_t *olen,
                              unsigned char *buf, size_t blen,
-                             int (*f_rng)(void *, unsigned char *, size_t),
+                             mbedtls_f_rng_t *f_rng,
                              void *p_rng);
 
 /**
@@ -372,7 +372,7 @@
  */
 int mbedtls_ecdh_make_public(mbedtls_ecdh_context *ctx, size_t *olen,
                              unsigned char *buf, size_t blen,
-                             int (*f_rng)(void *, unsigned char *, size_t),
+                             mbedtls_f_rng_t *f_rng,
                              void *p_rng);
 
 /**
@@ -428,7 +428,7 @@
  */
 int mbedtls_ecdh_calc_secret(mbedtls_ecdh_context *ctx, size_t *olen,
                              unsigned char *buf, size_t blen,
-                             int (*f_rng)(void *, unsigned char *, size_t),
+                             mbedtls_f_rng_t *f_rng,
                              void *p_rng);
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
diff --git a/include/mbedtls/ecdsa.h b/include/mbedtls/ecdsa.h
index 2ecf349..c161661 100644
--- a/include/mbedtls/ecdsa.h
+++ b/include/mbedtls/ecdsa.h
@@ -150,7 +150,8 @@
  *                  buffer of length \p blen Bytes. It may be \c NULL if
  *                  \p blen is zero.
  * \param blen      The length of \p buf in Bytes.
- * \param f_rng     The RNG function. This must not be \c NULL.
+ * \param f_rng     The RNG function, used both to generate the ECDSA nonce
+ *                  and for blinding. This must not be \c NULL.
  * \param p_rng     The RNG context to be passed to \p f_rng. This may be
  *                  \c NULL if \p f_rng doesn't need a context parameter.
  *
@@ -160,7 +161,7 @@
  */
 int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
                        const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
-                       int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+                       mbedtls_f_rng_t *f_rng, void *p_rng);
 
 #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
 /**
@@ -207,7 +208,7 @@
                                mbedtls_mpi *s, const mbedtls_mpi *d,
                                const unsigned char *buf, size_t blen,
                                mbedtls_md_type_t md_alg,
-                               int (*f_rng_blind)(void *, unsigned char *, size_t),
+                               mbedtls_f_rng_t *f_rng_blind,
                                void *p_rng_blind);
 #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
 
@@ -247,7 +248,8 @@
  *                      buffer of length \p blen Bytes. It may be \c NULL if
  *                      \p blen is zero.
  * \param blen          The length of \p buf in Bytes.
- * \param f_rng         The RNG function. This must not be \c NULL.
+ * \param f_rng         The RNG function used to generate the ECDSA nonce.
+ *                      This must not be \c NULL.
  * \param p_rng         The RNG context to be passed to \p f_rng. This may be
  *                      \c NULL if \p f_rng doesn't need a context parameter.
  * \param f_rng_blind   The RNG function used for blinding. This must not be
@@ -271,9 +273,9 @@
     mbedtls_mpi *r, mbedtls_mpi *s,
     const mbedtls_mpi *d,
     const unsigned char *buf, size_t blen,
-    int (*f_rng)(void *, unsigned char *, size_t),
+    mbedtls_f_rng_t *f_rng,
     void *p_rng,
-    int (*f_rng_blind)(void *, unsigned char *, size_t),
+    mbedtls_f_rng_t *f_rng_blind,
     void *p_rng_blind,
     mbedtls_ecdsa_restart_ctx *rs_ctx);
 
@@ -334,7 +336,7 @@
     mbedtls_mpi *r, mbedtls_mpi *s,
     const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
     mbedtls_md_type_t md_alg,
-    int (*f_rng_blind)(void *, unsigned char *, size_t),
+    mbedtls_f_rng_t *f_rng_blind,
     void *p_rng_blind,
     mbedtls_ecdsa_restart_ctx *rs_ctx);
 
@@ -458,10 +460,10 @@
  * \param sig_size  The size of the \p sig buffer in bytes.
  * \param slen      The address at which to store the actual length of
  *                  the signature written. Must not be \c NULL.
- * \param f_rng     The RNG function. This must not be \c NULL if
- *                  #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
- *                  it is used only for blinding and may be set to \c NULL, but
- *                  doing so is DEPRECATED.
+ * \param f_rng     The RNG function. This is used for blinding.
+ *                  If #MBEDTLS_ECDSA_DETERMINISTIC is unset, this is also
+ *                  used to generate the ECDSA nonce.
+ *                  This must not be \c NULL.
  * \param p_rng     The RNG context to be passed to \p f_rng. This may be
  *                  \c NULL if \p f_rng is \c NULL or doesn't use a context.
  *
@@ -473,7 +475,7 @@
                                   mbedtls_md_type_t md_alg,
                                   const unsigned char *hash, size_t hlen,
                                   unsigned char *sig, size_t sig_size, size_t *slen,
-                                  int (*f_rng)(void *, unsigned char *, size_t),
+                                  mbedtls_f_rng_t *f_rng,
                                   void *p_rng);
 
 /**
@@ -501,9 +503,10 @@
  * \param sig_size  The size of the \p sig buffer in bytes.
  * \param slen      The address at which to store the actual length of
  *                  the signature written. Must not be \c NULL.
- * \param f_rng     The RNG function. This must not be \c NULL if
- *                  #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
- *                  it is unused and may be set to \c NULL.
+ * \param f_rng     The RNG function. This is used for blinding.
+ *                  If #MBEDTLS_ECDSA_DETERMINISTIC is unset, this is also
+ *                  used to generate the ECDSA nonce.
+ *                  This must not be \c NULL.
  * \param p_rng     The RNG context to be passed to \p f_rng. This may be
  *                  \c NULL if \p f_rng is \c NULL or doesn't use a context.
  * \param rs_ctx    The restart context to use. This may be \c NULL to disable
@@ -520,7 +523,7 @@
                                               mbedtls_md_type_t md_alg,
                                               const unsigned char *hash, size_t hlen,
                                               unsigned char *sig, size_t sig_size, size_t *slen,
-                                              int (*f_rng)(void *, unsigned char *, size_t),
+                                              mbedtls_f_rng_t *f_rng,
                                               void *p_rng,
                                               mbedtls_ecdsa_restart_ctx *rs_ctx);
 
@@ -608,7 +611,7 @@
  * \return         An \c MBEDTLS_ERR_ECP_XXX code on failure.
  */
 int mbedtls_ecdsa_genkey(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
-                         int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+                         mbedtls_f_rng_t *f_rng, void *p_rng);
 
 /**
  * \brief           This function sets up an ECDSA context from an EC key pair.
diff --git a/include/mbedtls/ecjpake.h b/include/mbedtls/ecjpake.h
index c2148a2..7da8cb4 100644
--- a/include/mbedtls/ecjpake.h
+++ b/include/mbedtls/ecjpake.h
@@ -162,7 +162,7 @@
  */
 int mbedtls_ecjpake_write_round_one(mbedtls_ecjpake_context *ctx,
                                     unsigned char *buf, size_t len, size_t *olen,
-                                    int (*f_rng)(void *, unsigned char *, size_t),
+                                    mbedtls_f_rng_t *f_rng,
                                     void *p_rng);
 
 /**
@@ -203,7 +203,7 @@
  */
 int mbedtls_ecjpake_write_round_two(mbedtls_ecjpake_context *ctx,
                                     unsigned char *buf, size_t len, size_t *olen,
-                                    int (*f_rng)(void *, unsigned char *, size_t),
+                                    mbedtls_f_rng_t *f_rng,
                                     void *p_rng);
 
 /**
@@ -243,7 +243,7 @@
  */
 int mbedtls_ecjpake_derive_secret(mbedtls_ecjpake_context *ctx,
                                   unsigned char *buf, size_t len, size_t *olen,
-                                  int (*f_rng)(void *, unsigned char *, size_t),
+                                  mbedtls_f_rng_t *f_rng,
                                   void *p_rng);
 
 /**
@@ -266,7 +266,7 @@
  */
 int mbedtls_ecjpake_write_shared_key(mbedtls_ecjpake_context *ctx,
                                      unsigned char *buf, size_t len, size_t *olen,
-                                     int (*f_rng)(void *, unsigned char *, size_t),
+                                     mbedtls_f_rng_t *f_rng,
                                      void *p_rng);
 
 /**
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index 623910b..5cc0271 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -966,7 +966,7 @@
  */
 int mbedtls_ecp_mul(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
                     const mbedtls_mpi *m, const mbedtls_ecp_point *P,
-                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+                    mbedtls_f_rng_t *f_rng, void *p_rng);
 
 /**
  * \brief           This function performs multiplication of a point by
@@ -1000,7 +1000,7 @@
  */
 int mbedtls_ecp_mul_restartable(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
                                 const mbedtls_mpi *m, const mbedtls_ecp_point *P,
-                                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+                                mbedtls_f_rng_t *f_rng, void *p_rng,
                                 mbedtls_ecp_restart_ctx *rs_ctx);
 
 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
@@ -1179,7 +1179,7 @@
  */
 int mbedtls_ecp_gen_privkey(const mbedtls_ecp_group *grp,
                             mbedtls_mpi *d,
-                            int (*f_rng)(void *, unsigned char *, size_t),
+                            mbedtls_f_rng_t *f_rng,
                             void *p_rng);
 
 /**
@@ -1212,7 +1212,7 @@
 int mbedtls_ecp_gen_keypair_base(mbedtls_ecp_group *grp,
                                  const mbedtls_ecp_point *G,
                                  mbedtls_mpi *d, mbedtls_ecp_point *Q,
-                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 mbedtls_f_rng_t *f_rng,
                                  void *p_rng);
 
 /**
@@ -1240,7 +1240,7 @@
  */
 int mbedtls_ecp_gen_keypair(mbedtls_ecp_group *grp, mbedtls_mpi *d,
                             mbedtls_ecp_point *Q,
-                            int (*f_rng)(void *, unsigned char *, size_t),
+                            mbedtls_f_rng_t *f_rng,
                             void *p_rng);
 
 /**
@@ -1257,7 +1257,7 @@
  *                  on failure.
  */
 int mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
-                        int (*f_rng)(void *, unsigned char *, size_t),
+                        mbedtls_f_rng_t *f_rng,
                         void *p_rng);
 
 /** \brief          Set the public key in a key pair object.
@@ -1451,7 +1451,7 @@
  */
 int mbedtls_ecp_check_pub_priv(
     const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv,
-    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+    mbedtls_f_rng_t *f_rng, void *p_rng);
 
 /** \brief          Calculate the public key from a private key in a key pair.
  *
@@ -1468,7 +1468,7 @@
  */
 int mbedtls_ecp_keypair_calc_public(
     mbedtls_ecp_keypair *key,
-    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+    mbedtls_f_rng_t *f_rng, void *p_rng);
 
 /** \brief          Query the group that a key pair belongs to.
  *
diff --git a/include/mbedtls/lms.h b/include/mbedtls/lms.h
index 95fce21..2f29791 100644
--- a/include/mbedtls/lms.h
+++ b/include/mbedtls/lms.h
@@ -364,7 +364,7 @@
 int mbedtls_lms_generate_private_key(mbedtls_lms_private_t *ctx,
                                      mbedtls_lms_algorithm_type_t type,
                                      mbedtls_lmots_algorithm_type_t otstype,
-                                     int (*f_rng)(void *, unsigned char *, size_t),
+                                     mbedtls_f_rng_t *f_rng,
                                      void *p_rng, const unsigned char *seed,
                                      size_t seed_size);
 
@@ -427,7 +427,7 @@
  * \return         A non-zero error code on failure.
  */
 int mbedtls_lms_sign(mbedtls_lms_private_t *ctx,
-                     int (*f_rng)(void *, unsigned char *, size_t),
+                     mbedtls_f_rng_t *f_rng,
                      void *p_rng, const unsigned char *msg,
                      unsigned int msg_size, unsigned char *sig, size_t sig_size,
                      size_t *sig_len);
diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h
index 52f4cc6..2b7f34b 100644
--- a/include/mbedtls/pk.h
+++ b/include/mbedtls/pk.h
@@ -285,7 +285,7 @@
                                                const unsigned char *input, unsigned char *output,
                                                size_t output_max_len);
 typedef int (*mbedtls_pk_rsa_alt_sign_func)(void *ctx,
-                                            int (*f_rng)(void *, unsigned char *, size_t),
+                                            mbedtls_f_rng_t *f_rng,
                                             void *p_rng,
                                             mbedtls_md_type_t md_alg, unsigned int hashlen,
                                             const unsigned char *hash, unsigned char *sig);
@@ -849,7 +849,7 @@
 int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
                     const unsigned char *hash, size_t hash_len,
                     unsigned char *sig, size_t sig_size, size_t *sig_len,
-                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+                    mbedtls_f_rng_t *f_rng, void *p_rng);
 
 /**
  * \brief           Make signature given a signature type.
@@ -885,7 +885,7 @@
                         mbedtls_md_type_t md_alg,
                         const unsigned char *hash, size_t hash_len,
                         unsigned char *sig, size_t sig_size, size_t *sig_len,
-                        int (*f_rng)(void *, unsigned char *, size_t),
+                        mbedtls_f_rng_t *f_rng,
                         void *p_rng);
 
 /**
@@ -921,7 +921,7 @@
                                 mbedtls_md_type_t md_alg,
                                 const unsigned char *hash, size_t hash_len,
                                 unsigned char *sig, size_t sig_size, size_t *sig_len,
-                                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+                                mbedtls_f_rng_t *f_rng, void *p_rng,
                                 mbedtls_pk_restart_ctx *rs_ctx);
 
 /**
@@ -947,7 +947,7 @@
 int mbedtls_pk_decrypt(mbedtls_pk_context *ctx,
                        const unsigned char *input, size_t ilen,
                        unsigned char *output, size_t *olen, size_t osize,
-                       int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+                       mbedtls_f_rng_t *f_rng, void *p_rng);
 
 /**
  * \brief           Encrypt message (including padding if relevant).
@@ -973,7 +973,7 @@
 int mbedtls_pk_encrypt(mbedtls_pk_context *ctx,
                        const unsigned char *input, size_t ilen,
                        unsigned char *output, size_t *olen, size_t osize,
-                       int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+                       mbedtls_f_rng_t *f_rng, void *p_rng);
 
 /**
  * \brief           Check if a public-private pair of keys matches.
@@ -991,7 +991,7 @@
  */
 int mbedtls_pk_check_pair(const mbedtls_pk_context *pub,
                           const mbedtls_pk_context *prv,
-                          int (*f_rng)(void *, unsigned char *, size_t),
+                          mbedtls_f_rng_t *f_rng,
                           void *p_rng);
 
 /**
@@ -1109,7 +1109,7 @@
 int mbedtls_pk_parse_key(mbedtls_pk_context *ctx,
                          const unsigned char *key, size_t keylen,
                          const unsigned char *pwd, size_t pwdlen,
-                         int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+                         mbedtls_f_rng_t *f_rng, void *p_rng);
 
 /** \ingroup pk_module */
 /**
@@ -1173,7 +1173,7 @@
  */
 int mbedtls_pk_parse_keyfile(mbedtls_pk_context *ctx,
                              const char *path, const char *password,
-                             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+                             mbedtls_f_rng_t *f_rng, void *p_rng);
 
 /** \ingroup pk_module */
 /**
diff --git a/include/mbedtls/platform_util.h b/include/mbedtls/platform_util.h
index 1b371ef..adad6bc 100644
--- a/include/mbedtls/platform_util.h
+++ b/include/mbedtls/platform_util.h
@@ -159,6 +159,56 @@
 void mbedtls_platform_zeroize(void *buf, size_t len);
 #endif
 
+/** \brief              The type of custom random generator (RNG) callbacks.
+ *
+ *                      Many Mbed TLS functions take two parameters
+ *                      `mbedtls_f_rng_t *f_rng, void *p_rng`. The
+ *                      library will call \c f_rng to generate
+ *                      random values.
+ *
+ * \note                This is typically one of the following:
+ *                      - mbedtls_ctr_drbg_random() with \c p_rng
+ *                        pointing to a #mbedtls_ctr_drbg_context;
+ *                      - mbedtls_hmac_drbg_random() with \c p_rng
+ *                        pointing to a #mbedtls_hmac_drbg_context;
+ *                      - mbedtls_psa_get_random() with
+ *                        `prng = MBEDTLS_PSA_RANDOM_STATE`.
+ *
+ * \note                Generally, given a call
+ *                      `mbedtls_foo(f_rng, p_rng, ....)`, the RNG callback
+ *                      and the context only need to remain valid until
+ *                      the call to `mbedtls_foo` returns. However, there
+ *                      are a few exceptions where the callback is stored
+ *                      in for future use. Check the documentation of
+ *                      the calling function.
+ *
+ * \warning             In a multithreaded environment, calling the
+ *                      function should be thread-safe. The standard
+ *                      functions provided by the library are thread-safe
+ *                      when #MBEDTLS_THREADING_C is enabled.
+ *
+ * \warning             This function must either provide as many
+ *                      bytes as requested of **cryptographic quality**
+ *                      random data, or return a negative error code.
+ *
+ * \param p_rng         The \c p_rng argument that was passed along \c f_rng.
+ *                      The library always passes \c p_rng unchanged.
+ *                      This is typically a pointer to the random generator
+ *                      state, or \c NULL if the custom random generator
+ *                      doesn't need a context-specific state.
+ * \param[out] output   On success, this must be filled with \p output_size
+ *                      bytes of cryptographic-quality random data.
+ * \param output_size   The number of bytes to output.
+ *
+ * \return              \c 0 on success, or a negative error code on failure.
+ *                      Library functions will generally propagate this
+ *                      error code, so \c MBEDTLS_ERR_xxx values are
+ *                      recommended. #MBEDTLS_ERR_ENTROPY_SOURCE_FAILED is
+ *                      typically sensible for RNG failures.
+ */
+typedef int mbedtls_f_rng_t(void *p_rng,
+                            unsigned char *output, size_t output_size);
+
 #if defined(MBEDTLS_HAVE_TIME_DATE)
 /**
  * \brief      Platform-specific implementation of gmtime_r()
diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h
index c1e76b3..3f0881a 100644
--- a/include/mbedtls/rsa.h
+++ b/include/mbedtls/rsa.h
@@ -465,7 +465,7 @@
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_gen_key(mbedtls_rsa_context *ctx,
-                        int (*f_rng)(void *, unsigned char *, size_t),
+                        mbedtls_f_rng_t *f_rng,
                         void *p_rng,
                         unsigned int nbits, int exponent);
 
@@ -590,7 +590,7 @@
  *
  */
 int mbedtls_rsa_private(mbedtls_rsa_context *ctx,
-                        int (*f_rng)(void *, unsigned char *, size_t),
+                        mbedtls_f_rng_t *f_rng,
                         void *p_rng,
                         const unsigned char *input,
                         unsigned char *output);
@@ -619,7 +619,7 @@
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_pkcs1_encrypt(mbedtls_rsa_context *ctx,
-                              int (*f_rng)(void *, unsigned char *, size_t),
+                              mbedtls_f_rng_t *f_rng,
                               void *p_rng,
                               size_t ilen,
                               const unsigned char *input,
@@ -646,7 +646,7 @@
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsaes_pkcs1_v15_encrypt(mbedtls_rsa_context *ctx,
-                                        int (*f_rng)(void *, unsigned char *, size_t),
+                                        mbedtls_f_rng_t *f_rng,
                                         void *p_rng,
                                         size_t ilen,
                                         const unsigned char *input,
@@ -680,7 +680,7 @@
  * \return           An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsaes_oaep_encrypt(mbedtls_rsa_context *ctx,
-                                   int (*f_rng)(void *, unsigned char *, size_t),
+                                   mbedtls_f_rng_t *f_rng,
                                    void *p_rng,
                                    const unsigned char *label, size_t label_len,
                                    size_t ilen,
@@ -723,7 +723,7 @@
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_pkcs1_decrypt(mbedtls_rsa_context *ctx,
-                              int (*f_rng)(void *, unsigned char *, size_t),
+                              mbedtls_f_rng_t *f_rng,
                               void *p_rng,
                               size_t *olen,
                               const unsigned char *input,
@@ -765,7 +765,7 @@
  *
  */
 int mbedtls_rsa_rsaes_pkcs1_v15_decrypt(mbedtls_rsa_context *ctx,
-                                        int (*f_rng)(void *, unsigned char *, size_t),
+                                        mbedtls_f_rng_t *f_rng,
                                         void *p_rng,
                                         size_t *olen,
                                         const unsigned char *input,
@@ -806,7 +806,7 @@
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsaes_oaep_decrypt(mbedtls_rsa_context *ctx,
-                                   int (*f_rng)(void *, unsigned char *, size_t),
+                                   mbedtls_f_rng_t *f_rng,
                                    void *p_rng,
                                    const unsigned char *label, size_t label_len,
                                    size_t *olen,
@@ -849,7 +849,7 @@
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_pkcs1_sign(mbedtls_rsa_context *ctx,
-                           int (*f_rng)(void *, unsigned char *, size_t),
+                           mbedtls_f_rng_t *f_rng,
                            void *p_rng,
                            mbedtls_md_type_t md_alg,
                            unsigned int hashlen,
@@ -881,7 +881,7 @@
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsassa_pkcs1_v15_sign(mbedtls_rsa_context *ctx,
-                                      int (*f_rng)(void *, unsigned char *, size_t),
+                                      mbedtls_f_rng_t *f_rng,
                                       void *p_rng,
                                       mbedtls_md_type_t md_alg,
                                       unsigned int hashlen,
@@ -933,7 +933,7 @@
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsassa_pss_sign_ext(mbedtls_rsa_context *ctx,
-                                    int (*f_rng)(void *, unsigned char *, size_t),
+                                    mbedtls_f_rng_t *f_rng,
                                     void *p_rng,
                                     mbedtls_md_type_t md_alg,
                                     unsigned int hashlen,
@@ -983,7 +983,7 @@
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx,
-                                int (*f_rng)(void *, unsigned char *, size_t),
+                                mbedtls_f_rng_t *f_rng,
                                 void *p_rng,
                                 mbedtls_md_type_t md_alg,
                                 unsigned int hashlen,
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index cc9da34..3cdddf7 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -2255,12 +2255,16 @@
 /**
  * \brief          Set the random number generator callback
  *
+ * \note           The callback with its parameter must remain valid as
+ *                 long as there is an SSL context that uses the
+ *                 SSL configuration.
+ *
  * \param conf     SSL configuration
  * \param f_rng    RNG function (mandatory)
  * \param p_rng    RNG parameter
  */
 void mbedtls_ssl_conf_rng(mbedtls_ssl_config *conf,
-                          int (*f_rng)(void *, unsigned char *, size_t),
+                          mbedtls_f_rng_t *f_rng,
                           void *p_rng);
 
 /**
diff --git a/include/mbedtls/ssl_cookie.h b/include/mbedtls/ssl_cookie.h
index 71c258e..0f211e6 100644
--- a/include/mbedtls/ssl_cookie.h
+++ b/include/mbedtls/ssl_cookie.h
@@ -70,7 +70,7 @@
  * \brief          Setup cookie context (generate keys)
  */
 int mbedtls_ssl_cookie_setup(mbedtls_ssl_cookie_ctx *ctx,
-                             int (*f_rng)(void *, unsigned char *, size_t),
+                             mbedtls_f_rng_t *f_rng,
                              void *p_rng);
 
 /**
diff --git a/include/mbedtls/ssl_ticket.h b/include/mbedtls/ssl_ticket.h
index 2ee1400..9f7e440 100644
--- a/include/mbedtls/ssl_ticket.h
+++ b/include/mbedtls/ssl_ticket.h
@@ -98,7 +98,9 @@
  *
  * \param ctx       Context to be set up
  * \param f_rng     RNG callback function (mandatory)
- * \param p_rng     RNG callback context
+ * \param p_rng     RNG callback context.
+ *                  Note that the RNG callback must remain valid
+ *                  until the ticket context is freed.
  * \param cipher    AEAD cipher to use for ticket protection.
  *                  Recommended value: MBEDTLS_CIPHER_AES_256_GCM.
  * \param lifetime  Tickets lifetime in seconds
@@ -122,7 +124,7 @@
  *                  or a specific MBEDTLS_ERR_XXX error code
  */
 int mbedtls_ssl_ticket_setup(mbedtls_ssl_ticket_context *ctx,
-                             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+                             mbedtls_f_rng_t *f_rng, void *p_rng,
                              mbedtls_cipher_type_t cipher,
                              uint32_t lifetime);
 
diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h
index 453f598..6b10461 100644
--- a/include/mbedtls/x509.h
+++ b/include/mbedtls/x509.h
@@ -332,7 +332,8 @@
  *                   call to mbedtls_asn1_free_named_data_list().
  *
  * \param[out] head  Address in which to store the pointer to the head of the
- *                   allocated list of mbedtls_x509_name
+ *                   allocated list of mbedtls_x509_name. Must point to NULL on
+ *                   entry.
  * \param[in] name   The string representation of a DN to convert
  *
  * \return           0 on success, or a negative error code.
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index 1ce0d23..6b96039 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -1176,7 +1176,7 @@
  * \note            \p f_rng is used for the signature operation.
  */
 int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size,
-                              int (*f_rng)(void *, unsigned char *, size_t),
+                              mbedtls_f_rng_t *f_rng,
                               void *p_rng);
 
 #if defined(MBEDTLS_PEM_WRITE_C)
@@ -1194,7 +1194,7 @@
  * \note            \p f_rng is used for the signature operation.
  */
 int mbedtls_x509write_crt_pem(mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size,
-                              int (*f_rng)(void *, unsigned char *, size_t),
+                              mbedtls_f_rng_t *f_rng,
                               void *p_rng);
 #endif /* MBEDTLS_PEM_WRITE_C */
 #endif /* MBEDTLS_X509_CRT_WRITE_C */
diff --git a/include/mbedtls/x509_csr.h b/include/mbedtls/x509_csr.h
index 8c31c09..c4bd7f1 100644
--- a/include/mbedtls/x509_csr.h
+++ b/include/mbedtls/x509_csr.h
@@ -349,7 +349,7 @@
  * \note            \p f_rng is used for the signature operation.
  */
 int mbedtls_x509write_csr_der(mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
-                              int (*f_rng)(void *, unsigned char *, size_t),
+                              mbedtls_f_rng_t *f_rng,
                               void *p_rng);
 
 #if defined(MBEDTLS_PEM_WRITE_C)
@@ -368,7 +368,7 @@
  * \note            \p f_rng is used for the signature operation.
  */
 int mbedtls_x509write_csr_pem(mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
-                              int (*f_rng)(void *, unsigned char *, size_t),
+                              mbedtls_f_rng_t *f_rng,
                               void *p_rng);
 #endif /* MBEDTLS_PEM_WRITE_C */
 #endif /* MBEDTLS_X509_CSR_WRITE_C */
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 2bbcea3..2fe9f35 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -59,6 +59,18 @@
  * of integral types defined in "crypto_types.h". */
 #include "crypto_values.h"
 
+/* The file "crypto_sizes.h" contains definitions for size calculation
+ * macros whose definitions are implementation-specific. */
+#include "crypto_sizes.h"
+
+/* The file "crypto_struct.h" contains definitions for
+ * implementation-specific structs that are declared above. */
+#if defined(MBEDTLS_PSA_CRYPTO_STRUCT_FILE)
+#include MBEDTLS_PSA_CRYPTO_STRUCT_FILE
+#else
+#include "crypto_struct.h"
+#endif
+
 /** \defgroup initialization Library initialization
  * @{
  */
@@ -4958,18 +4970,6 @@
 }
 #endif
 
-/* The file "crypto_sizes.h" contains definitions for size calculation
- * macros whose definitions are implementation-specific. */
-#include "crypto_sizes.h"
-
-/* The file "crypto_struct.h" contains definitions for
- * implementation-specific structs that are declared above. */
-#if defined(MBEDTLS_PSA_CRYPTO_STRUCT_FILE)
-#include MBEDTLS_PSA_CRYPTO_STRUCT_FILE
-#else
-#include "crypto_struct.h"
-#endif
-
 /* The file "crypto_extra.h" contains vendor-specific definitions. This
  * can include vendor-defined algorithms, extra functions, etc. */
 #include "crypto_extra.h"
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index a046ba5..7074090 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -952,6 +952,208 @@
  */
 #define PSA_PAKE_STEP_ZK_PROOF                  ((psa_pake_step_t) 0x03)
 
+/**@}*/
+
+/** A sufficient output buffer size for psa_pake_output().
+ *
+ * If the size of the output buffer is at least this large, it is guaranteed
+ * that psa_pake_output() will not fail due to an insufficient output buffer
+ * size. The actual size of the output might be smaller in any given call.
+ *
+ * See also #PSA_PAKE_OUTPUT_MAX_SIZE
+ *
+ * \param alg           A PAKE algorithm (\c PSA_ALG_XXX value such that
+ *                      #PSA_ALG_IS_PAKE(\p alg) is true).
+ * \param primitive     A primitive of type ::psa_pake_primitive_t that is
+ *                      compatible with algorithm \p alg.
+ * \param output_step   A value of type ::psa_pake_step_t that is valid for the
+ *                      algorithm \p alg.
+ * \return              A sufficient output buffer size for the specified
+ *                      PAKE algorithm, primitive, and output step. If the
+ *                      PAKE algorithm, primitive, or output step is not
+ *                      recognized, or the parameters are incompatible,
+ *                      return 0.
+ */
+#define PSA_PAKE_OUTPUT_SIZE(alg, primitive, output_step)               \
+    (alg == PSA_ALG_JPAKE &&                                           \
+     primitive == PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC,      \
+                                     PSA_ECC_FAMILY_SECP_R1, 256) ?    \
+     (                                                                 \
+         output_step == PSA_PAKE_STEP_KEY_SHARE ? 65 :                   \
+         output_step == PSA_PAKE_STEP_ZK_PUBLIC ? 65 :                   \
+         32                                                              \
+     ) :                                                               \
+     0)
+
+/** A sufficient input buffer size for psa_pake_input().
+ *
+ * The value returned by this macro is guaranteed to be large enough for any
+ * valid input to psa_pake_input() in an operation with the specified
+ * parameters.
+ *
+ * See also #PSA_PAKE_INPUT_MAX_SIZE
+ *
+ * \param alg           A PAKE algorithm (\c PSA_ALG_XXX value such that
+ *                      #PSA_ALG_IS_PAKE(\p alg) is true).
+ * \param primitive     A primitive of type ::psa_pake_primitive_t that is
+ *                      compatible with algorithm \p alg.
+ * \param input_step    A value of type ::psa_pake_step_t that is valid for the
+ *                      algorithm \p alg.
+ * \return              A sufficient input buffer size for the specified
+ *                      input, cipher suite and algorithm. If the cipher suite,
+ *                      the input type or PAKE algorithm is not recognized, or
+ *                      the parameters are incompatible, return 0.
+ */
+#define PSA_PAKE_INPUT_SIZE(alg, primitive, input_step)                 \
+    (alg == PSA_ALG_JPAKE &&                                           \
+     primitive == PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC,      \
+                                     PSA_ECC_FAMILY_SECP_R1, 256) ?    \
+     (                                                                 \
+         input_step == PSA_PAKE_STEP_KEY_SHARE ? 65 :                    \
+         input_step == PSA_PAKE_STEP_ZK_PUBLIC ? 65 :                    \
+         32                                                              \
+     ) :                                                               \
+     0)
+
+/** Output buffer size for psa_pake_output() for any of the supported PAKE
+ * algorithm and primitive suites and output step.
+ *
+ * This macro must expand to a compile-time constant integer.
+ *
+ * The value of this macro must be at least as large as the largest value
+ * returned by PSA_PAKE_OUTPUT_SIZE()
+ *
+ * See also #PSA_PAKE_OUTPUT_SIZE(\p alg, \p primitive, \p output_step).
+ */
+#define PSA_PAKE_OUTPUT_MAX_SIZE 65
+
+/** Input buffer size for psa_pake_input() for any of the supported PAKE
+ * algorithm and primitive suites and input step.
+ *
+ * This macro must expand to a compile-time constant integer.
+ *
+ * The value of this macro must be at least as large as the largest value
+ * returned by PSA_PAKE_INPUT_SIZE()
+ *
+ * See also #PSA_PAKE_INPUT_SIZE(\p alg, \p primitive, \p output_step).
+ */
+#define PSA_PAKE_INPUT_MAX_SIZE 65
+
+/** Returns a suitable initializer for a PAKE cipher suite object of type
+ * psa_pake_cipher_suite_t.
+ */
+#define PSA_PAKE_CIPHER_SUITE_INIT { PSA_ALG_NONE, 0, 0, 0, PSA_ALG_NONE }
+
+/** Returns a suitable initializer for a PAKE operation object of type
+ * psa_pake_operation_t.
+ */
+#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
+#define PSA_PAKE_OPERATION_INIT { 0 }
+#else
+#define PSA_PAKE_OPERATION_INIT { 0, PSA_ALG_NONE, 0, PSA_PAKE_OPERATION_STAGE_SETUP, \
+                                  { 0 }, { { 0 } } }
+#endif
+
+struct psa_pake_cipher_suite_s {
+    psa_algorithm_t algorithm;
+    psa_pake_primitive_type_t type;
+    psa_pake_family_t family;
+    uint16_t  bits;
+    psa_algorithm_t hash;
+};
+
+struct psa_crypto_driver_pake_inputs_s {
+    uint8_t *MBEDTLS_PRIVATE(password);
+    size_t MBEDTLS_PRIVATE(password_len);
+    uint8_t *MBEDTLS_PRIVATE(user);
+    size_t MBEDTLS_PRIVATE(user_len);
+    uint8_t *MBEDTLS_PRIVATE(peer);
+    size_t MBEDTLS_PRIVATE(peer_len);
+    psa_key_attributes_t MBEDTLS_PRIVATE(attributes);
+    struct psa_pake_cipher_suite_s MBEDTLS_PRIVATE(cipher_suite);
+};
+
+typedef enum psa_crypto_driver_pake_step {
+    PSA_JPAKE_STEP_INVALID        = 0,  /* Invalid step */
+    PSA_JPAKE_X1_STEP_KEY_SHARE   = 1,  /* Round 1: input/output key share (for ephemeral private key X1).*/
+    PSA_JPAKE_X1_STEP_ZK_PUBLIC   = 2,  /* Round 1: input/output Schnorr NIZKP public key for the X1 key */
+    PSA_JPAKE_X1_STEP_ZK_PROOF    = 3,  /* Round 1: input/output Schnorr NIZKP proof for the X1 key */
+    PSA_JPAKE_X2_STEP_KEY_SHARE   = 4,  /* Round 1: input/output key share (for ephemeral private key X2).*/
+    PSA_JPAKE_X2_STEP_ZK_PUBLIC   = 5,  /* Round 1: input/output Schnorr NIZKP public key for the X2 key */
+    PSA_JPAKE_X2_STEP_ZK_PROOF    = 6,  /* Round 1: input/output Schnorr NIZKP proof for the X2 key */
+    PSA_JPAKE_X2S_STEP_KEY_SHARE  = 7,  /* Round 2: output X2S key (our key) */
+    PSA_JPAKE_X2S_STEP_ZK_PUBLIC  = 8,  /* Round 2: output Schnorr NIZKP public key for the X2S key (our key) */
+    PSA_JPAKE_X2S_STEP_ZK_PROOF   = 9,  /* Round 2: output Schnorr NIZKP proof for the X2S key (our key) */
+    PSA_JPAKE_X4S_STEP_KEY_SHARE  = 10, /* Round 2: input X4S key (from peer) */
+    PSA_JPAKE_X4S_STEP_ZK_PUBLIC  = 11, /* Round 2: input Schnorr NIZKP public key for the X4S key (from peer) */
+    PSA_JPAKE_X4S_STEP_ZK_PROOF   = 12  /* Round 2: input Schnorr NIZKP proof for the X4S key (from peer) */
+} psa_crypto_driver_pake_step_t;
+
+typedef enum psa_jpake_round {
+    PSA_JPAKE_FIRST = 0,
+    PSA_JPAKE_SECOND = 1,
+    PSA_JPAKE_FINISHED = 2
+} psa_jpake_round_t;
+
+typedef enum psa_jpake_io_mode {
+    PSA_JPAKE_INPUT = 0,
+    PSA_JPAKE_OUTPUT = 1
+} psa_jpake_io_mode_t;
+
+struct psa_jpake_computation_stage_s {
+    /* The J-PAKE round we are currently on */
+    psa_jpake_round_t MBEDTLS_PRIVATE(round);
+    /* The 'mode' we are currently in (inputting or outputting) */
+    psa_jpake_io_mode_t MBEDTLS_PRIVATE(io_mode);
+    /* The number of completed inputs so far this round */
+    uint8_t MBEDTLS_PRIVATE(inputs);
+    /* The number of completed outputs so far this round */
+    uint8_t MBEDTLS_PRIVATE(outputs);
+    /* The next expected step (KEY_SHARE, ZK_PUBLIC or ZK_PROOF) */
+    psa_pake_step_t MBEDTLS_PRIVATE(step);
+};
+
+#define PSA_JPAKE_EXPECTED_INPUTS(round) ((round) == PSA_JPAKE_FINISHED ? 0 : \
+                                          ((round) == PSA_JPAKE_FIRST ? 2 : 1))
+#define PSA_JPAKE_EXPECTED_OUTPUTS(round) ((round) == PSA_JPAKE_FINISHED ? 0 : \
+                                           ((round) == PSA_JPAKE_FIRST ? 2 : 1))
+
+struct psa_pake_operation_s {
+#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
+    mbedtls_psa_client_handle_t handle;
+#else
+    /** Unique ID indicating which driver got assigned to do the
+     * operation. Since driver contexts are driver-specific, swapping
+     * drivers halfway through the operation is not supported.
+     * ID values are auto-generated in psa_crypto_driver_wrappers.h
+     * ID value zero means the context is not valid or not assigned to
+     * any driver (i.e. none of the driver contexts are active). */
+    unsigned int MBEDTLS_PRIVATE(id);
+    /* Algorithm of the PAKE operation */
+    psa_algorithm_t MBEDTLS_PRIVATE(alg);
+    /* A primitive of type compatible with algorithm */
+    psa_pake_primitive_t MBEDTLS_PRIVATE(primitive);
+    /* Stage of the PAKE operation: waiting for the setup, collecting inputs
+     * or computing. */
+    uint8_t MBEDTLS_PRIVATE(stage);
+    /* Holds computation stage of the PAKE algorithms. */
+    union {
+        uint8_t MBEDTLS_PRIVATE(dummy);
+#if defined(PSA_WANT_ALG_JPAKE)
+        struct psa_jpake_computation_stage_s MBEDTLS_PRIVATE(jpake);
+#endif
+    } MBEDTLS_PRIVATE(computation_stage);
+    union {
+        psa_driver_pake_context_t MBEDTLS_PRIVATE(ctx);
+        struct psa_crypto_driver_pake_inputs_s MBEDTLS_PRIVATE(inputs);
+    } MBEDTLS_PRIVATE(data);
+#endif
+};
+
+/** \addtogroup pake
+ * @{
+ */
+
 /** The type of the data structure for PAKE cipher suites.
  *
  * This is an implementation-defined \c struct. Applications should not
@@ -1654,114 +1856,6 @@
 
 /**@}*/
 
-/** A sufficient output buffer size for psa_pake_output().
- *
- * If the size of the output buffer is at least this large, it is guaranteed
- * that psa_pake_output() will not fail due to an insufficient output buffer
- * size. The actual size of the output might be smaller in any given call.
- *
- * See also #PSA_PAKE_OUTPUT_MAX_SIZE
- *
- * \param alg           A PAKE algorithm (\c PSA_ALG_XXX value such that
- *                      #PSA_ALG_IS_PAKE(\p alg) is true).
- * \param primitive     A primitive of type ::psa_pake_primitive_t that is
- *                      compatible with algorithm \p alg.
- * \param output_step   A value of type ::psa_pake_step_t that is valid for the
- *                      algorithm \p alg.
- * \return              A sufficient output buffer size for the specified
- *                      PAKE algorithm, primitive, and output step. If the
- *                      PAKE algorithm, primitive, or output step is not
- *                      recognized, or the parameters are incompatible,
- *                      return 0.
- */
-#define PSA_PAKE_OUTPUT_SIZE(alg, primitive, output_step)               \
-    (alg == PSA_ALG_JPAKE &&                                           \
-     primitive == PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC,      \
-                                     PSA_ECC_FAMILY_SECP_R1, 256) ?    \
-     (                                                                 \
-         output_step == PSA_PAKE_STEP_KEY_SHARE ? 65 :                   \
-         output_step == PSA_PAKE_STEP_ZK_PUBLIC ? 65 :                   \
-         32                                                              \
-     ) :                                                               \
-     0)
-
-/** A sufficient input buffer size for psa_pake_input().
- *
- * The value returned by this macro is guaranteed to be large enough for any
- * valid input to psa_pake_input() in an operation with the specified
- * parameters.
- *
- * See also #PSA_PAKE_INPUT_MAX_SIZE
- *
- * \param alg           A PAKE algorithm (\c PSA_ALG_XXX value such that
- *                      #PSA_ALG_IS_PAKE(\p alg) is true).
- * \param primitive     A primitive of type ::psa_pake_primitive_t that is
- *                      compatible with algorithm \p alg.
- * \param input_step    A value of type ::psa_pake_step_t that is valid for the
- *                      algorithm \p alg.
- * \return              A sufficient input buffer size for the specified
- *                      input, cipher suite and algorithm. If the cipher suite,
- *                      the input type or PAKE algorithm is not recognized, or
- *                      the parameters are incompatible, return 0.
- */
-#define PSA_PAKE_INPUT_SIZE(alg, primitive, input_step)                 \
-    (alg == PSA_ALG_JPAKE &&                                           \
-     primitive == PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC,      \
-                                     PSA_ECC_FAMILY_SECP_R1, 256) ?    \
-     (                                                                 \
-         input_step == PSA_PAKE_STEP_KEY_SHARE ? 65 :                    \
-         input_step == PSA_PAKE_STEP_ZK_PUBLIC ? 65 :                    \
-         32                                                              \
-     ) :                                                               \
-     0)
-
-/** Output buffer size for psa_pake_output() for any of the supported PAKE
- * algorithm and primitive suites and output step.
- *
- * This macro must expand to a compile-time constant integer.
- *
- * The value of this macro must be at least as large as the largest value
- * returned by PSA_PAKE_OUTPUT_SIZE()
- *
- * See also #PSA_PAKE_OUTPUT_SIZE(\p alg, \p primitive, \p output_step).
- */
-#define PSA_PAKE_OUTPUT_MAX_SIZE 65
-
-/** Input buffer size for psa_pake_input() for any of the supported PAKE
- * algorithm and primitive suites and input step.
- *
- * This macro must expand to a compile-time constant integer.
- *
- * The value of this macro must be at least as large as the largest value
- * returned by PSA_PAKE_INPUT_SIZE()
- *
- * See also #PSA_PAKE_INPUT_SIZE(\p alg, \p primitive, \p output_step).
- */
-#define PSA_PAKE_INPUT_MAX_SIZE 65
-
-/** Returns a suitable initializer for a PAKE cipher suite object of type
- * psa_pake_cipher_suite_t.
- */
-#define PSA_PAKE_CIPHER_SUITE_INIT { PSA_ALG_NONE, 0, 0, 0, PSA_ALG_NONE }
-
-/** Returns a suitable initializer for a PAKE operation object of type
- * psa_pake_operation_t.
- */
-#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
-#define PSA_PAKE_OPERATION_INIT { 0 }
-#else
-#define PSA_PAKE_OPERATION_INIT { 0, PSA_ALG_NONE, 0, PSA_PAKE_OPERATION_STAGE_SETUP, \
-                                  { 0 }, { { 0 } } }
-#endif
-
-struct psa_pake_cipher_suite_s {
-    psa_algorithm_t algorithm;
-    psa_pake_primitive_type_t type;
-    psa_pake_family_t family;
-    uint16_t  bits;
-    psa_algorithm_t hash;
-};
-
 static inline psa_algorithm_t psa_pake_cs_get_algorithm(
     const psa_pake_cipher_suite_t *cipher_suite)
 {
@@ -1823,94 +1917,6 @@
     }
 }
 
-struct psa_crypto_driver_pake_inputs_s {
-    uint8_t *MBEDTLS_PRIVATE(password);
-    size_t MBEDTLS_PRIVATE(password_len);
-    uint8_t *MBEDTLS_PRIVATE(user);
-    size_t MBEDTLS_PRIVATE(user_len);
-    uint8_t *MBEDTLS_PRIVATE(peer);
-    size_t MBEDTLS_PRIVATE(peer_len);
-    psa_key_attributes_t MBEDTLS_PRIVATE(attributes);
-    psa_pake_cipher_suite_t MBEDTLS_PRIVATE(cipher_suite);
-};
-
-typedef enum psa_crypto_driver_pake_step {
-    PSA_JPAKE_STEP_INVALID        = 0,  /* Invalid step */
-    PSA_JPAKE_X1_STEP_KEY_SHARE   = 1,  /* Round 1: input/output key share (for ephemeral private key X1).*/
-    PSA_JPAKE_X1_STEP_ZK_PUBLIC   = 2,  /* Round 1: input/output Schnorr NIZKP public key for the X1 key */
-    PSA_JPAKE_X1_STEP_ZK_PROOF    = 3,  /* Round 1: input/output Schnorr NIZKP proof for the X1 key */
-    PSA_JPAKE_X2_STEP_KEY_SHARE   = 4,  /* Round 1: input/output key share (for ephemeral private key X2).*/
-    PSA_JPAKE_X2_STEP_ZK_PUBLIC   = 5,  /* Round 1: input/output Schnorr NIZKP public key for the X2 key */
-    PSA_JPAKE_X2_STEP_ZK_PROOF    = 6,  /* Round 1: input/output Schnorr NIZKP proof for the X2 key */
-    PSA_JPAKE_X2S_STEP_KEY_SHARE  = 7,  /* Round 2: output X2S key (our key) */
-    PSA_JPAKE_X2S_STEP_ZK_PUBLIC  = 8,  /* Round 2: output Schnorr NIZKP public key for the X2S key (our key) */
-    PSA_JPAKE_X2S_STEP_ZK_PROOF   = 9,  /* Round 2: output Schnorr NIZKP proof for the X2S key (our key) */
-    PSA_JPAKE_X4S_STEP_KEY_SHARE  = 10, /* Round 2: input X4S key (from peer) */
-    PSA_JPAKE_X4S_STEP_ZK_PUBLIC  = 11, /* Round 2: input Schnorr NIZKP public key for the X4S key (from peer) */
-    PSA_JPAKE_X4S_STEP_ZK_PROOF   = 12  /* Round 2: input Schnorr NIZKP proof for the X4S key (from peer) */
-} psa_crypto_driver_pake_step_t;
-
-typedef enum psa_jpake_round {
-    PSA_JPAKE_FIRST = 0,
-    PSA_JPAKE_SECOND = 1,
-    PSA_JPAKE_FINISHED = 2
-} psa_jpake_round_t;
-
-typedef enum psa_jpake_io_mode {
-    PSA_JPAKE_INPUT = 0,
-    PSA_JPAKE_OUTPUT = 1
-} psa_jpake_io_mode_t;
-
-struct psa_jpake_computation_stage_s {
-    /* The J-PAKE round we are currently on */
-    psa_jpake_round_t MBEDTLS_PRIVATE(round);
-    /* The 'mode' we are currently in (inputting or outputting) */
-    psa_jpake_io_mode_t MBEDTLS_PRIVATE(io_mode);
-    /* The number of completed inputs so far this round */
-    uint8_t MBEDTLS_PRIVATE(inputs);
-    /* The number of completed outputs so far this round */
-    uint8_t MBEDTLS_PRIVATE(outputs);
-    /* The next expected step (KEY_SHARE, ZK_PUBLIC or ZK_PROOF) */
-    psa_pake_step_t MBEDTLS_PRIVATE(step);
-};
-
-#define PSA_JPAKE_EXPECTED_INPUTS(round) ((round) == PSA_JPAKE_FINISHED ? 0 : \
-                                          ((round) == PSA_JPAKE_FIRST ? 2 : 1))
-#define PSA_JPAKE_EXPECTED_OUTPUTS(round) ((round) == PSA_JPAKE_FINISHED ? 0 : \
-                                           ((round) == PSA_JPAKE_FIRST ? 2 : 1))
-
-struct psa_pake_operation_s {
-#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
-    mbedtls_psa_client_handle_t handle;
-#else
-    /** Unique ID indicating which driver got assigned to do the
-     * operation. Since driver contexts are driver-specific, swapping
-     * drivers halfway through the operation is not supported.
-     * ID values are auto-generated in psa_crypto_driver_wrappers.h
-     * ID value zero means the context is not valid or not assigned to
-     * any driver (i.e. none of the driver contexts are active). */
-    unsigned int MBEDTLS_PRIVATE(id);
-    /* Algorithm of the PAKE operation */
-    psa_algorithm_t MBEDTLS_PRIVATE(alg);
-    /* A primitive of type compatible with algorithm */
-    psa_pake_primitive_t MBEDTLS_PRIVATE(primitive);
-    /* Stage of the PAKE operation: waiting for the setup, collecting inputs
-     * or computing. */
-    uint8_t MBEDTLS_PRIVATE(stage);
-    /* Holds computation stage of the PAKE algorithms. */
-    union {
-        uint8_t MBEDTLS_PRIVATE(dummy);
-#if defined(PSA_WANT_ALG_JPAKE)
-        psa_jpake_computation_stage_t MBEDTLS_PRIVATE(jpake);
-#endif
-    } MBEDTLS_PRIVATE(computation_stage);
-    union {
-        psa_driver_pake_context_t MBEDTLS_PRIVATE(ctx);
-        psa_crypto_driver_pake_inputs_t MBEDTLS_PRIVATE(inputs);
-    } MBEDTLS_PRIVATE(data);
-#endif
-};
-
 static inline struct psa_pake_cipher_suite_s psa_pake_cipher_suite_init(void)
 {
     const struct psa_pake_cipher_suite_s v = PSA_PAKE_CIPHER_SUITE_INIT;
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index e2a1920..b2c21fa 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -300,7 +300,7 @@
 if(USE_SHARED_MBEDTLS_LIBRARY)
     set(CMAKE_LIBRARY_PATH ${CMAKE_CURRENT_BINARY_DIR})
     add_library(${mbedcrypto_target} SHARED ${src_crypto})
-    set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 3.6.3 SOVERSION 16)
+    set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 3.6.4 SOVERSION 16)
     target_link_libraries(${mbedcrypto_target} PUBLIC ${libs})
 
     if(TARGET ${everest_target})
@@ -312,11 +312,11 @@
     endif()
 
     add_library(${mbedx509_target} SHARED ${src_x509})
-    set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.6.3 SOVERSION 7)
+    set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.6.4 SOVERSION 7)
     target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${mbedcrypto_target})
 
     add_library(${mbedtls_target} SHARED ${src_tls})
-    set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.6.3 SOVERSION 21)
+    set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.6.4 SOVERSION 21)
     target_link_libraries(${mbedtls_target} PUBLIC ${libs} ${mbedx509_target})
 endif(USE_SHARED_MBEDTLS_LIBRARY)
 
diff --git a/library/aesni.c b/library/aesni.c
index 4fc1cb9..2857068 100644
--- a/library/aesni.c
+++ b/library/aesni.c
@@ -48,8 +48,19 @@
  */
 int mbedtls_aesni_has_support(unsigned int what)
 {
-    static int done = 0;
-    static unsigned int c = 0;
+    /* To avoid a race condition, tell the compiler that the assignment
+     * `done = 1` and the assignment to `c` may not be reordered.
+     * https://github.com/Mbed-TLS/mbedtls/issues/9840
+     *
+     * Note that we may also be worried about memory access reordering,
+     * but fortunately the x86 memory model is not too wild: stores
+     * from the same thread are observed consistently by other threads.
+     * (See example 8-1 in Sewell et al., "x86-TSO: A Rigorous and Usable
+     * Programmer’s Model for x86 Multiprocessors", CACM, 2010,
+     * https://www.cl.cam.ac.uk/~pes20/weakmemory/cacm.pdf)
+     */
+    static volatile int done = 0;
+    static volatile unsigned int c = 0;
 
     if (!done) {
 #if MBEDTLS_AESNI_HAVE_CODE == 2
diff --git a/library/asn1write.c b/library/asn1write.c
index 775a9ef..97f9db0 100644
--- a/library/asn1write.c
+++ b/library/asn1write.c
@@ -90,7 +90,9 @@
 
     len = size;
     (*p) -= len;
-    memcpy(*p, buf, len);
+    if (len != 0) {
+        memcpy(*p, buf, len);
+    }
 
     return (int) len;
 }
@@ -412,6 +414,7 @@
     } else if (val_len == 0) {
         mbedtls_free(cur->val.p);
         cur->val.p = NULL;
+        cur->val.len = 0;
     } else if (cur->val.len != val_len) {
         /*
          * Enlarge existing value buffer if needed
diff --git a/library/base64.c b/library/base64.c
index 9677dee..388fa9f 100644
--- a/library/base64.c
+++ b/library/base64.c
@@ -14,6 +14,7 @@
 #include "mbedtls/base64.h"
 #include "base64_internal.h"
 #include "constant_time_internal.h"
+#include "mbedtls/error.h"
 
 #include <stdint.h>
 
@@ -183,49 +184,72 @@
         n++;
     }
 
-    if (n == 0) {
-        *olen = 0;
-        return 0;
+    /* In valid base64, the number of digits (n-equals) is always of the form
+     * 4*k, 4*k+2 or *4k+3. Also, the number n of digits plus the number of
+     * equal signs at the end is always a multiple of 4. */
+    if ((n - equals) % 4 == 1) {
+        return MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
+    }
+    if (n % 4 != 0) {
+        return MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
     }
 
-    /* The following expression is to calculate the following formula without
-     * risk of integer overflow in n:
-     *     n = ( ( n * 6 ) + 7 ) >> 3;
+    /* We've determined that the input is valid, and that it contains
+     * exactly k blocks of digits-or-equals, with n = 4 * k,
+     * and equals only present at the end of the last block if at all.
+     * Now we can calculate the length of the output.
+     *
+     * Each block of 4 digits in the input map to 3 bytes of output.
+     * For the last block:
+     * - abcd (where abcd are digits) is a full 3-byte block;
+     * - abc= means 1 byte less than a full 3-byte block of output;
+     * - ab== means 2 bytes less than a full 3-byte block of output;
+     * - a==== and ==== is rejected above.
      */
-    n = (6 * (n >> 3)) + ((6 * (n & 0x7) + 7) >> 3);
-    n -= equals;
+    *olen = (n / 4) * 3 - equals;
 
-    if (dst == NULL || dlen < n) {
-        *olen = n;
+    /* If the output buffer is too small, signal this and stop here.
+     * Also, as documented, stop here if `dst` is null, independently of
+     * `dlen`.
+     *
+     * There is an edge case when the output is empty: in this case,
+     * `dlen == 0` with `dst == NULL` is valid (on some platforms,
+     * `malloc(0)` returns `NULL`). Since the call is valid, we return
+     * 0 in this case.
+     */
+    if ((*olen != 0 && dst == NULL) || dlen < *olen) {
         return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL;
     }
 
-    equals = 0;
     for (x = 0, p = dst; i > 0; i--, src++) {
         if (*src == '\r' || *src == '\n' || *src == ' ') {
             continue;
         }
-
-        x = x << 6;
         if (*src == '=') {
-            ++equals;
-        } else {
-            x |= mbedtls_ct_base64_dec_value(*src);
+            /* We already know from the first loop that equal signs are
+             * only at the end. */
+            break;
         }
+        x = x << 6;
+        x |= mbedtls_ct_base64_dec_value(*src);
 
         if (++accumulated_digits == 4) {
             accumulated_digits = 0;
             *p++ = MBEDTLS_BYTE_2(x);
-            if (equals <= 1) {
-                *p++ = MBEDTLS_BYTE_1(x);
-            }
-            if (equals <= 0) {
-                *p++ = MBEDTLS_BYTE_0(x);
-            }
+            *p++ = MBEDTLS_BYTE_1(x);
+            *p++ = MBEDTLS_BYTE_0(x);
         }
     }
+    if (accumulated_digits == 3) {
+        *p++ = MBEDTLS_BYTE_2(x << 6);
+        *p++ = MBEDTLS_BYTE_1(x << 6);
+    } else if (accumulated_digits == 2) {
+        *p++ = MBEDTLS_BYTE_2(x << 12);
+    }
 
-    *olen = (size_t) (p - dst);
+    if (*olen != (size_t) (p - dst)) {
+        return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    }
 
     return 0;
 }
diff --git a/library/cipher.c b/library/cipher.c
index 7f4c121..2ae01dd 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -14,6 +14,7 @@
 #if defined(MBEDTLS_CIPHER_C)
 
 #include "mbedtls/cipher.h"
+#include "cipher_invasive.h"
 #include "cipher_wrap.h"
 #include "mbedtls/platform_util.h"
 #include "mbedtls/error.h"
@@ -838,8 +839,14 @@
     }
 }
 
-static int get_pkcs_padding(unsigned char *input, size_t input_len,
-                            size_t *data_len)
+/*
+ * Get the length of the PKCS7 padding.
+ *
+ * Note: input_len must be the block size of the cipher.
+ */
+MBEDTLS_STATIC_TESTABLE int mbedtls_get_pkcs_padding(unsigned char *input,
+                                                     size_t input_len,
+                                                     size_t *data_len)
 {
     size_t i, pad_idx;
     unsigned char padding_len;
@@ -849,10 +856,6 @@
     }
 
     padding_len = input[input_len - 1];
-    if (padding_len == 0 || padding_len > input_len) {
-        return MBEDTLS_ERR_CIPHER_INVALID_PADDING;
-    }
-    *data_len = input_len - padding_len;
 
     mbedtls_ct_condition_t bad = mbedtls_ct_uint_gt(padding_len, input_len);
     bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0));
@@ -866,6 +869,9 @@
         bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool_and(in_padding, different));
     }
 
+    /* If the padding is invalid, set the output length to 0 */
+    *data_len = mbedtls_ct_if(bad, 0, input_len - padding_len);
+
     return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING);
 }
 #endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
@@ -1144,7 +1150,7 @@
 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
         case MBEDTLS_PADDING_PKCS7:
             ctx->add_padding = add_pkcs_padding;
-            ctx->get_padding = get_pkcs_padding;
+            ctx->get_padding = mbedtls_get_pkcs_padding;
             break;
 #endif
 #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
diff --git a/library/cipher_invasive.h b/library/cipher_invasive.h
new file mode 100644
index 0000000..702f8f7
--- /dev/null
+++ b/library/cipher_invasive.h
@@ -0,0 +1,27 @@
+/**
+ * \file cipher_invasive.h
+ *
+ * \brief Cipher 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 OR GPL-2.0-or-later
+ */
+#ifndef MBEDTLS_CIPHER_INVASIVE_H
+#define MBEDTLS_CIPHER_INVASIVE_H
+
+#include "common.h"
+
+#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_CIPHER_C)
+
+MBEDTLS_STATIC_TESTABLE int mbedtls_get_pkcs_padding(unsigned char *input,
+                                                     size_t input_len,
+                                                     size_t *data_len);
+
+#endif
+
+#endif /* MBEDTLS_CIPHER_INVASIVE_H */
diff --git a/library/common.h b/library/common.h
index 7bb2674..50f2a29 100644
--- a/library/common.h
+++ b/library/common.h
@@ -434,4 +434,20 @@
 #    define MBEDTLS_MAYBE_UNUSED
 #endif
 
+/* GCC >= 15 has a warning 'unterminated-string-initialization' which complains if you initialize
+ * a string into an array without space for a terminating NULL character. In some places in the
+ * codebase this behaviour is intended, so we add the macro MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING
+ * to suppress the warning in these places.
+ */
+#if defined(__has_attribute)
+#if __has_attribute(nonstring)
+#define MBEDTLS_HAS_ATTRIBUTE_NONSTRING
+#endif /* __has_attribute(nonstring) */
+#endif /* __has_attribute */
+#if defined(MBEDTLS_HAS_ATTRIBUTE_NONSTRING)
+#define MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING __attribute__((nonstring))
+#else
+#define MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING
+#endif /* MBEDTLS_HAS_ATTRIBUTE_NONSTRING */
+
 #endif /* MBEDTLS_LIBRARY_COMMON_H */
diff --git a/library/lmots.c b/library/lmots.c
index c51cb41..404aa80 100644
--- a/library/lmots.c
+++ b/library/lmots.c
@@ -401,8 +401,11 @@
         return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
     }
 
-    ctx->params.type = (mbedtls_lmots_algorithm_type_t)
-                       MBEDTLS_GET_UINT32_BE(key, MBEDTLS_LMOTS_SIG_TYPE_OFFSET);
+    uint32_t type = MBEDTLS_GET_UINT32_BE(key, MBEDTLS_LMOTS_SIG_TYPE_OFFSET);
+    if (type != (uint32_t) MBEDTLS_LMOTS_SHA256_N32_W8) {
+        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
+    }
+    ctx->params.type = (mbedtls_lmots_algorithm_type_t) type;
 
     if (key_len != MBEDTLS_LMOTS_PUBLIC_KEY_LEN(ctx->params.type)) {
         return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
diff --git a/library/lms.c b/library/lms.c
index 7f7bec0..41d34bf 100644
--- a/library/lms.c
+++ b/library/lms.c
@@ -101,6 +101,9 @@
     size_t output_hash_len;
     unsigned char r_node_idx_bytes[4];
 
+    /* Always zeroize the output buffer because it may contain data from the previous invocation */
+    memset(out, 0, MBEDTLS_LMS_M_NODE_BYTES(params->type));
+
     op = psa_hash_operation_init();
     status = psa_hash_setup(&op, PSA_ALG_SHA_256);
     if (status != PSA_SUCCESS) {
@@ -239,25 +242,25 @@
 int mbedtls_lms_import_public_key(mbedtls_lms_public_t *ctx,
                                   const unsigned char *key, size_t key_size)
 {
-    mbedtls_lms_algorithm_type_t type;
-    mbedtls_lmots_algorithm_type_t otstype;
-
-    type = (mbedtls_lms_algorithm_type_t) MBEDTLS_GET_UINT32_BE(key, PUBLIC_KEY_TYPE_OFFSET);
-    if (type != MBEDTLS_LMS_SHA256_M32_H10) {
+    if (key_size < 4) {
         return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
     }
-    ctx->params.type = type;
+
+    uint32_t type = MBEDTLS_GET_UINT32_BE(key, PUBLIC_KEY_TYPE_OFFSET);
+    if (type != (uint32_t) MBEDTLS_LMS_SHA256_M32_H10) {
+        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
+    }
+    ctx->params.type = (mbedtls_lms_algorithm_type_t) type;
 
     if (key_size != MBEDTLS_LMS_PUBLIC_KEY_LEN(ctx->params.type)) {
         return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
     }
 
-    otstype = (mbedtls_lmots_algorithm_type_t)
-              MBEDTLS_GET_UINT32_BE(key, PUBLIC_KEY_OTSTYPE_OFFSET);
-    if (otstype != MBEDTLS_LMOTS_SHA256_N32_W8) {
+    uint32_t otstype = MBEDTLS_GET_UINT32_BE(key, PUBLIC_KEY_OTSTYPE_OFFSET);
+    if (otstype != (uint32_t) MBEDTLS_LMOTS_SHA256_N32_W8) {
         return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
     }
-    ctx->params.otstype = otstype;
+    ctx->params.otstype = (mbedtls_lmots_algorithm_type_t) otstype;
 
     memcpy(ctx->params.I_key_identifier,
            key + PUBLIC_KEY_I_KEY_ID_OFFSET,
@@ -374,12 +377,16 @@
         return MBEDTLS_ERR_LMS_VERIFY_FAILED;
     }
 
-    create_merkle_leaf_value(
+    ret = create_merkle_leaf_value(
         &ctx->params,
         Kc_candidate_ots_pub_key,
         MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + q_leaf_identifier,
         Tc_candidate_root_node);
 
+    if (ret != 0) {
+        return MBEDTLS_ERR_LMS_VERIFY_FAILED;
+    }
+
     curr_node_id = MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) +
                    q_leaf_identifier;
 
@@ -398,9 +405,11 @@
                          height * MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type);
         }
 
-        create_merkle_internal_value(&ctx->params, left_node, right_node,
-                                     parent_node_id, Tc_candidate_root_node);
-
+        ret = create_merkle_internal_value(&ctx->params, left_node, right_node,
+                                           parent_node_id, Tc_candidate_root_node);
+        if (ret != 0) {
+            return MBEDTLS_ERR_LMS_VERIFY_FAILED;
+        }
         curr_node_id /= 2;
     }
 
diff --git a/library/pem.c b/library/pem.c
index 0207601..119fd59 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -243,7 +243,10 @@
 #if defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C)
 static int pem_check_pkcs_padding(unsigned char *input, size_t input_len, size_t *data_len)
 {
-    /* input_len > 0 is guaranteed by mbedtls_pem_read_buffer(). */
+    /* input_len > 0 is not guaranteed by mbedtls_pem_read_buffer(). */
+    if (input_len < 1) {
+        return MBEDTLS_ERR_PEM_INVALID_DATA;
+    }
     size_t pad_len = input[input_len - 1];
     size_t i;
 
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 348c79c..9c28609 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -2400,8 +2400,11 @@
         goto exit;
     }
 
-    /* Ensure all of the context is zeroized, since PSA_HASH_OPERATION_INIT only
-     * directly zeroes the int-sized dummy member of the context union. */
+    /* Make sure the driver-dependent part of the operation is zeroed.
+     * This is a guarantee we make to drivers. Initializing the operation
+     * does not necessarily take care of it, since the context is a
+     * union and initializing a union does not necessarily initialize
+     * all of its members. */
     memset(&operation->ctx, 0, sizeof(operation->ctx));
 
     status = psa_driver_wrapper_hash_setup(operation, alg);
@@ -2596,6 +2599,13 @@
         return PSA_ERROR_BAD_STATE;
     }
 
+    /* Make sure the driver-dependent part of the operation is zeroed.
+     * This is a guarantee we make to drivers. Initializing the operation
+     * does not necessarily take care of it, since the context is a
+     * union and initializing a union does not necessarily initialize
+     * all of its members. */
+    memset(&target_operation->ctx, 0, sizeof(target_operation->ctx));
+
     psa_status_t status = psa_driver_wrapper_hash_clone(source_operation,
                                                         target_operation);
     if (status != PSA_SUCCESS) {
@@ -2693,6 +2703,13 @@
         goto exit;
     }
 
+    /* Make sure the driver-dependent part of the operation is zeroed.
+     * This is a guarantee we make to drivers. Initializing the operation
+     * does not necessarily take care of it, since the context is a
+     * union and initializing a union does not necessarily initialize
+     * all of its members. */
+    memset(&operation->ctx, 0, sizeof(operation->ctx));
+
     status = psa_get_and_lock_key_slot_with_policy(
         key,
         &slot,
@@ -3619,6 +3636,13 @@
         return PSA_ERROR_BAD_STATE;
     }
 
+    /* Make sure the driver-dependent part of the operation is zeroed.
+     * This is a guarantee we make to drivers. Initializing the operation
+     * does not necessarily take care of it, since the context is a
+     * union and initializing a union does not necessarily initialize
+     * all of its members. */
+    memset(&operation->ctx, 0, sizeof(operation->ctx));
+
     status = psa_sign_verify_check_alg(0, alg);
     if (status != PSA_SUCCESS) {
         operation->error_occurred = 1;
@@ -3779,6 +3803,13 @@
         return PSA_ERROR_BAD_STATE;
     }
 
+    /* Make sure the driver-dependent part of the operation is zeroed.
+     * This is a guarantee we make to drivers. Initializing the operation
+     * does not necessarily take care of it, since the context is a
+     * union and initializing a union does not necessarily initialize
+     * all of its members. */
+    memset(&operation->ctx, 0, sizeof(operation->ctx));
+
     status = psa_sign_verify_check_alg(0, alg);
     if (status != PSA_SUCCESS) {
         operation->error_occurred = 1;
@@ -4446,6 +4477,14 @@
     }
     operation->default_iv_length = PSA_CIPHER_IV_LENGTH(slot->attr.type, alg);
 
+
+    /* Make sure the driver-dependent part of the operation is zeroed.
+     * This is a guarantee we make to drivers. Initializing the operation
+     * does not necessarily take care of it, since the context is a
+     * union and initializing a union does not necessarily initialize
+     * all of its members. */
+    memset(&operation->ctx, 0, sizeof(operation->ctx));
+
     /* Try doing the operation through a driver before using software fallback. */
     if (cipher_operation == MBEDTLS_ENCRYPT) {
         status = psa_driver_wrapper_cipher_encrypt_setup(operation,
@@ -5079,6 +5118,13 @@
         goto exit;
     }
 
+    /* Make sure the driver-dependent part of the operation is zeroed.
+     * This is a guarantee we make to drivers. Initializing the operation
+     * does not necessarily take care of it, since the context is a
+     * union and initializing a union does not necessarily initialize
+     * all of its members. */
+    memset(&operation->ctx, 0, sizeof(operation->ctx));
+
     if (is_encrypt) {
         key_usage = PSA_KEY_USAGE_ENCRYPT;
     } else {
@@ -5585,7 +5631,7 @@
 }
 
 /****************************************************************/
-/* Generators */
+/* Key derivation: output generation */
 /****************************************************************/
 
 #if defined(BUILTIN_ALG_ANY_HKDF) || \
@@ -5599,6 +5645,17 @@
 #if defined(BUILTIN_ALG_ANY_HKDF) || \
     defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
     defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
+
+/** Internal helper to set up an HMAC operation with a key passed directly.
+ *
+ * \param[in,out] operation     A MAC operation object. It does not need to
+ *                              be initialized.
+ * \param hash_alg              The hash algorithm used for HMAC.
+ * \param hmac_key              The HMAC key.
+ * \param hmac_key_length       Length of \p hmac_key in bytes.
+ *
+ * \return A PSA status code.
+ */
 static psa_status_t psa_key_derivation_start_hmac(
     psa_mac_operation_t *operation,
     psa_algorithm_t hash_alg,
@@ -5611,6 +5668,14 @@
     psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(hmac_key_length));
     psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
 
+    /* Make sure the whole the operation is zeroed.
+     * It isn't enough to require the caller to initialize operation to
+     * PSA_MAC_OPERATION_INIT, since one field is a union and initializing
+     * a union does not necessarily initialize all of its members.
+     * psa_mac_setup() would handle PSA_MAC_OPERATION_INIT, but here we
+     * bypass it and call lower-level functions directly. */
+    memset(operation, 0, sizeof(*operation));
+
     operation->is_sign = 1;
     operation->mac_size = PSA_HASH_LENGTH(hash_alg);
 
@@ -5835,7 +5900,7 @@
 {
     psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(alg);
     uint8_t hash_length = PSA_HASH_LENGTH(hash_alg);
-    psa_mac_operation_t hmac = PSA_MAC_OPERATION_INIT;
+    psa_mac_operation_t hmac;
     size_t hmac_output_length;
     psa_status_t status, cleanup_status;
 
@@ -6036,7 +6101,14 @@
     psa_key_attributes_t *attributes)
 {
     psa_status_t status;
-    psa_mac_operation_t mac_operation = PSA_MAC_OPERATION_INIT;
+    psa_mac_operation_t mac_operation;
+    /* Make sure the whole the operation is zeroed.
+     * PSA_MAC_OPERATION_INIT does not necessarily do it fully,
+     * since one field is a union and initializing a union does not
+     * necessarily initialize all of its members.
+     * psa_mac_setup() would do it, but here we bypass it and call
+     * lower-level functions directly. */
+    memset(&mac_operation, 0, sizeof(mac_operation));
     size_t mac_output_length;
     uint8_t U_i[PSA_MAC_MAX_SIZE];
     uint8_t *U_accumulator = pbkdf2->output_block;
@@ -6667,7 +6739,7 @@
 
 
 /****************************************************************/
-/* Key derivation */
+/* Key derivation: operation management */
 /****************************************************************/
 
 #if defined(AT_LEAST_ONE_BUILTIN_KDF)
@@ -8222,6 +8294,8 @@
                                    key);
 }
 
+
+
 /****************************************************************/
 /* Module setup */
 /****************************************************************/
@@ -8497,6 +8571,12 @@
     return status;
 }
 
+
+
+/****************************************************************/
+/* PAKE */
+/****************************************************************/
+
 #if defined(PSA_WANT_ALG_SOME_PAKE)
 psa_status_t psa_crypto_driver_pake_get_password_len(
     const psa_crypto_driver_pake_inputs_t *inputs,
@@ -8621,7 +8701,11 @@
         goto exit;
     }
 
-    memset(&operation->data.inputs, 0, sizeof(operation->data.inputs));
+    /* Make sure the variable-purpose part of the operation is zeroed.
+     * Initializing the operation does not necessarily take care of it,
+     * since the context is a union and initializing a union does not
+     * necessarily initialize all of its members. */
+    memset(&operation->data, 0, sizeof(operation->data));
 
     operation->alg = cipher_suite->algorithm;
     operation->primitive = PSA_PAKE_PRIMITIVE(cipher_suite->type,
diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c
index 8fe6218..4464158 100644
--- a/library/psa_crypto_mac.c
+++ b/library/psa_crypto_mac.c
@@ -465,6 +465,15 @@
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     mbedtls_psa_mac_operation_t operation = MBEDTLS_PSA_MAC_OPERATION_INIT;
+    /* Make sure the whole operation is zeroed.
+     * PSA_MAC_OPERATION_INIT does not necessarily do it fully,
+     * since one field is a union and initializing a union does not
+     * necessarily initialize all of its members.
+     * In multipart operations, this is done in the API functions,
+     * before driver dispatch, since it needs to be done before calling
+     * the driver entry point. Here, we bypass the multipart API,
+     * so it's our job. */
+    memset(&operation, 0, sizeof(operation));
 
     status = psa_mac_setup(&operation,
                            attributes, key_buffer, key_buffer_size,
diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c
index 358c7a2..f1a651f 100644
--- a/library/psa_crypto_slot_management.c
+++ b/library/psa_crypto_slot_management.c
@@ -663,7 +663,7 @@
             /* Refresh slot_idx, for when the slot is not the original
              * selected_slot but rather unused_persistent_key_slot.  */
             slot_idx = selected_slot - global_data.key_slots;
-            *volatile_key_id = PSA_KEY_ID_VOLATILE_MIN + slot_idx;
+            *volatile_key_id = PSA_KEY_ID_VOLATILE_MIN + (psa_key_id_t) slot_idx;
         }
 #endif
         *p_slot = selected_slot;
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index 9f50c8e..38fd262 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -4461,7 +4461,7 @@
         ret = 0;
         goto exit;
     } else {
-        MBEDTLS_SSL_DEBUG_MSG(2, ("Next handshake message %u not or only partially bufffered",
+        MBEDTLS_SSL_DEBUG_MSG(2, ("Next handshake message %u not or only partially buffered",
                                   hs->in_msg_seq));
     }
 
@@ -6275,7 +6275,7 @@
     } else {
         /*
          * If we are past the point where we can send early data or we have
-         * already reached the maximum early data size, return immediatly.
+         * already reached the maximum early data size, return immediately.
          * Otherwise, progress the handshake as much as possible to not delay
          * it too much. If we reach a point where we can still send early data,
          * then we will send some.
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index ce14c7d..b5bea75 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -5762,7 +5762,7 @@
 
 /* NOTICE: see above */
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-static uint16_t ssl_tls12_preset_default_sig_algs[] = {
+static const uint16_t ssl_tls12_preset_default_sig_algs[] = {
 
 #if defined(MBEDTLS_MD_CAN_SHA512)
 #if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
@@ -5826,7 +5826,7 @@
 
 /* NOTICE: see above */
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-static uint16_t ssl_tls12_preset_suiteb_sig_algs[] = {
+static const uint16_t ssl_tls12_preset_suiteb_sig_algs[] = {
 
 #if defined(MBEDTLS_MD_CAN_SHA256)
 #if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c
index 791b84e..65d6dbd 100644
--- a/library/ssl_tls12_client.c
+++ b/library/ssl_tls12_client.c
@@ -2024,7 +2024,7 @@
 
     tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id);
     if (tls_id == 0) {
-        MBEDTLS_SSL_DEBUG_MSG(1, ("ECC group %u not suported",
+        MBEDTLS_SSL_DEBUG_MSG(1, ("ECC group %u not supported",
                                   grp_id));
         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
     }
diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c
index fd559a7..1967883 100644
--- a/library/ssl_tls13_keys.c
+++ b/library/ssl_tls13_keys.c
@@ -82,7 +82,8 @@
  *            the HkdfLabel structure on success.
  */
 
-static const char tls13_label_prefix[6] = "tls13 ";
+/* We need to tell the compiler that we meant to leave out the null character. */
+static const char tls13_label_prefix[6] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING = "tls13 ";
 
 #define SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN(label_len, context_len) \
     (2                     /* expansion length           */ \
diff --git a/library/ssl_tls13_keys.h b/library/ssl_tls13_keys.h
index 14f6e48..1509e9a 100644
--- a/library/ssl_tls13_keys.h
+++ b/library/ssl_tls13_keys.h
@@ -40,8 +40,9 @@
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
 
+/* We need to tell the compiler that we meant to leave out the null character. */
 #define MBEDTLS_SSL_TLS1_3_LABEL(name, string)       \
-    const unsigned char name    [sizeof(string) - 1];
+    const unsigned char name    [sizeof(string) - 1] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING;
 
 union mbedtls_ssl_tls13_labels_union {
     MBEDTLS_SSL_TLS1_3_LABEL_LIST
diff --git a/library/x509_create.c b/library/x509_create.c
index 839b5df..420e36b 100644
--- a/library/x509_create.c
+++ b/library/x509_create.c
@@ -292,8 +292,12 @@
     unsigned char data[MBEDTLS_X509_MAX_DN_NAME_SIZE];
     size_t data_len = 0;
 
-    /* Clear existing chain if present */
-    mbedtls_asn1_free_named_data_list(head);
+    /* Ensure the output parameter is not already populated.
+     * (If it were, overwriting it would likely cause a memory leak.)
+     */
+    if (*head != NULL) {
+        return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
+    }
 
     while (c <= end) {
         if (in_attr_type && *c == '=') {
diff --git a/library/x509write_crt.c b/library/x509write_crt.c
index 56f23c9..d829ffe 100644
--- a/library/x509write_crt.c
+++ b/library/x509write_crt.c
@@ -84,12 +84,14 @@
 int mbedtls_x509write_crt_set_subject_name(mbedtls_x509write_cert *ctx,
                                            const char *subject_name)
 {
+    mbedtls_asn1_free_named_data_list(&ctx->subject);
     return mbedtls_x509_string_to_names(&ctx->subject, subject_name);
 }
 
 int mbedtls_x509write_crt_set_issuer_name(mbedtls_x509write_cert *ctx,
                                           const char *issuer_name)
 {
+    mbedtls_asn1_free_named_data_list(&ctx->issuer);
     return mbedtls_x509_string_to_names(&ctx->issuer, issuer_name);
 }
 
diff --git a/library/x509write_csr.c b/library/x509write_csr.c
index 0d6f6bb..75bd8f0 100644
--- a/library/x509write_csr.c
+++ b/library/x509write_csr.c
@@ -66,6 +66,7 @@
 int mbedtls_x509write_csr_set_subject_name(mbedtls_x509write_csr *ctx,
                                            const char *subject_name)
 {
+    mbedtls_asn1_free_named_data_list(&ctx->subject);
     return mbedtls_x509_string_to_names(&ctx->subject, subject_name);
 }
 
diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c
index 93c1729..98ddd48 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -56,6 +56,10 @@
 
 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
 
+#if defined(_MSC_VER)
+#pragma warning(disable : 5105) // warning inside winbase.h in C11 mode
+#endif
+
 #include <windows.h>
 #include <process.h>
 
diff --git a/programs/test/dlopen.c b/programs/test/dlopen.c
index f241254..1ee24ae 100644
--- a/programs/test/dlopen.c
+++ b/programs/test/dlopen.c
@@ -47,8 +47,15 @@
 #if defined(MBEDTLS_SSL_TLS_C)
     void *tls_so = dlopen(TLS_SO_FILENAME, RTLD_NOW);
     CHECK_DLERROR("dlopen", TLS_SO_FILENAME);
+#pragma GCC diagnostic push
+    /* dlsym() returns an object pointer which is meant to be used as a
+     * function pointer. This has undefined behavior in standard C, so
+     * "gcc -std=c99 -pedantic" complains about it, but it is perfectly
+     * fine on platforms that have dlsym(). */
+#pragma GCC diagnostic ignored "-Wpedantic"
     const int *(*ssl_list_ciphersuites)(void) =
         dlsym(tls_so, "mbedtls_ssl_list_ciphersuites");
+#pragma GCC diagnostic pop
     CHECK_DLERROR("dlsym", "mbedtls_ssl_list_ciphersuites");
     const int *ciphersuites = ssl_list_ciphersuites();
     for (n = 0; ciphersuites[n] != 0; n++) {/* nothing to do, we're just counting */
@@ -75,8 +82,15 @@
 #if defined(MBEDTLS_MD_C)
     void *crypto_so = dlopen(CRYPTO_SO_FILENAME, RTLD_NOW);
     CHECK_DLERROR("dlopen", CRYPTO_SO_FILENAME);
+#pragma GCC diagnostic push
+    /* dlsym() returns an object pointer which is meant to be used as a
+     * function pointer. This has undefined behavior in standard C, so
+     * "gcc -std=c99 -pedantic" complains about it, but it is perfectly
+     * fine on platforms that have dlsym(). */
+#pragma GCC diagnostic ignored "-Wpedantic"
     const int *(*md_list)(void) =
         dlsym(crypto_so, "mbedtls_md_list");
+#pragma GCC diagnostic pop
     CHECK_DLERROR("dlsym", "mbedtls_md_list");
     const int *mds = md_list();
     for (n = 0; mds[n] != 0; n++) {/* nothing to do, we're just counting */
diff --git a/programs/test/udp_proxy.c b/programs/test/udp_proxy.c
index 43d2e8c..b580b06 100644
--- a/programs/test/udp_proxy.c
+++ b/programs/test/udp_proxy.c
@@ -50,6 +50,11 @@
 /* For select() */
 #if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
     !defined(EFI32)
+
+#if defined(_MSC_VER)
+#pragma warning(disable : 5105) // warning inside winbase.h in C11 mode
+#endif
+
 #include <winsock2.h>
 #include <windows.h>
 #if defined(_MSC_VER)
diff --git a/programs/x509/cert_req.c b/programs/x509/cert_req.c
index 995ee49..38b7af0 100644
--- a/programs/x509/cert_req.c
+++ b/programs/x509/cert_req.c
@@ -150,7 +150,6 @@
     mbedtls_ctr_drbg_context ctr_drbg;
     const char *pers = "csr example app";
     mbedtls_x509_san_list *cur, *prev;
-    mbedtls_asn1_named_data *ext_san_dirname = NULL;
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
     uint8_t ip[4] = { 0 };
 #endif
@@ -274,7 +273,15 @@
                     cur->node.san.unstructured_name.len = sizeof(ip);
                 } else if (strcmp(q, "DN") == 0) {
                     cur->node.type = MBEDTLS_X509_SAN_DIRECTORY_NAME;
-                    if ((ret = mbedtls_x509_string_to_names(&ext_san_dirname,
+                    /* Work around an API mismatch between string_to_names() and
+                     * mbedtls_x509_subject_alternative_name, which holds an
+                     * actual mbedtls_x509_name while a pointer to one would be
+                     * more convenient here. (Note mbedtls_x509_name and
+                     * mbedtls_asn1_named_data are synonymous, again
+                     * string_to_names() uses one while
+                     * cur->node.san.directory_name is nominally the other.) */
+                    mbedtls_asn1_named_data *tmp_san_dirname = NULL;
+                    if ((ret = mbedtls_x509_string_to_names(&tmp_san_dirname,
                                                             subtype_value)) != 0) {
                         mbedtls_strerror(ret, buf, sizeof(buf));
                         mbedtls_printf(
@@ -283,7 +290,9 @@
                             (unsigned int) -ret, buf);
                         goto exit;
                     }
-                    cur->node.san.directory_name = *ext_san_dirname;
+                    cur->node.san.directory_name = *tmp_san_dirname;
+                    mbedtls_free(tmp_san_dirname);
+                    tmp_san_dirname = NULL;
                 } else {
                     mbedtls_free(cur);
                     goto usage;
@@ -492,7 +501,6 @@
     }
 
     mbedtls_x509write_csr_free(&req);
-    mbedtls_asn1_free_named_data_list(&ext_san_dirname);
     mbedtls_pk_free(&key);
     mbedtls_ctr_drbg_free(&ctr_drbg);
     mbedtls_entropy_free(&entropy);
@@ -502,12 +510,21 @@
 
     cur = opt.san_list;
     while (cur != NULL) {
-        prev = cur;
-        cur = cur->next;
-        mbedtls_free(prev);
+        mbedtls_x509_san_list *next = cur->next;
+        /* Note: mbedtls_x509_free_subject_alt_name() is not what we want here.
+         * It's the right thing for entries that were parsed from a certificate,
+         * where pointers are to the raw certificate, but here all the
+         * pointers were allocated while parsing from a user-provided string. */
+        if (cur->node.type == MBEDTLS_X509_SAN_DIRECTORY_NAME) {
+            mbedtls_x509_name *dn = &cur->node.san.directory_name;
+            mbedtls_free(dn->oid.p);
+            mbedtls_free(dn->val.p);
+            mbedtls_asn1_free_named_data_list(&dn->next);
+        }
+        mbedtls_free(cur);
+        cur = next;
     }
 
-
     mbedtls_exit(exit_code);
 }
 #endif /* MBEDTLS_X509_CSR_WRITE_C && MBEDTLS_PK_PARSE_C && MBEDTLS_FS_IO &&
diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c
index 6fd1dce..95f08b9 100644
--- a/programs/x509/cert_write.c
+++ b/programs/x509/cert_write.c
@@ -312,7 +312,6 @@
     mbedtls_ctr_drbg_context ctr_drbg;
     const char *pers = "crt example app";
     mbedtls_x509_san_list *cur, *prev;
-    mbedtls_asn1_named_data *ext_san_dirname = NULL;
     uint8_t ip[4] = { 0 };
     /*
      * Set to sane values
@@ -595,7 +594,15 @@
                     cur->node.san.unstructured_name.len = sizeof(ip);
                 } else if (strcmp(q, "DN") == 0) {
                     cur->node.type = MBEDTLS_X509_SAN_DIRECTORY_NAME;
-                    if ((ret = mbedtls_x509_string_to_names(&ext_san_dirname,
+                    /* Work around an API mismatch between string_to_names() and
+                     * mbedtls_x509_subject_alternative_name, which holds an
+                     * actual mbedtls_x509_name while a pointer to one would be
+                     * more convenient here. (Note mbedtls_x509_name and
+                     * mbedtls_asn1_named_data are synonymous, again
+                     * string_to_names() uses one while
+                     * cur->node.san.directory_name is nominally the other.) */
+                    mbedtls_asn1_named_data *tmp_san_dirname = NULL;
+                    if ((ret = mbedtls_x509_string_to_names(&tmp_san_dirname,
                                                             subtype_value)) != 0) {
                         mbedtls_strerror(ret, buf, sizeof(buf));
                         mbedtls_printf(
@@ -604,7 +611,9 @@
                             (unsigned int) -ret, buf);
                         goto exit;
                     }
-                    cur->node.san.directory_name = *ext_san_dirname;
+                    cur->node.san.directory_name = *tmp_san_dirname;
+                    mbedtls_free(tmp_san_dirname);
+                    tmp_san_dirname = NULL;
                 } else {
                     mbedtls_free(cur);
                     goto usage;
@@ -995,10 +1004,26 @@
     exit_code = MBEDTLS_EXIT_SUCCESS;
 
 exit:
+    cur = opt.san_list;
+    while (cur != NULL) {
+        mbedtls_x509_san_list *next = cur->next;
+        /* Note: mbedtls_x509_free_subject_alt_name() is not what we want here.
+         * It's the right thing for entries that were parsed from a certificate,
+         * where pointers are to the raw certificate, but here all the
+         * pointers were allocated while parsing from a user-provided string. */
+        if (cur->node.type == MBEDTLS_X509_SAN_DIRECTORY_NAME) {
+            mbedtls_x509_name *dn = &cur->node.san.directory_name;
+            mbedtls_free(dn->oid.p);
+            mbedtls_free(dn->val.p);
+            mbedtls_asn1_free_named_data_list(&dn->next);
+        }
+        mbedtls_free(cur);
+        cur = next;
+    }
+
 #if defined(MBEDTLS_X509_CSR_PARSE_C)
     mbedtls_x509_csr_free(&csr);
 #endif /* MBEDTLS_X509_CSR_PARSE_C */
-    mbedtls_asn1_free_named_data_list(&ext_san_dirname);
     mbedtls_x509_crt_free(&issuer_crt);
     mbedtls_x509write_crt_free(&crt);
     mbedtls_pk_free(&loaded_subject_key);
diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py
index 301bfc4..52034a1 100755
--- a/tests/scripts/analyze_outcomes.py
+++ b/tests/scripts/analyze_outcomes.py
@@ -86,10 +86,6 @@
             # Untested platform-specific optimizations.
             # https://github.com/Mbed-TLS/mbedtls/issues/9588
             'Config: MBEDTLS_HAVE_SSE2',
-            # Obsolete configuration option, to be replaced by
-            # PSA entropy drivers.
-            # https://github.com/Mbed-TLS/mbedtls/issues/8150
-            'Config: MBEDTLS_NO_PLATFORM_ENTROPY',
             # Untested aspect of the platform interface.
             # https://github.com/Mbed-TLS/mbedtls/issues/9589
             'Config: MBEDTLS_PLATFORM_NO_STD_FUNCTIONS',
diff --git a/tests/scripts/components-compiler.sh b/tests/scripts/components-compiler.sh
index c0edd20..1eac64f 100644
--- a/tests/scripts/components-compiler.sh
+++ b/tests/scripts/components-compiler.sh
@@ -72,6 +72,35 @@
     type "$GCC_LATEST" >/dev/null 2>/dev/null
 }
 
+# Prepare for a non-regression for https://github.com/Mbed-TLS/mbedtls/issues/9814 :
+# test with GCC 15.
+# Eventually, $GCC_LATEST will be GCC 15 or above, and we can remove this
+# separate component.
+# For the time being, we don't make $GCC_LATEST be GCC 15 on the CI
+# platform, because that would break branches where #9814 isn't fixed yet.
+support_test_gcc15_drivers_opt () {
+    if type gcc-15 >/dev/null 2>/dev/null; then
+        GCC_15=gcc-15
+    elif [ -x /usr/local/gcc-15/bin/gcc-15 ]; then
+        GCC_15=/usr/local/gcc-15/bin/gcc-15
+    else
+        return 1
+    fi
+}
+component_test_gcc15_drivers_opt () {
+    msg "build: GCC 15: full + test drivers dispatching to builtins"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_CONFIG
+    loc_cflags="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST_ALL"
+    loc_cflags="${loc_cflags} '-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/user-config-for-test.h\"'"
+    loc_cflags="${loc_cflags} -I../framework/tests/include -O2"
+
+    make CC=$GCC_15 CFLAGS="${loc_cflags}" LDFLAGS="$ASAN_CFLAGS"
+
+    msg "test: GCC 15: full + test drivers dispatching to builtins"
+    make test
+}
+
 component_test_gcc_earliest_opt () {
     scripts/config.py full
     test_build_opt 'full config' "$GCC_EARLIEST" -O2
diff --git a/tests/scripts/components-configuration-crypto.sh b/tests/scripts/components-configuration-crypto.sh
index e3096f3..04c38f6 100644
--- a/tests/scripts/components-configuration-crypto.sh
+++ b/tests/scripts/components-configuration-crypto.sh
@@ -426,6 +426,23 @@
     tests/ssl-opt.sh -f 'Default\|opaque'
 }
 
+component_test_entropy_nv_seed_only () {
+    msg "build: full minus platform entropy (NV seed only)"
+    scripts/config.py full
+    scripts/config.py set MBEDTLS_NO_PLATFORM_ENTROPY
+    make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
+
+    msg "build: full minus platform entropy (NV seed only)"
+    make test
+
+    # Check that the library seems to refer to the seedfile, but not to
+    # platform entropy sources.
+    grep seedfile library/platform.o
+    not grep getrandom library/entropy*.o
+    not grep /dev/random library/entropy*.o
+    not grep /dev/.random library/entropy*.o
+}
+
 component_test_psa_inject_entropy () {
     msg "build: full + MBEDTLS_PSA_INJECT_ENTROPY"
     scripts/config.py full
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 16e2675..ad87605 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -12526,7 +12526,7 @@
             0 \
             -c "Buffering HS message" \
             -c "found fragmented DTLS handshake message"\
-            -c "Next handshake message 1 not or only partially bufffered" \
+            -c "Next handshake message 1 not or only partially buffered" \
             -c "Next handshake message has been buffered - load"\
             -S "Buffering HS message" \
             -S "Next handshake message has been buffered - load"\
diff --git a/tests/suites/test_suite_asn1write.function b/tests/suites/test_suite_asn1write.function
index f5fc025..b1e66ed 100644
--- a/tests/suites/test_suite_asn1write.function
+++ b/tests/suites/test_suite_asn1write.function
@@ -550,6 +550,9 @@
     }
     if (new_len == 0) {
         TEST_ASSERT(found->val.p == NULL);
+        /* If new_len != 0, then new_val != NULL and the length has been checked
+         * above by TEST_MEMORY_COMPARE(). But not here, so we need to check. */
+        TEST_EQUAL(found->val.len, 0);
     } else if (new_len == old_len) {
         TEST_ASSERT(found->val.p == old_val);
     } else {
@@ -583,8 +586,10 @@
     TEST_MEMORY_COMPARE(found->oid.p, found->oid.len, oid, oid_len);
     if (new_len == 0) {
         TEST_ASSERT(found->val.p == NULL);
+        TEST_EQUAL(found->val.len, 0);
     } else if (new_val == NULL) {
         TEST_ASSERT(found->val.p != NULL);
+        TEST_EQUAL(found->val.len, new_len);
     } else {
         TEST_ASSERT(found->val.p != new_val);
         TEST_MEMORY_COMPARE(found->val.p, found->val.len,
diff --git a/tests/suites/test_suite_base64.data b/tests/suites/test_suite_base64.data
index 3999e73..feed172 100644
--- a/tests/suites/test_suite_base64.data
+++ b/tests/suites/test_suite_base64.data
@@ -76,6 +76,107 @@
 Base64 decode (Space inside string)
 mbedtls_base64_decode:"zm masd":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
 
+# The next few test cases validate systematically for short inputs that
+# we require the correct number of trailing equal signs.
+
+# 4k+1 digits is always wrong (wouldn't encode more bytes than 4k digits)
+Base64 decode: 1 digit, 0 equals (bad)
+mbedtls_base64_decode:"Y":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 1 digit, 1 equals (bad)
+mbedtls_base64_decode:"Y=":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 1 digit, 2 equals (bad)
+mbedtls_base64_decode:"Y==":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 1 digit, 3 equals (bad)
+mbedtls_base64_decode:"Y===":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 2 digits, 0 equals (bad)
+mbedtls_base64_decode:"Yw":"c":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 2 digits, 1 equals (bad)
+mbedtls_base64_decode:"Yw=":"c":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 2 digits, 2 equals (good)
+mbedtls_base64_decode:"Yw==":"c":0
+
+Base64 decode: 2 digits, 3 equals (bad)
+mbedtls_base64_decode:"Yw===":"c":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 3 digits, 0 equals (bad)
+mbedtls_base64_decode:"Y28":"co":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 3 digits, 1 equals (good)
+mbedtls_base64_decode:"Y28=":"co":0
+
+Base64 decode: 3 digits, 2 equals (bad)
+mbedtls_base64_decode:"Y28==":"co":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 3 digits, 3 equals (bad)
+mbedtls_base64_decode:"Y28===":"co":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 4 digits, 0 equals (good)
+mbedtls_base64_decode:"Y29t":"com":0
+
+Base64 decode: 4 digits, 1 equals (bad)
+mbedtls_base64_decode:"Y29t=":"com":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 4 digits, 2 equals (bad)
+mbedtls_base64_decode:"Y29t==":"com":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 4 digits, 3 equals (bad)
+mbedtls_base64_decode:"Y29t===":"com":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+# 4k+1 digits is always wrong (wouldn't encode more bytes than 4k digits)
+Base64 decode: 5 digits, 0 equals (bad)
+mbedtls_base64_decode:"Y29tc":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 5 digits, 1 equals (bad)
+mbedtls_base64_decode:"Y29tc=":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 5 digits, 2 equals (bad)
+mbedtls_base64_decode:"Y29tc==":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 5 digits, 3 equals (bad)
+mbedtls_base64_decode:"Y29tc===":"com":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 6 digits, 0 equals (bad)
+mbedtls_base64_decode:"Y29tcA":"comp":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 6 digits, 1 equals (bad)
+mbedtls_base64_decode:"Y29tcA=":"comp":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 6 digits, 2 equals (good)
+mbedtls_base64_decode:"Y29tcA==":"comp":0
+
+Base64 decode: 6 digits, 3 equals (bad)
+mbedtls_base64_decode:"Y29tcA===":"comp":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 7 digits, 0 equals (bad)
+mbedtls_base64_decode:"Y29tcG8":"compo":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 7 digits, 1 equals (good)
+mbedtls_base64_decode:"Y29tcG8=":"compo":0
+
+Base64 decode: 7 digits, 2 equals (bad)
+mbedtls_base64_decode:"Y29tcG8==":"compo":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 7 digits, 3 equals (bad)
+mbedtls_base64_decode:"Y29tcG8===":"compo":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 8 digits, 0 equals (good)
+mbedtls_base64_decode:"Y29tcG9z":"compos":0
+
+Base64 decode: 8 digits, 1 equals (bad)
+mbedtls_base64_decode:"Y29tcG9z=":"compos":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 8 digits, 2 equals (bad)
+mbedtls_base64_decode:"Y29tcG9z==":"compos":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
+Base64 decode: 8 digits, 3 equals (bad)
+mbedtls_base64_decode:"Y29tcG9z===":"compos":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+
 Base64 decode "Zm9vYmFy" (no newline nor '\0' at end)
 base64_decode_hex_src:"5a6d3976596d4679":"foobar":0
 
diff --git a/tests/suites/test_suite_base64.function b/tests/suites/test_suite_base64.function
index e351ad8..095f980 100644
--- a/tests/suites/test_suite_base64.function
+++ b/tests/suites/test_suite_base64.function
@@ -85,20 +85,67 @@
 /* BEGIN_CASE */
 void mbedtls_base64_decode(char *src_string, char *dst_string, int result)
 {
-    unsigned char src_str[1000];
-    unsigned char dst_str[1000];
+    unsigned char *src = NULL;
+    size_t src_len = strlen(src_string);
+    unsigned char *dst = NULL;
+    size_t correct_dst_len = strlen(dst_string);
+    size_t dst_size = correct_dst_len;
     size_t len;
-    int res;
 
-    memset(src_str, 0x00, 1000);
-    memset(dst_str, 0x00, 1000);
-
-    strncpy((char *) src_str, src_string, sizeof(src_str) - 1);
-    res = mbedtls_base64_decode(dst_str, sizeof(dst_str), &len, src_str, strlen((char *) src_str));
-    TEST_ASSERT(res == result);
-    if (result == 0) {
-        TEST_ASSERT(strcmp((char *) dst_str, dst_string) == 0);
+    /* Allocate exactly the size of the input, to ensure there's no buffer
+     * overread in builds with ASan. (src_string has at least one extra null
+     * character at the end.) */
+    TEST_CALLOC(src, src_len);
+    if (src_len != 0) {
+        memcpy(src, src_string, src_len);
     }
+
+    /* Allocate exactly the size of the input, to ensure there's no buffer
+     * overflow in builds with ASan. */
+    TEST_CALLOC(dst, dst_size);
+
+    /* Test normal operation */
+    TEST_EQUAL(mbedtls_base64_decode(dst, dst_size, &len,
+                                     src, src_len),
+               result);
+    if (result == 0) {
+        TEST_MEMORY_COMPARE(dst_string, correct_dst_len, dst, len);
+    }
+
+    /* Test an output buffer that's one byte too small */
+    if (result == 0 && dst_size != 0) {
+        mbedtls_free(dst);
+        dst = NULL;
+        TEST_CALLOC(dst, dst_size - 1);
+        TEST_EQUAL(mbedtls_base64_decode(dst, dst_size - 1, &len,
+                                         src, src_len),
+                   MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL);
+        TEST_EQUAL(correct_dst_len, len);
+    }
+
+    /* Test an empty output buffer. `mbedtls_base64_decode()` must return
+     * `BUFFER_TOO_SMALL` but report the correct output length.
+     * Skip this when dst_size==0 since that would be a valid call to
+     * `mbedtls_base64_decode()` which should return 0.
+     */
+    if (result == 0 && dst_size != 0) {
+        TEST_EQUAL(mbedtls_base64_decode(NULL, 0, &len,
+                                         src, src_len),
+                   MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL);
+        TEST_EQUAL(correct_dst_len, len);
+    }
+
+    /* Test dst=NULL with dlen!=0 (explicitly documented as supported) */
+    if (result == 0 && dst_size != 0) {
+        TEST_EQUAL(mbedtls_base64_decode(NULL, 42, &len,
+                                         src, src_len),
+                   MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL);
+        TEST_EQUAL(correct_dst_len, len);
+    }
+
+exit:
+    mbedtls_free(src);
+    mbedtls_free(dst);
 }
 /* END_CASE */
 
diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function
index 040c35c..2856ae5 100644
--- a/tests/suites/test_suite_cipher.function
+++ b/tests/suites/test_suite_cipher.function
@@ -6,6 +6,10 @@
 #include "mbedtls/gcm.h"
 #endif
 
+#include "cipher_invasive.h"
+
+#include "test/constant_flow.h"
+
 #if defined(MBEDTLS_CIPHER_HAVE_SOME_AEAD_VIA_LEGACY_OR_USE_PSA) || defined(MBEDTLS_NIST_KW_C)
 #define MBEDTLS_CIPHER_AUTH_CRYPT
 #endif
@@ -1260,3 +1264,20 @@
     mbedtls_free(key);
 }
 /* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
+void get_pkcs_padding(data_t *decrypted_block, int exp_ret, int exp_len)
+{
+    int ret;
+    size_t calculated_len;
+
+    TEST_CF_SECRET(decrypted_block->x, decrypted_block->len);
+    ret = mbedtls_get_pkcs_padding(decrypted_block->x, decrypted_block->len,
+                                   &calculated_len);
+
+    TEST_EQUAL(ret, exp_ret);
+    if (exp_ret == 0) {
+        TEST_EQUAL(calculated_len, exp_len);
+    }
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_cipher.padding.data b/tests/suites/test_suite_cipher.padding.data
index 0370fb3..85b14c1 100644
--- a/tests/suites/test_suite_cipher.padding.data
+++ b/tests/suites/test_suite_cipher.padding.data
@@ -217,3 +217,18 @@
 
 Check no padding #3 (correct by definition)
 check_padding:MBEDTLS_PADDING_NONE:"":0:0
+
+Constant-time PKCS7 padding, valid #1
+get_pkcs_padding:"00112233445566778899AABBCCDDEE01":0:15
+
+Constant-time PKCS7 padding, valid #2
+get_pkcs_padding:"00112233445566778899AA0505050505":0:11
+
+Constant-time PKCS7 padding, valid #3
+get_pkcs_padding:"10101010101010101010101010101010":0:0
+
+Constant-time PKCS7 padding, invalid zero
+get_pkcs_padding:"00112233445566778899AABBCCDDEE00":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
+
+Constant-time PKCS7 padding, invalid > 16
+get_pkcs_padding:"00112233445566778899AABBCCDDEE11":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
diff --git a/tests/suites/test_suite_config.crypto_combinations.data b/tests/suites/test_suite_config.crypto_combinations.data
index d3287d2..9cc09ec 100644
--- a/tests/suites/test_suite_config.crypto_combinations.data
+++ b/tests/suites/test_suite_config.crypto_combinations.data
@@ -1,5 +1,10 @@
 # Interesting combinations of low-level crypto options
 
+# Entropy: available in mbedtls_entropy_init(), thanks to NV seed, no platform sources, no custom source
+Config: entropy: NV seed only
+depends_on:!MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_NO_PLATFORM_ENTROPY:!MBEDTLS_ENTROPY_HARDWARE_ALT
+pass:
+
 Config: ECC: Weierstrass curves only
 depends_on:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED:!MBEDTLS_ECP_MONTGOMERY_ENABLED
 pass:
diff --git a/tests/suites/test_suite_lms.data b/tests/suites/test_suite_lms.data
index 16ebd1d..5601cce 100644
--- a/tests/suites/test_suite_lms.data
+++ b/tests/suites/test_suite_lms.data
@@ -186,6 +186,13 @@
 # print('lms_verify_test:"{}":"{}":"{}":0'.format(message.hex(), sig.hex(), public_key.get_pubkey().hex()))
 lms_verify_test:"92d036bde8c45b8bb5dea2a072560b1e29fc4bb7dc4549ce90bccee8a6e962a1":"00000001000000042e758f2a0e8f301af58847b6973a15fe4856b91af88a1ff601e2f0e87bde33afbc39202a66e38931fbecd7d493cf957b37eeb57ed2e4d8f693b97adafa8241746d775cfb9471688d935e090581eb8586e7004d6b8855963d82ccb6f79df2d93dd35848556da6735def0f0c6c8fc969c1df692341f6a99626eff37d20226cef361c8802a995fa43535fe2336d8ae468c78eb6a7082e27c2c6317c034369b588e3d65a2eeac9804b427702dc49f681a841076813ed407399aa778259e7c34c750baa6d296a384e1274facaba9e2214d197628f5df7b2bf3896fedeab377b8edb775d6e8d67f1474ba3066794447f8f8e0c13552a007557a1f1c3b9bd2b41d9b446c6bcf36c828fd4c80850a31ee603065f5cc90d198df03835195b14e27da7bf727a16081fcc787f1dc7fa6da8b9ff908fb2c02d6f2a183486de0e39cd7da7fcdee0c8e96876c56ad9b0b18e4e4999e2c81a618aa4b27e050ce488dbb1e79089131afacc446cdf15b625f4e011f8d8160bb93f326bca3bb56fa41e34893d55f17d746fc142297997c5dbbba8f6b6c80678168ba455f12bac6982e5192de5462a46e14a45a01ce9e07279aa301dfd0fa9a12c6a55059b19a19d7afbe99779ea130ddeeb5ecb67d2ddb6c1c5d198e421b78091efa5aa429e1eb052760c0d8e2eb0c0ced000e93f7f265611a385f77c0cece0496eb29010f710e70a768d3713f0b7fc60c8ce372dc3234f27c7a1c2776a939ef70c7be869337b967df2223d4f20dca697e3bb6d0e53bbad153ff08d579f60c8535710f253b90e73ee9a19e1e57df66ec6c85ad1b4cea28a9d62fc5a4cf130f70b910dbc7e6f0e6b0cce1a1b5ff106b7f0b101405c0989084b2c94977116b98d15d6062a8d77d660aa813d432cf3338484308b7beed10236081f52da44eb807f9a75fd4cc1ba998ef3fc2e4791712597c786dd46431468bb4a1975a6cd854a1da23912fc99160f51df484efc9371c2d8e028d9468635cf93226f5a8834d14cead59e5d2a61dd6440d7b91c903ae8823907b75595c4828c7710036b347dcfb67f8561e835a53f569c8b3a1cd4317b2a6b2243100ee3d9468f9191acf2276d18dde9ebf2e11a48ba1fc1a15dc51091d3358d8d1f65ec7d84b97bb1669a9141f74065454f08e5ef25432b7635b8ec673ca70e4b3c25d07975a6fb725a56f28c1b5a81a6da2fe0a2c3474275926f9819a25b942462a68097e1cf6d9ae94f6b1f76b54addaeda04f9fc8db025fd6c453e1ad928f9323bf1381fce1893938828612728185d22a3d45d21ce762c066ab53a582c487d76d431e5b8f65a382142dd823d4620931e5572a4e6aee69986421afa119634bc8ea88aa6535c4d619ca0e0af94934637bc0c834e5e2a7a2853fa73835d00e13e5f26ad085ef66c8efb60097860cb199e03596a3b8f0ec78690d527bbc9363dd9702226788b1529871df74918ae2a4e02745043bd5ee8ab027826fb4cd54b0c27d99076757a1b41e2725ec02adc7926e8213796a8aa1740a2dc675437771e0364a83b0bd64c9620f6c203d92626ff29ef736eac0e13c71fd1957333ee0048000000061f7b7d6f916710efe9ed625ae689c67b3cc1cdf0d672e58c0b86b3839bbba2c243dcda2e63b26f5efa39ced6095a54625e67ab25d3df068e903eaaee894ac0f1fdeb4a2f1390f655db3608583eacfb0be4282f7bd1c42c5d748d524d7cdcd45878dea56cbc11a63bebbd74a5413ce72a931b1d4794c78c4cf16315bf2e055bb3305fe0272c8b916856cc27aa7a773ddce62afa7bb4da76c287e0ed3ed10452512de82c051f17b49c608b1a259e16a3812c0de684f2cb1ee59296c375376f146e2b0cc299ef41ed8e6fdf0557ec8d95fa026970f8d47c8347fed1e37e018413c5e813d1726ea18bc926ed02840349ab3b2adc8758a9cd57be38e9e76869762a81bb79721ca1c031c9dfdc3735fe9318064b62c2a7e8e2ec099963257b0705aac812dbc8cc3fbeea81af7c0d592c7e2ad1c21e877d4ae392b13ac1b57a8311d406":"000000060000000447cc5b29dd0cecd01c382434a6d16864d51b60cdb2a9eed2419015d8524c717ce38a865d7a37da6c84f94621ad595f5d":0
 
+LMS negative test (corrupt Merkle path byte)
+# Corrupt one byte at index 200 in the Merkle authentication path to force internal failure.
+# The test modifies a valid test's data so that the left_node parameter of create_merkle_internal_value becomes invalid.
+# Since that corrupted data is not used by mbedtls_lms_verify before that invocation,
+# the test targets the check of the value returned by create_merkle_internal_value.
+lms_verify_test:"92d036bde8c45b8bb5dea2a072560b1e29fc4bb7dc4549ce90bccee8a6e962a1":"00000001000000042e758f2a0e8f301af58847b6973a15fe4856b91af88a1ff601e2f0e87bde33afbc39202a66e38931fbecd7d493cf957b37eeb57ed2e4d8f693b97adafa8241746d775cfb9471688d935e090581eb8586e7004d6b8855963d82ccb6f79df2d93dd35848556da6735def0f0c6c8fc969c1df692341f6a99626eff37d20226cef361c8802a995fa43535fe2336d8ae468c78eb6a7082e27c2c6317c034369b588e3d65a2eeac9804b427702dc49f681a841076813ed407399aa778259e7c34c750b556d296a384e1274facaba9e2214d197628f5df7b2bf3896fedeab377b8edb775d6e8d67f1474ba3066794447f8f8e0c13552a007557a1f1c3b9bd2b41d9b446c6bcf36c828fd4c80850a31ee603065f5cc90d198df03835195b14e27da7bf727a16081fcc787f1dc7fa6da8b9ff908fb2c02d6f2a183486de0e39cd7da7fcdee0c8e96876c56ad9b0b18e4e4999e2c81a618aa4b27e050ce488dbb1e79089131afacc446cdf15b625f4e011f8d8160bb93f326bca3bb56fa41e34893d55f17d746fc142297997c5dbbba8f6b6c80678168ba455f12bac6982e5192de5462a46e14a45a01ce9e07279aa301dfd0fa9a12c6a55059b19a19d7afbe99779ea130ddeeb5ecb67d2ddb6c1c5d198e421b78091efa5aa429e1eb052760c0d8e2eb0c0ced000e93f7f265611a385f77c0cece0496eb29010f710e70a768d3713f0b7fc60c8ce372dc3234f27c7a1c2776a939ef70c7be869337b967df2223d4f20dca697e3bb6d0e53bbad153ff08d579f60c8535710f253b90e73ee9a19e1e57df66ec6c85ad1b4cea28a9d62fc5a4cf130f70b910dbc7e6f0e6b0cce1a1b5ff106b7f0b101405c0989084b2c94977116b98d15d6062a8d77d660aa813d432cf3338484308b7beed10236081f52da44eb807f9a75fd4cc1ba998ef3fc2e4791712597c786dd46431468bb4a1975a6cd854a1da23912fc99160f51df484efc9371c2d8e028d9468635cf93226f5a8834d14cead59e5d2a61dd6440d7b91c903ae8823907b75595c4828c7710036b347dcfb67f8561e835a53f569c8b3a1cd4317b2a6b2243100ee3d9468f9191acf2276d18dde9ebf2e11a48ba1fc1a15dc51091d3358d8d1f65ec7d84b97bb1669a9141f74065454f08e5ef25432b7635b8ec673ca70e4b3c25d07975a6fb725a56f28c1b5a81a6da2fe0a2c3474275926f9819a25b942462a68097e1cf6d9ae94f6b1f76b54addaeda04f9fc8db025fd6c453e1ad928f9323bf1381fce1893938828612728185d22a3d45d21ce762c066ab53a582c487d76d431e5b8f65a382142dd823d4620931e5572a4e6aee69986421afa119634bc8ea88aa6535c4d619ca0e0af94934637bc0c834e5e2a7a2853fa73835d00e13e5f26ad085ef66c8efb60097860cb199e03596a3b8f0ec78690d527bbc9363dd9702226788b1529871df74918ae2a4e02745043bd5ee8ab027826fb4cd54b0c27d99076757a1b41e2725ec02adc7926e8213796a8aa1740a2dc675437771e0364a83b0bd64c9620f6c203d92626ff29ef736eac0e13c71fd1957333ee0048000000061f7b7d6f916710efe9ed625ae689c67b3cc1cdf0d672e58c0b86b3839bbba2c243dcda2e63b26f5efa39ced6095a54625e67ab25d3df068e903eaaee894ac0f1fdeb4a2f1390f655db3608583eacfb0be4282f7bd1c42c5d748d524d7cdcd45878dea56cbc11a63bebbd74a5413ce72a931b1d4794c78c4cf16315bf2e055bb3305fe0272c8b916856cc27aa7a773ddce62afa7bb4da76c287e0ed3ed10452512de82c051f17b49c608b1a259e16a3812c0de684f2cb1ee59296c375376f146e2b0cc299ef41ed8e6fdf0557ec8d95fa026970f8d47c8347fed1e37e018413c5e813d1726ea18bc926ed02840349ab3b2adc8758a9cd57be38e9e76869762a81bb79721ca1c031c9dfdc3735fe9318064b62c2a7e8e2ec099963257b0705aac812dbc8cc3fbeea81af7c0d592c7e2ad1c21e877d4ae392b13ac1b57a8311d406":"000000060000000447cc5b29dd0cecd01c382434a6d16864d51b60cdb2a9eed2419015d8524c717ce38a865d7a37da6c84f94621ad595f5d":MBEDTLS_ERR_LMS_VERIFY_FAILED
+
 LMS negative test (invalid lms type) #1
 # This test uses the data from hash-sigs interop test #1. This test has a valid
 # LMOTS type (0x4) but an invalid LMS type (0x5), and should fail.
@@ -212,6 +219,12 @@
 # test should fail to verify the signature.
 lms_verify_test:"bfff9cd687351db88a98c71fd2f9b927a0ee600130a112533b791041d30cb91665fc369a5ac7cc9a04547414ac45288081d19d4a600579c73ac4bc953de03ad6":"0000040000000004e474c96c496b231ecedcd92566ab3e1cdfac83f7e56abaae6571401e212e59bdbcc18105e0709249510d13d7ae1091558c217033316ac70a36aae764bd0f4032e369453c634b81061079d216d03d3c55976a1aabc00287b307297ae03587ba20839460daae85d26dfcef7638c10a1d8559612e5e9ced1a4205a52ca0ce88e58602e59cf9ab34adf2e958e56570573297b99f733fbbf58d2440526fd4dc15c5509e8a11405f6c08772abcf58731fbf9a73642670e3247c5f70905f0fa81f6174bf32977209923507525a170fcd260e81f04193583fbcd305ac245c80eb337ca326fd1105e73748fab8a1f0c8d8a99f011718e7aae027a34d2a85ff18769fa277810126a86b51b096a04d8e28a4fb8c5e14e50a67cb1ee88e43e5cc077902442f5d9c55ac2b8acdd76c67bc740c6083aba4e3cb404c23f1f3118337563fef6a4b01fb476810c5b5682d0aecdccd55c85a4af50e9150f7d83dcccd8e822a302e6e5a52e00505e6e65338dcfb9cfbe22594e9e18ebde36af29450c5ea31523019cf64fd6eca8c77d98c2a146dcedd51bf6c61c1f7cacbce3ab20c8606930cc42737e17f2703cf0980aef560768d1ac5585c05a60a5f94db15f5ac4d4df5cbd81430878d4e9b77346e3a6538b80b80873e3e6c37860470091979296631440adb8cc71991aba2a4dd2884764878306fe774a25512cfbf080f2829ea2903ffa748dd187c21aef918ee3436a1bd336c3d09cc1f748d7528db90a98f69078b82c4d23de7bcec092a292d2b8cac71a5c87d008f128b89a5e608a4501aef41e9f17e4056ed4767957188f780159daebf327751386980b0fca5a2d36b141acff957f46ce2381897099619475db9d3a613e7ef98b056f42b4d6eafb1d62eebbe46a7502f893fbd36ccfb12a280f45ffb93f050eb280bf0a6cd640abdea8590bffb98bdb29ee3a31daa0fa3ab35fee11dc1b7d1fcea82b0e284b2e35b34e77c3f401ed887e7fc6c97b327f76f99caca2f355afa2753a8923bfb06fb2a9df08d31c93882e34ef5a3cccc9d078855334bdf909ae418b177724c42fb1d586d212c4474932acce295236030f4379158957300fe9fdc5cc9145e3ded50cf9f5a8e19321961536c4a47fffc3eb4383fb78a5d2aeed5b45b92132b5e2a53e3b67841fa2e1bd217ee2c30812c4eb1bd4f8c85b328e23d27f12a2fad5c6b236c87f8fd1aad441416e53ebd4d45d4bf601b94eb37dc9a065218ae58e69dba1250bb20626baeda961b3ef11d217697e73f41fa3870d726a032bc4a388fb12c023822945df058e22f54e5f6377eab34297c57883515204fc189d0d4b0ad9bacb24acf7f9d55e7c6368bb8ababd7622f586ec22683306c5d88d5244219a3952adbd85c89893a441a58b532e15600cd5afdbb5b441e1670b72656c7995189bdf993154e09912db8c4ddaff0e75591720230cf99c8b71cd841dffc4372c5e0f9ff906a379d28d6884351609bf7c849ebfabfb049ae986bbb8467251dbf5ccdd05a86ff6ce1392f7ca1bd49595ad9ad805d71b389afab1865f7f69dc24662af19934f025ced212536509500c132aec000000068b991bed50319a6cb9ff040b92f1563889b3787c37145fc9737d4643f66ade33ebd85a2c29b8c64a581cff01b89d59807d6fade2d2c88872f77d0ed83d97c4b5438681d0b95feb973125e4ee70ebe11699290b831e86571e36513a71f159d48ce563f6814cc2a89851d2520c5275b34cc83614cab14c0d197166580d800ee6b9004b8fd72daac8d73c36c1623c37be93ba49a06c4efde238a3a10a05daba5d4942f7de52648af2be31f33e723b3605346282f5d5e356c5d0004eea40fe0b80abf658f6c96c56319ab53d7fefb5879e0136d1cf320973a2f47c1ee3d21554910f09d17afac4607657c4309890957a4954bf86e2a8491ba37dd88b2c3fe3c7edebd767c400bc23e40d165b27133c726b90bc26cbb2a86a6aa400c47aa7ffc538388de8490b9349afa53b814ffe2a56ff16a496e9648284193754f989f6f12aeb6e":"0000000600000004d96bb26744d99ef624e32161c36d3d6efcdd0484e2b17a6dd183125be4b1af1cda931a91a3acb1151877c174f7943fd9":MBEDTLS_ERR_LMS_VERIFY_FAILED
 
+LMS public key import: truncated input below minimum valid size
+# This test provides an input buffer that is one byte shorter than the minimum required
+# size (MBEDTLS_LMS_TYPE_LEN - 1). The import operation is expected to fail gracefully,
+# without attempting to read beyond the end of the buffer.
+lms_import_export_test:"000000":MBEDTLS_ERR_LMS_BAD_INPUT_DATA
+
 LMS import/export test
 # This test uses the key from hsslms interop test 1, imports it, exports it and
 # tests that it is the same. It also checks if the export correctly fail when
diff --git a/tests/suites/test_suite_pem.data b/tests/suites/test_suite_pem.data
index 007ba10..11c54b7 100644
--- a/tests/suites/test_suite_pem.data
+++ b/tests/suites/test_suite_pem.data
@@ -49,10 +49,22 @@
 depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
 mbedtls_pem_read_buffer:"-----BEGIN EC PRIVATE KEY-----":"-----END EC PRIVATE KEY-----":"-----BEGIN EC PRIVATE KEY-----\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: DES-EDE3-CBC,AA94892A169FA426\n\nMAAA\n-----END EC PRIVATE KEY-----":"pwd":MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:""
 
-PEM read (malformed PEM AES-128-CBC)
+PEM read (malformed PEM AES-128-CBC: 3-byte ciphertext)
 depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
 mbedtls_pem_read_buffer:"-----BEGIN EC PRIVATE KEY-----":"-----END EC PRIVATE KEY-----":"-----BEGIN EC PRIVATE KEY-----\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: AES-128-CBC,AA94892A169FA426AA94892A169FA426\n\nMAAA\n-----END EC PRIVATE KEY-----":"pwd":MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:""
 
+PEM read (malformed PEM AES-128-CBC: 1-byte ciphertext)
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
+mbedtls_pem_read_buffer:"-----BEGIN EC PRIVATE KEY-----":"-----END EC PRIVATE KEY-----":"-----BEGIN EC PRIVATE KEY-----\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: AES-128-CBC,7BA38DE00F67851E4207216809C3BB15\n\n8Q==-----END EC PRIVATE KEY-----":"pwd":MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:""
+
+PEM read (malformed PEM AES-128-CBC: empty ciphertext)
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
+mbedtls_pem_read_buffer:"-----BEGIN EC PRIVATE KEY-----":"-----END EC PRIVATE KEY-----":"-----BEGIN EC PRIVATE KEY-----\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: AES-128-CBC,7BA38DE00F67851E4207216809C3BB15\n\n-----END EC PRIVATE KEY-----":"pwd":MBEDTLS_ERR_PEM_BAD_INPUT_DATA:""
+
+PEM read (malformed PEM AES-128-CBC: base64 with missing equals)
+depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
+mbedtls_pem_read_buffer:"-----BEGIN EC PRIVATE KEY-----":"-----END EC PRIVATE KEY-----":"-----BEGIN EC PRIVATE KEY-----\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: AES-128-CBC,7BA38DE00F67851E4207216809C3BB15\n\n8Q-----END EC PRIVATE KEY-----":"pwd":MBEDTLS_ERR_PEM_INVALID_DATA + MBEDTLS_ERR_BASE64_INVALID_CHARACTER:""
+
 # The output sequence's length is not multiple of block size (16 bytes). This
 # proves that the pem_context->len value is properly updated based on the SEQUENCE
 # length read from the decoded ASN.1 data (i.e. extra padding, if any, is ignored).
diff --git a/tests/suites/test_suite_pem.function b/tests/suites/test_suite_pem.function
index 091cbd1..342ca52 100644
--- a/tests/suites/test_suite_pem.function
+++ b/tests/suites/test_suite_pem.function
@@ -15,16 +15,16 @@
 
 
     ret = mbedtls_pem_write_buffer(start, end, buf->x, buf->len, NULL, 0, &olen);
-    TEST_ASSERT(ret == MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL);
+    TEST_EQUAL(ret, MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL);
 
     check_buf = (unsigned char *) mbedtls_calloc(1, olen);
     TEST_ASSERT(check_buf != NULL);
 
     ret = mbedtls_pem_write_buffer(start, end, buf->x, buf->len, check_buf, olen, &olen2);
 
-    TEST_ASSERT(olen2 <= olen);
-    TEST_ASSERT(olen > strlen((char *) result_str));
-    TEST_ASSERT(ret == 0);
+    TEST_LE_U(olen2, olen);
+    TEST_LE_U(strlen((char *) result_str) + 1, olen);
+    TEST_EQUAL(ret, 0);
     TEST_ASSERT(strncmp((char *) check_buf, (char *) result_str, olen) == 0);
 
 exit:
@@ -76,15 +76,14 @@
 
     ret = mbedtls_pem_read_buffer(&ctx, header, footer, (unsigned char *) data,
                                   (unsigned char *) pwd, pwd_len, &use_len);
-    TEST_ASSERT(ret == res);
+    TEST_EQUAL(ret, res);
     if (ret != 0) {
         goto exit;
     }
 
     use_len = 0;
     buf = mbedtls_pem_get_buffer(&ctx, &use_len);
-    TEST_EQUAL(use_len, out->len);
-    TEST_ASSERT(memcmp(out->x, buf, out->len) == 0);
+    TEST_MEMORY_COMPARE(out->x, out->len, buf, use_len);
 
 exit:
     mbedtls_pem_free(&ctx);
diff --git a/tests/suites/test_suite_psa_crypto.concurrent.data b/tests/suites/test_suite_psa_crypto.concurrent.data
new file mode 100644
index 0000000..94fafef
--- /dev/null
+++ b/tests/suites/test_suite_psa_crypto.concurrent.data
@@ -0,0 +1,188 @@
+PSA concurrently import/exercise same key: RSA keypair, PKCS#1 v1.5 raw
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT
+concurrently_use_same_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:100
+
+PSA concurrently import/exercise same key: RSA keypair, PSS-SHA-256
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT
+concurrently_use_same_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):100
+
+PSA concurrently import/exercise same key: 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_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT
+concurrently_use_same_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):100
+
+PSA concurrently import/exercise same key: RSA public key, PKCS#1 v1.5 raw
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY
+concurrently_use_same_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:100
+
+PSA concurrently import/exercise same key: RSA public key, PSS-SHA-256
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY
+concurrently_use_same_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):100
+
+PSA concurrently import/exercise same key: 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
+concurrently_use_same_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):100
+
+PSA concurrently import/exercise same key: ECP SECP256R1 keypair, ECDSA
+depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256
+concurrently_use_same_persistent_key:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_ECDSA_ANY:100
+
+PSA concurrently import/exercise same key: ECP SECP256R1 keypair, deterministic ECDSA
+depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256
+concurrently_use_same_persistent_key:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):100
+
+PSA concurrently import/exercise same key: ECP SECP256R1 keypair, ECDH
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256
+concurrently_use_same_persistent_key:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_ECDH:100
+
+PSA concurrently import/exercise same key: HKDF SHA-256
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
+concurrently_use_same_persistent_key:"c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0":PSA_KEY_TYPE_DERIVE:192:PSA_ALG_HKDF(PSA_ALG_SHA_256):100
+
+PSA concurrently import/exercise same key: TLS 1.2 PRF SHA-256
+depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF
+concurrently_use_same_persistent_key:"c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0":PSA_KEY_TYPE_DERIVE:192:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):100
+
+PSA concurrent key generation: bad type (RSA public key)
+depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT:0:8:5
+
+PSA concurrent key generation: raw data, 0 bits: invalid argument
+depends_on:MBEDTLS_THREADING_PTHREAD
+# The spec allows either INVALID_ARGUMENT or NOT_SUPPORTED
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:0:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT:0:8:5
+
+PSA concurrent key generation: raw data, 7 bits: invalid argument
+depends_on:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:7:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT:0:8:5
+
+PSA concurrent key generation: raw data, 8 bits
+depends_on:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation- raw data, 9 bits: invalid argument
+depends_on:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:9:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT:0:8:5
+
+PSA concurrent key generation: raw data, (MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8 bits
+depends_on:MBEDTLS_THREADING_PTHREAD:MBEDTLS_PSA_KEY_BUFFER_MAX_SIZE >= (MBEDTLS_CTR_DRBG_MAX_REQUEST + 1)
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:(MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: raw data, (2 * MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8 bits
+depends_on:MBEDTLS_THREADING_PTHREAD:MBEDTLS_PSA_KEY_BUFFER_MAX_SIZE >= (2 * MBEDTLS_CTR_DRBG_MAX_REQUEST + 1)
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:(2 * MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: raw data, 65528 bits (large key, ok if it fits)
+depends_on:MBEDTLS_THREADING_PTHREAD:MBEDTLS_PSA_KEY_BUFFER_MAX_SIZE > PSA_BITS_TO_BYTES(65528)
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:65528:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS:1:8:5
+
+PSA concurrent key generation: raw data, 65536 bits (not supported)
+depends_on:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:65536:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_NOT_SUPPORTED:0:8:5
+
+PSA concurrent key generation: AES, 128 bits, CTR
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: AES, 128 bits, GCM
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_GCM:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: DES, 64 bits, CBC-nopad
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DES:64:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_NO_PADDING:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: DES, 128 bits, CBC-nopad
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_NO_PADDING:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: DES, 192 bits, CBC-nopad
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DES:192:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_NO_PADDING:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: invalid key size: AES, 64 bits
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_AES:64:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_ERROR_INVALID_ARGUMENT:0:8:5
+
+PSA concurrent key generation: RSA, minimum allowed key size, good, sign (PKCS#1 v1.5)
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS > 128:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: RSA, 1032 bits, good, sign (PKCS#1 v1.5)
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS <= 1032:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:1032:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: RSA, 1024 bits, good, sign (PSS SHA-256)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS <= 1024:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys: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:8:5
+
+PSA concurrent key generation: 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_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS <= 1024:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys: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:8:5
+
+PSA concurrent key generation: RSA, minimum allowed key size, good, encrypt (PKCS#1 v1.5)
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS >= 256:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS <= 2048:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: RSA, 1024 bits, good, encrypt (OAEP SHA-256)
+depends_on:PSA_WANT_ALG_RSA_OAEP:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS <= 1024:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: RSA, 0 bits: invalid
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_THREADING_PTHREAD
+# The spec allows either INVALID_ARGUMENT or NOT_SUPPORTED
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_INVALID_ARGUMENT:0:8:5
+
+PSA concurrent key generation: RSA, size not multiple of 8: not supported
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS + 62:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_NOT_SUPPORTED:0:8:5
+
+PSA concurrent key generation: RSA, size not multiple of 2: not supported
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS + 63:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_NOT_SUPPORTED:0:8:5
+
+PSA concurrent key generation: RSA, maximum size exceeded
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_MAX_KEY_BITS+8:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_NOT_SUPPORTED:0:8:5
+
+PSA concurrent key generation: ECC, SECP256R1, good
+depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_ECDSA_ANY:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: ECC, SECP256R1, incorrect bit size
+depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256:MBEDTLS_THREADING_PTHREAD
+# INVALID_ARGUMENT would make more sense, but our code as currently structured
+# doesn't fully relate the curve with its size.
+concurrently_generate_keys:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_ECDSA_ANY:PSA_ERROR_NOT_SUPPORTED:0:8:5
+
+PSA concurrent key generation: ECC, Curve25519, good
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_MONTGOMERY_255:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY):255:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: ECC, Curve448, good
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_MONTGOMERY_448:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY):448:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: FFDH, 2048 bits, good
+depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:PSA_WANT_DH_RFC7919_2048:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):2048:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: FFDH, 3072 bits, good
+depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:PSA_WANT_DH_RFC7919_3072:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):3072:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: FFDH, 4096 bits, good
+depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:PSA_WANT_DH_RFC7919_4096:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):4096:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: FFDH, 6144 bits, good
+depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:PSA_WANT_DH_RFC7919_6144:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):6144:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: FFDH, 8192 bits, good
+depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:PSA_WANT_DH_RFC7919_8192:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):8192:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: FFDH, 1024 bits, invalid bits
+depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):1024:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_ERROR_NOT_SUPPORTED:0:8:5
+
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 038d912..22ecab0 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -4295,50 +4295,6 @@
 depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF
 import_and_exercise_key:"c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0":PSA_KEY_TYPE_DERIVE:192:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256)
 
-PSA concurrently import/exercise same key: RSA keypair, PKCS#1 v1.5 raw
-depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT
-concurrently_use_same_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:100
-
-PSA concurrently import/exercise same key: RSA keypair, PSS-SHA-256
-depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT
-concurrently_use_same_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):100
-
-PSA concurrently import/exercise same key: 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_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT
-concurrently_use_same_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):100
-
-PSA concurrently import/exercise same key: RSA public key, PKCS#1 v1.5 raw
-depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY
-concurrently_use_same_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:100
-
-PSA concurrently import/exercise same key: RSA public key, PSS-SHA-256
-depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY
-concurrently_use_same_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):100
-
-PSA concurrently import/exercise same key: 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
-concurrently_use_same_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):100
-
-PSA concurrently import/exercise same key: ECP SECP256R1 keypair, ECDSA
-depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256
-concurrently_use_same_persistent_key:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_ECDSA_ANY:100
-
-PSA concurrently import/exercise same key: ECP SECP256R1 keypair, deterministic ECDSA
-depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256
-concurrently_use_same_persistent_key:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):100
-
-PSA concurrently import/exercise same key: ECP SECP256R1 keypair, ECDH
-depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256
-concurrently_use_same_persistent_key:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_ECDH:100
-
-PSA concurrently import/exercise same key: HKDF SHA-256
-depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
-concurrently_use_same_persistent_key:"c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0":PSA_KEY_TYPE_DERIVE:192:PSA_ALG_HKDF(PSA_ALG_SHA_256):100
-
-PSA concurrently import/exercise same key: TLS 1.2 PRF SHA-256
-depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF
-concurrently_use_same_persistent_key:"c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0":PSA_KEY_TYPE_DERIVE:192:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):100
-
 PSA sign hash: RSA PKCS#1 v1.5, raw
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT
 sign_hash_deterministic:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN_RAW:"616263":"2c7744983f023ac7bb1c55529d83ed11a76a7898a1bb5ce191375a4aa7495a633d27879ff58eba5a57371c34feb1180e8b850d552476ebb5634df620261992f12ebee9097041dbbea85a42d45b344be5073ceb772ffc604954b9158ba81ec3dc4d9d65e3ab7aa318165f38c36f841f1c69cb1cfa494aa5cbb4d6c0efbafb043a"
@@ -7670,192 +7626,9 @@
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_ECDH
 generate_key_ext:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:0:"2a":PSA_ERROR_INVALID_ARGUMENT
 
-PSA concurrent key generation: bad type (RSA public key)
-depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT:0:8:5
-
-PSA concurrent key generation: raw data, 0 bits: invalid argument
-depends_on:MBEDTLS_THREADING_PTHREAD
-# The spec allows either INVALID_ARGUMENT or NOT_SUPPORTED
-concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:0:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT:0:8:5
-
-PSA concurrent key generation: raw data, 7 bits: invalid argument
-depends_on:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:7:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT:0:8:5
-
-PSA concurrent key generation: raw data, 8 bits
-depends_on:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS:0:8:5
-
-PSA concurrent key generation- raw data, 9 bits: invalid argument
-depends_on:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:9:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT:0:8:5
-
-PSA concurrent key generation: raw data, (MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8 bits
-depends_on:MBEDTLS_THREADING_PTHREAD:MBEDTLS_PSA_KEY_BUFFER_MAX_SIZE >= (MBEDTLS_CTR_DRBG_MAX_REQUEST + 1)
-concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:(MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS:0:8:5
-
-PSA concurrent key generation: raw data, (2 * MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8 bits
-depends_on:MBEDTLS_THREADING_PTHREAD:MBEDTLS_PSA_KEY_BUFFER_MAX_SIZE >= (2 * MBEDTLS_CTR_DRBG_MAX_REQUEST + 1)
-concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:(2 * MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS:0:8:5
-
-PSA concurrent key generation: raw data, 65528 bits (large key, ok if it fits)
-depends_on:MBEDTLS_THREADING_PTHREAD:MBEDTLS_PSA_KEY_BUFFER_MAX_SIZE > PSA_BITS_TO_BYTES(65528)
-concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:65528:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS:1:8:5
-
-PSA concurrent key generation: raw data, 65536 bits (not supported)
-depends_on:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:65536:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_NOT_SUPPORTED:0:8:5
-
-PSA concurrent key generation: AES, 128 bits, CTR
-depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_SUCCESS:0:8:5
-
-PSA concurrent key generation: AES, 128 bits, GCM
-depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_GCM:PSA_SUCCESS:0:8:5
-
-PSA concurrent key generation: DES, 64 bits, CBC-nopad
-depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_DES:64:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_NO_PADDING:PSA_SUCCESS:0:8:5
-
-PSA concurrent key generation: DES, 128 bits, CBC-nopad
-depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_DES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_NO_PADDING:PSA_SUCCESS:0:8:5
-
-PSA concurrent key generation: DES, 192 bits, CBC-nopad
-depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_DES:192:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_NO_PADDING:PSA_SUCCESS:0:8:5
-
-PSA concurrent key generation: invalid key size: AES, 64 bits
-depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_AES:64:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_ERROR_INVALID_ARGUMENT:0:8:5
-
-PSA concurrent key generation: RSA, minimum allowed key size, good, sign (PKCS#1 v1.5)
-depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS > 128:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_SUCCESS:0:8:5
-
-PSA concurrent key generation: RSA, 1032 bits, good, sign (PKCS#1 v1.5)
-depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS <= 1032:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:1032:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_SUCCESS:0:8:5
-
-PSA concurrent key generation: RSA, 1024 bits, good, sign (PSS SHA-256)
-depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS <= 1024:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys: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:8:5
-
-PSA concurrent key generation: 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_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS <= 1024:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys: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:8:5
-
-PSA concurrent key generation: RSA, minimum allowed key size, good, encrypt (PKCS#1 v1.5)
-depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS >= 256:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS <= 2048:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_SUCCESS:0:8:5
-
-PSA concurrent key generation: RSA, 1024 bits, good, encrypt (OAEP SHA-256)
-depends_on:PSA_WANT_ALG_RSA_OAEP:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS <= 1024:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):PSA_SUCCESS:0:8:5
-
-PSA concurrent key generation: RSA, 0 bits: invalid
-depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_THREADING_PTHREAD
-# The spec allows either INVALID_ARGUMENT or NOT_SUPPORTED
-concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_INVALID_ARGUMENT:0:8:5
-
-PSA concurrent key generation: RSA, size not multiple of 8: not supported
-depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS + 62:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_NOT_SUPPORTED:0:8:5
-
-PSA concurrent key generation: RSA, size not multiple of 2: not supported
-depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS + 63:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_NOT_SUPPORTED:0:8:5
-
-PSA concurrent key generation: RSA, maximum size exceeded
-depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_MAX_KEY_BITS+8:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_NOT_SUPPORTED:0:8:5
-
-PSA concurrent key generation: ECC, SECP256R1, good
-depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_ECDSA_ANY:PSA_SUCCESS:0:8:5
-
-PSA concurrent key generation: ECC, SECP256R1, incorrect bit size
-depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256:MBEDTLS_THREADING_PTHREAD
-# INVALID_ARGUMENT would make more sense, but our code as currently structured
-# doesn't fully relate the curve with its size.
-concurrently_generate_keys:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_ECDSA_ANY:PSA_ERROR_NOT_SUPPORTED:0:8:5
-
-PSA concurrent key generation: ECC, Curve25519, good
-depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_MONTGOMERY_255:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY):255:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_SUCCESS:0:8:5
-
-PSA concurrent key generation: ECC, Curve448, good
-depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_MONTGOMERY_448:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY):448:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_SUCCESS:0:8:5
-
-PSA concurrent key generation: FFDH, 2048 bits, good
-depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:PSA_WANT_DH_RFC7919_2048:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):2048:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_SUCCESS:0:8:5
-
-PSA concurrent key generation: FFDH, 3072 bits, good
-depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:PSA_WANT_DH_RFC7919_3072:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):3072:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_SUCCESS:0:8:5
-
-PSA concurrent key generation: FFDH, 4096 bits, good
-depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:PSA_WANT_DH_RFC7919_4096:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):4096:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_SUCCESS:0:8:5
-
-PSA concurrent key generation: FFDH, 6144 bits, good
-depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:PSA_WANT_DH_RFC7919_6144:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):6144:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_SUCCESS:0:8:5
-
-PSA concurrent key generation: FFDH, 8192 bits, good
-depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:PSA_WANT_DH_RFC7919_8192:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):8192:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_SUCCESS:0:8:5
-
-PSA concurrent key generation: FFDH, 1024 bits, invalid bits
-depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:MBEDTLS_THREADING_PTHREAD
-concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):1024:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_ERROR_NOT_SUPPORTED:0:8:5
-
 Key production parameters initializers
 key_production_parameters_init:
 
-PSA import persistent key: raw data, 8 bits
-depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
-persistent_key_load_key_from_storage:"2a":PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0:IMPORT_KEY
-
-PSA import persistent key: AES, 128 bits, exportable
-depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PSA_CRYPTO_STORAGE_C
-persistent_key_load_key_from_storage:"2b7e151628aed2a6abf7158809cf4f3c":PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:IMPORT_KEY
-
-PSA import persistent key: AES, 128 bits, non-exportable
-depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PSA_CRYPTO_STORAGE_C
-persistent_key_load_key_from_storage:"2b7e151628aed2a6abf7158809cf4f3c":PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR:IMPORT_KEY
-
-PSA generate persistent key: raw data, 8 bits, exportable
-depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
-persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0:GENERATE_KEY
-
-PSA generate persistent key: AES, 128 bits, exportable
-depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PSA_CRYPTO_STORAGE_C
-persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:GENERATE_KEY
-
-PSA generate persistent key: AES, 128 bits, non-exportable
-depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PSA_CRYPTO_STORAGE_C
-persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:GENERATE_KEY
-
-PSA generate persistent key: DES, 64 bits, exportable
-depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES:MBEDTLS_PSA_CRYPTO_STORAGE_C
-persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_DES:64:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_NO_PADDING:GENERATE_KEY
-
-PSA generate persistent key: RSA, minimum size key, exportable
-depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_CRYPTO_STORAGE_C:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS >= 512
-persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):GENERATE_KEY
-
-PSA generate persistent key: ECC, SECP256R1, exportable
-depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:MBEDTLS_PSA_CRYPTO_STORAGE_C
-persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_ECDSA_ANY:GENERATE_KEY
-
-PSA derive persistent key: HKDF SHA-256, exportable
-persistent_key_load_key_from_storage:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_TYPE_RAW_DATA:1024:PSA_KEY_USAGE_EXPORT:0:DERIVE_KEY
-
 ECP group ID <-> PSA family - SECP192R1
 depends_on:PSA_WANT_ECC_SECP_R1_192
 ecc_conversion_functions:MBEDTLS_ECP_DP_SECP192R1:PSA_ECC_FAMILY_SECP_R1:192
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index da6c1c4..b4ff66a 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -343,7 +343,7 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
-    psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
+    psa_aead_operation_t operation = psa_aead_operation_init_short();
     unsigned char *output_data = NULL;
     unsigned char *part_data = NULL;
     unsigned char *final_data = NULL;
@@ -598,7 +598,7 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
-    psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
+    psa_mac_operation_t operation = psa_mac_operation_init_short();
     unsigned char mac[PSA_MAC_MAX_SIZE];
     size_t part_offset = 0;
     size_t part_length = 0;
@@ -2147,7 +2147,7 @@
 {
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
+    psa_mac_operation_t operation = psa_mac_operation_init_short();
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t policy_alg = policy_alg_arg;
     psa_algorithm_t exercise_alg = exercise_alg_arg;
@@ -2247,7 +2247,7 @@
 {
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
+    psa_cipher_operation_t operation = psa_cipher_operation_init_short();
     psa_key_usage_t policy_usage = policy_usage_arg;
     size_t output_buffer_size = 0;
     size_t input_buffer_size = 0;
@@ -2338,7 +2338,7 @@
 {
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
+    psa_aead_operation_t operation = psa_aead_operation_init_short();
     psa_key_usage_t policy_usage = policy_usage_arg;
     psa_status_t status;
     psa_status_t expected_status = expected_status_arg;
@@ -2596,7 +2596,7 @@
 {
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
     psa_status_t status;
 
     PSA_ASSERT(psa_crypto_init());
@@ -2647,7 +2647,7 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_key_type_t key_type = key_type_arg;
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
     psa_status_t status;
     psa_status_t expected_status = expected_status_arg;
 
@@ -2730,7 +2730,7 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_key_type_t key_type = key_type_arg;
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
     psa_status_t status;
     psa_status_t expected_status = expected_status_arg;
 
@@ -2917,13 +2917,15 @@
      * Clang 5 complains when `-Wmissing-field-initializers` is used, even
      * though it's OK by the C standard. We could test for this, but we'd need
      * to suppress the Clang warning for the test. */
+    psa_hash_operation_t short_wrapper = psa_hash_operation_init_short();
     psa_hash_operation_t func = psa_hash_operation_init();
     psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
     psa_hash_operation_t zero;
-
     memset(&zero, 0, sizeof(zero));
 
     /* A freshly-initialized hash operation should not be usable. */
+    TEST_EQUAL(psa_hash_update(&short_wrapper, input, sizeof(input)),
+               PSA_ERROR_BAD_STATE);
     TEST_EQUAL(psa_hash_update(&func, input, sizeof(input)),
                PSA_ERROR_BAD_STATE);
     TEST_EQUAL(psa_hash_update(&init, input, sizeof(input)),
@@ -2932,6 +2934,7 @@
                PSA_ERROR_BAD_STATE);
 
     /* A default hash operation should be abortable without error. */
+    PSA_ASSERT(psa_hash_abort(&short_wrapper));
     PSA_ASSERT(psa_hash_abort(&func));
     PSA_ASSERT(psa_hash_abort(&init));
     PSA_ASSERT(psa_hash_abort(&zero));
@@ -2947,7 +2950,7 @@
     size_t output_size = 0;
     size_t output_length = 0;
     psa_status_t expected_status = expected_status_arg;
-    psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
+    psa_hash_operation_t operation = psa_hash_operation_init_short();
     psa_status_t status;
 
     PSA_ASSERT(psa_crypto_init());
@@ -2993,7 +2996,7 @@
     uint8_t *output = NULL;
     size_t output_size = output_size_arg;
     size_t output_length = INVALID_EXPORT_LENGTH;
-    psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
+    psa_hash_operation_t operation = psa_hash_operation_init_short();
     psa_status_t expected_status = expected_status_arg;
     psa_status_t status;
 
@@ -3040,7 +3043,7 @@
 {
     psa_algorithm_t alg = alg_arg;
     psa_status_t expected_status = expected_status_arg;
-    psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
+    psa_hash_operation_t operation = psa_hash_operation_init_short();
     psa_status_t status;
 
     PSA_ASSERT(psa_crypto_init());
@@ -3078,7 +3081,7 @@
     psa_algorithm_t alg = alg_arg;
     uint8_t output[PSA_HASH_MAX_SIZE + 1];
     size_t output_length = INVALID_EXPORT_LENGTH;
-    psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
+    psa_hash_operation_t operation = psa_hash_operation_init_short();
     size_t i;
 
     PSA_ASSERT(psa_crypto_init());
@@ -3188,7 +3191,7 @@
     };
     unsigned char hash[sizeof(valid_hash)] = { 0 };
     size_t hash_len;
-    psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
+    psa_hash_operation_t operation = psa_hash_operation_init_short();
 
     PSA_ASSERT(psa_crypto_init());
 
@@ -3292,7 +3295,7 @@
         0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb
     };
     size_t expected_size = PSA_HASH_LENGTH(alg);
-    psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
+    psa_hash_operation_t operation = psa_hash_operation_init_short();
 
     PSA_ASSERT(psa_crypto_init());
 
@@ -3326,7 +3329,7 @@
     psa_algorithm_t alg = PSA_ALG_SHA_256;
     unsigned char hash[PSA_HASH_MAX_SIZE];
     size_t expected_size = PSA_HASH_LENGTH(alg);
-    psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
+    psa_hash_operation_t operation = psa_hash_operation_init_short();
     size_t hash_len;
 
     PSA_ASSERT(psa_crypto_init());
@@ -3347,11 +3350,11 @@
 {
     psa_algorithm_t alg = PSA_ALG_SHA_256;
     unsigned char hash[PSA_HASH_MAX_SIZE];
-    psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
-    psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
-    psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
-    psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
-    psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
+    psa_hash_operation_t op_source = psa_hash_operation_init_short();
+    psa_hash_operation_t op_init = psa_hash_operation_init_short();
+    psa_hash_operation_t op_setup = psa_hash_operation_init_short();
+    psa_hash_operation_t op_finished = psa_hash_operation_init_short();
+    psa_hash_operation_t op_aborted = psa_hash_operation_init_short();
     size_t hash_len;
 
     PSA_ASSERT(psa_crypto_init());
@@ -3392,11 +3395,11 @@
 {
     psa_algorithm_t alg = PSA_ALG_SHA_256;
     unsigned char hash[PSA_HASH_MAX_SIZE];
-    psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
-    psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
-    psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
-    psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
-    psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
+    psa_hash_operation_t op_init = psa_hash_operation_init_short();
+    psa_hash_operation_t op_setup = psa_hash_operation_init_short();
+    psa_hash_operation_t op_finished = psa_hash_operation_init_short();
+    psa_hash_operation_t op_aborted = psa_hash_operation_init_short();
+    psa_hash_operation_t op_target = psa_hash_operation_init_short();
     size_t hash_len;
 
     PSA_ASSERT(psa_crypto_init());
@@ -3437,13 +3440,16 @@
      * Clang 5 complains when `-Wmissing-field-initializers` is used, even
      * though it's OK by the C standard. We could test for this, but we'd need
      * to suppress the Clang warning for the test. */
+    psa_mac_operation_t short_wrapper = psa_mac_operation_init_short();
     psa_mac_operation_t func = psa_mac_operation_init();
     psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
     psa_mac_operation_t zero;
-
     memset(&zero, 0, sizeof(zero));
 
     /* A freshly-initialized MAC operation should not be usable. */
+    TEST_EQUAL(psa_mac_update(&short_wrapper,
+                              input, sizeof(input)),
+               PSA_ERROR_BAD_STATE);
     TEST_EQUAL(psa_mac_update(&func,
                               input, sizeof(input)),
                PSA_ERROR_BAD_STATE);
@@ -3455,6 +3461,7 @@
                PSA_ERROR_BAD_STATE);
 
     /* A default MAC operation should be abortable without error. */
+    PSA_ASSERT(psa_mac_abort(&short_wrapper));
     PSA_ASSERT(psa_mac_abort(&func));
     PSA_ASSERT(psa_mac_abort(&init));
     PSA_ASSERT(psa_mac_abort(&zero));
@@ -3470,10 +3477,12 @@
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
     psa_status_t expected_status = expected_status_arg;
-    psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
+    psa_mac_operation_t operation = psa_mac_operation_init_short();
     psa_status_t status = PSA_ERROR_GENERIC_ERROR;
 #if defined(KNOWN_SUPPORTED_MAC_ALG)
-    const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
+    /* We need to tell the compiler that we meant to leave out the null character. */
+    const uint8_t smoke_test_key_data[16] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING =
+        "kkkkkkkkkkkkkkkk";
 #endif
 
     PSA_ASSERT(psa_crypto_init());
@@ -3513,7 +3522,7 @@
         0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
     };
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
+    psa_mac_operation_t operation = psa_mac_operation_init_short();
     uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
     size_t sign_mac_length = 0;
     const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
@@ -3678,7 +3687,7 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
-    psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
+    psa_mac_operation_t operation = psa_mac_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     uint8_t *actual_mac = NULL;
     size_t mac_buffer_size =
@@ -3764,7 +3773,7 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
-    psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
+    psa_mac_operation_t operation = psa_mac_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     uint8_t *perturbed_mac = NULL;
 
@@ -3862,13 +3871,18 @@
      * Clang 5 complains when `-Wmissing-field-initializers` is used, even
      * though it's OK by the C standard. We could test for this, but we'd need
      * to suppress the Clang warning for the test. */
+    psa_cipher_operation_t short_wrapper = psa_cipher_operation_init_short();
     psa_cipher_operation_t func = psa_cipher_operation_init();
     psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
     psa_cipher_operation_t zero;
-
     memset(&zero, 0, sizeof(zero));
 
     /* A freshly-initialized cipher operation should not be usable. */
+    TEST_EQUAL(psa_cipher_update(&short_wrapper,
+                                 input, sizeof(input),
+                                 output, sizeof(output),
+                                 &output_length),
+               PSA_ERROR_BAD_STATE);
     TEST_EQUAL(psa_cipher_update(&func,
                                  input, sizeof(input),
                                  output, sizeof(output),
@@ -3886,6 +3900,7 @@
                PSA_ERROR_BAD_STATE);
 
     /* A default cipher operation should be abortable without error. */
+    PSA_ASSERT(psa_cipher_abort(&short_wrapper));
     PSA_ASSERT(psa_cipher_abort(&func));
     PSA_ASSERT(psa_cipher_abort(&init));
     PSA_ASSERT(psa_cipher_abort(&zero));
@@ -3901,10 +3916,12 @@
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
     psa_status_t expected_status = expected_status_arg;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
+    psa_cipher_operation_t operation = psa_cipher_operation_init_short();
     psa_status_t status;
 #if defined(KNOWN_SUPPORTED_CIPHER_ALG)
-    const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
+    /* We need to tell the compiler that we meant to leave out the null character. */
+    const uint8_t smoke_test_key_data[16] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING =
+        "kkkkkkkkkkkkkkkk";
 #endif
 
     PSA_ASSERT(psa_crypto_init());
@@ -3940,7 +3957,7 @@
     psa_key_type_t key_type = PSA_KEY_TYPE_AES;
     psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
+    psa_cipher_operation_t operation = psa_cipher_operation_init_short();
     unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES)] = { 0 };
     const uint8_t key_data[] = {
         0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
@@ -4126,7 +4143,7 @@
     size_t output_buffer_size = 0;
     size_t output_length = 0;
     size_t function_output_length;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
+    psa_cipher_operation_t operation = psa_cipher_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 
     if (PSA_ERROR_BAD_STATE != expected_status) {
@@ -4191,7 +4208,7 @@
                                        int expected_result)
 {
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
+    psa_cipher_operation_t operation = psa_cipher_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     size_t output_buffer_size = 0;
     unsigned char *output = NULL;
@@ -4226,7 +4243,7 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
+    psa_cipher_operation_t operation = psa_cipher_operation_init_short();
     uint8_t iv[1] = { 0x5a };
     unsigned char *output = NULL;
     size_t output_buffer_size = 0;
@@ -4343,7 +4360,7 @@
     psa_algorithm_t alg = alg_arg;
     psa_key_type_t key_type = key_type_arg;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
+    psa_cipher_operation_t operation = psa_cipher_operation_init_short();
     psa_status_t status;
 
     PSA_ASSERT(psa_crypto_init());
@@ -4393,7 +4410,7 @@
     size_t output2_buffer_size = 0;
     size_t output2_length = 0;
     size_t function_output_length = 0;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
+    psa_cipher_operation_t operation = psa_cipher_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 
     PSA_ASSERT(psa_crypto_init());
@@ -4477,7 +4494,7 @@
     size_t output_buffer_size = 0;
     size_t function_output_length = 0;
     size_t total_output_length = 0;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
+    psa_cipher_operation_t operation = psa_cipher_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 
     PSA_ASSERT(psa_crypto_init());
@@ -4576,7 +4593,7 @@
     size_t output_buffer_size = 0;
     size_t function_output_length = 0;
     size_t total_output_length = 0;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
+    psa_cipher_operation_t operation = psa_cipher_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 
     PSA_ASSERT(psa_crypto_init());
@@ -4675,7 +4692,7 @@
     size_t output_buffer_size = 0;
     size_t output_length = 0;
     size_t function_output_length;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
+    psa_cipher_operation_t operation = psa_cipher_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 
     if (PSA_ERROR_BAD_STATE != expected_status) {
@@ -4888,8 +4905,8 @@
     size_t output2_buffer_size = 0;
     size_t output2_length = 0;
     size_t function_output_length;
-    psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
-    psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
+    psa_cipher_operation_t operation1 = psa_cipher_operation_init_short();
+    psa_cipher_operation_t operation2 = psa_cipher_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 
     PSA_ASSERT(psa_crypto_init());
@@ -5444,7 +5461,7 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
-    psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
+    psa_aead_operation_t operation = psa_aead_operation_init_short();
     /* Some tests try to get more than the maximum nonce length,
      * so allocate double. */
     uint8_t nonce_buffer[PSA_AEAD_NONCE_MAX_SIZE * 2];
@@ -5548,7 +5565,7 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
-    psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
+    psa_aead_operation_t operation = psa_aead_operation_init_short();
     uint8_t *nonce_buffer = NULL;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_status_t status = PSA_ERROR_GENERIC_ERROR;
@@ -5671,7 +5688,7 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
-    psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
+    psa_aead_operation_t operation = psa_aead_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_status_t status = PSA_ERROR_GENERIC_ERROR;
     psa_status_t expected_status = expected_status_arg;
@@ -5755,7 +5772,7 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
-    psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
+    psa_aead_operation_t operation = psa_aead_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_status_t status = PSA_ERROR_GENERIC_ERROR;
     psa_status_t expected_status = expected_status_arg;
@@ -5842,7 +5859,7 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
-    psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
+    psa_aead_operation_t operation = psa_aead_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_status_t status = PSA_ERROR_GENERIC_ERROR;
     psa_status_t expected_status = expected_status_arg;
@@ -5935,7 +5952,7 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
-    psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
+    psa_aead_operation_t operation = psa_aead_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_status_t status = PSA_ERROR_GENERIC_ERROR;
     psa_status_t expected_status = expected_status_arg;
@@ -5977,7 +5994,7 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
-    psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
+    psa_aead_operation_t operation = psa_aead_operation_init_short();
     unsigned char *output_data = NULL;
     unsigned char *final_data = NULL;
     size_t output_size = 0;
@@ -6879,7 +6896,7 @@
     size_t max_completes = 0;
 
     psa_sign_hash_interruptible_operation_t operation =
-        psa_sign_hash_interruptible_operation_init();
+        psa_sign_hash_interruptible_operation_init_short();
 
     PSA_ASSERT(psa_crypto_init());
 
@@ -7061,7 +7078,7 @@
 
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_sign_hash_interruptible_operation_t operation =
-        psa_sign_hash_interruptible_operation_init();
+        psa_sign_hash_interruptible_operation_init_short();
 
     TEST_CALLOC(signature, signature_size);
 
@@ -7272,9 +7289,9 @@
     size_t max_completes = 0;
 
     psa_sign_hash_interruptible_operation_t sign_operation =
-        psa_sign_hash_interruptible_operation_init();
+        psa_sign_hash_interruptible_operation_init_short();
     psa_verify_hash_interruptible_operation_t verify_operation =
-        psa_verify_hash_interruptible_operation_init();
+        psa_verify_hash_interruptible_operation_init_short();
 
     PSA_ASSERT(psa_crypto_init());
 
@@ -7367,7 +7384,7 @@
 
     PSA_ASSERT(psa_verify_hash_abort(&verify_operation));
 
-    verify_operation = psa_verify_hash_interruptible_operation_init();
+    verify_operation = psa_verify_hash_interruptible_operation_init_short();
 
     if (input_data->len != 0) {
         /* Flip a bit in the input and verify that the signature is now
@@ -7475,7 +7492,7 @@
     size_t max_completes = 0;
 
     psa_verify_hash_interruptible_operation_t operation =
-        psa_verify_hash_interruptible_operation_init();
+        psa_verify_hash_interruptible_operation_init_short();
 
     TEST_LE_U(signature_data->len, PSA_SIGNATURE_MAX_SIZE);
 
@@ -7645,7 +7662,7 @@
     size_t min_completes = 0;
     size_t max_completes = 0;
     psa_verify_hash_interruptible_operation_t operation =
-        psa_verify_hash_interruptible_operation_init();
+        psa_verify_hash_interruptible_operation_init_short();
 
     PSA_ASSERT(psa_crypto_init());
 
@@ -7754,9 +7771,9 @@
     size_t signature_length = 0xdeadbeef;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_sign_hash_interruptible_operation_t sign_operation =
-        psa_sign_hash_interruptible_operation_init();
+        psa_sign_hash_interruptible_operation_init_short();
     psa_verify_hash_interruptible_operation_t verify_operation =
-        psa_verify_hash_interruptible_operation_init();
+        psa_verify_hash_interruptible_operation_init_short();
 
     PSA_ASSERT(psa_crypto_init());
 
@@ -7910,9 +7927,9 @@
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     uint8_t *input_buffer = NULL;
     psa_sign_hash_interruptible_operation_t sign_operation =
-        psa_sign_hash_interruptible_operation_init();
+        psa_sign_hash_interruptible_operation_init_short();
     psa_verify_hash_interruptible_operation_t verify_operation =
-        psa_verify_hash_interruptible_operation_init();
+        psa_verify_hash_interruptible_operation_init_short();
 
     PSA_ASSERT(psa_crypto_init());
 
@@ -8041,9 +8058,9 @@
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
 
     psa_sign_hash_interruptible_operation_t sign_operation =
-        psa_sign_hash_interruptible_operation_init();
+        psa_sign_hash_interruptible_operation_init_short();
     psa_verify_hash_interruptible_operation_t verify_operation =
-        psa_verify_hash_interruptible_operation_init();
+        psa_verify_hash_interruptible_operation_init_short();
 
     PSA_ASSERT(psa_crypto_init());
 
@@ -8736,13 +8753,15 @@
      * though it's OK by the C standard. We could test for this, but we'd need
      * to suppress the Clang warning for the test. */
     size_t capacity;
+    psa_key_derivation_operation_t short_wrapper = psa_key_derivation_operation_init_short();
     psa_key_derivation_operation_t func = psa_key_derivation_operation_init();
     psa_key_derivation_operation_t init = PSA_KEY_DERIVATION_OPERATION_INIT;
     psa_key_derivation_operation_t zero;
-
     memset(&zero, 0, sizeof(zero));
 
     /* A default operation should not be able to report its capacity. */
+    TEST_EQUAL(psa_key_derivation_get_capacity(&short_wrapper, &capacity),
+               PSA_ERROR_BAD_STATE);
     TEST_EQUAL(psa_key_derivation_get_capacity(&func, &capacity),
                PSA_ERROR_BAD_STATE);
     TEST_EQUAL(psa_key_derivation_get_capacity(&init, &capacity),
@@ -8751,6 +8770,7 @@
                PSA_ERROR_BAD_STATE);
 
     /* A default operation should be abortable without error. */
+    PSA_ASSERT(psa_key_derivation_abort(&short_wrapper));
     PSA_ASSERT(psa_key_derivation_abort(&func));
     PSA_ASSERT(psa_key_derivation_abort(&init));
     PSA_ASSERT(psa_key_derivation_abort(&zero));
@@ -8762,7 +8782,7 @@
 {
     psa_algorithm_t alg = alg_arg;
     psa_status_t expected_status = expected_status_arg;
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
 
     PSA_ASSERT(psa_crypto_init());
 
@@ -8782,7 +8802,7 @@
     psa_algorithm_t alg = alg_arg;
     size_t capacity = capacity_arg;
     psa_status_t expected_status = expected_status_arg;
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
 
     PSA_ASSERT(psa_crypto_init());
 
@@ -8826,7 +8846,7 @@
     mbedtls_svc_key_id_t keys[] = { MBEDTLS_SVC_KEY_ID_INIT,
                                     MBEDTLS_SVC_KEY_ID_INIT,
                                     MBEDTLS_SVC_KEY_ID_INIT };
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     size_t i;
     psa_key_type_t output_key_type = output_key_type_arg;
@@ -8909,7 +8929,7 @@
 void derive_input_invalid_cost(int alg_arg, int64_t cost)
 {
     psa_algorithm_t alg = alg_arg;
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
 
     PSA_ASSERT(psa_crypto_init());
     PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
@@ -8931,7 +8951,7 @@
     psa_algorithm_t alg = alg_arg;
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     size_t key_type = PSA_KEY_TYPE_DERIVE;
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
     unsigned char input1[] = "Input 1";
     size_t input1_length = sizeof(input1);
     unsigned char input2[] = "Input 2";
@@ -8983,7 +9003,7 @@
     uint8_t output_buffer[16];
     size_t buffer_size = 16;
     size_t capacity = 0;
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
 
     TEST_ASSERT(psa_key_derivation_output_bytes(&operation,
                                                 output_buffer, buffer_size)
@@ -9030,7 +9050,7 @@
     psa_status_t statuses[] = { expected_status_arg1, expected_status_arg2,
                                 expected_status_arg3, expected_status_arg4 };
     size_t requested_capacity = requested_capacity_arg;
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
     uint8_t *expected_outputs[2] =
     { expected_output1->x, expected_output2->x };
     size_t output_sizes[2] =
@@ -9258,7 +9278,7 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_algorithm_t alg = alg_arg;
     size_t requested_capacity = requested_capacity_arg;
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
     unsigned char output_buffer[32];
     size_t expected_capacity = requested_capacity;
     size_t current_capacity;
@@ -9320,7 +9340,7 @@
                            int expected_output_status_arg)
 {
     psa_algorithm_t alg = PSA_ALG_TLS12_ECJPAKE_TO_PMS;
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
     psa_key_derivation_step_t step = (psa_key_derivation_step_t) derivation_step;
     uint8_t *output_buffer = NULL;
     psa_status_t status;
@@ -9377,7 +9397,7 @@
     psa_key_usage_t derived_usage = derived_usage_arg;
     psa_algorithm_t derived_alg = derived_alg_arg;
     size_t capacity = PSA_BITS_TO_BYTES(derived_bits);
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
 
@@ -9442,7 +9462,7 @@
     size_t bytes1 = bytes1_arg;
     size_t bytes2 = bytes2_arg;
     size_t capacity = bytes1 + bytes2;
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
     uint8_t *output_buffer = NULL;
     uint8_t *export_buffer = NULL;
     psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
@@ -9526,7 +9546,7 @@
     const psa_algorithm_t alg = alg_arg;
     const psa_key_type_t key_type = key_type_arg;
     const size_t bits = bits_arg;
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
     const size_t export_buffer_size =
         PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, bits);
     uint8_t *export_buffer = NULL;
@@ -9591,7 +9611,7 @@
     const size_t bits = bits_arg;
     psa_custom_key_parameters_t custom = PSA_CUSTOM_KEY_PARAMETERS_INIT;
     custom.flags = flags_arg;
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
     const size_t export_buffer_size =
         PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, bits);
     uint8_t *export_buffer = NULL;
@@ -9662,7 +9682,7 @@
     const size_t bits = bits_arg;
     psa_key_production_parameters_t *params = NULL;
     size_t params_data_length = 0;
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
     const size_t export_buffer_size =
         PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, bits);
     uint8_t *export_buffer = NULL;
@@ -9732,7 +9752,7 @@
     psa_key_type_t type = type_arg;
     size_t bits = bits_arg;
     psa_status_t expected_status = expected_status_arg;
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
     psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
 
@@ -9783,7 +9803,7 @@
     psa_algorithm_t alg = alg_arg;
     psa_algorithm_t our_key_alg = our_key_alg_arg;
     psa_key_type_t our_key_type = our_key_type_arg;
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_status_t expected_status = expected_status_arg;
     psa_status_t status;
@@ -9903,7 +9923,7 @@
     mbedtls_svc_key_id_t our_key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_algorithm_t alg = alg_arg;
     psa_key_type_t our_key_type = our_key_type_arg;
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     size_t actual_capacity;
     unsigned char output[16];
@@ -10000,7 +10020,7 @@
     mbedtls_svc_key_id_t our_key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_algorithm_t alg = alg_arg;
     psa_key_type_t our_key_type = our_key_type_arg;
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     uint8_t *actual_output = NULL;
 
@@ -10366,7 +10386,7 @@
     size_t bits = bits_arg;
     psa_key_usage_t usage_flags = usage_flags_arg;
     psa_algorithm_t alg = alg_arg;
-    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init_short();
     unsigned char *first_export = NULL;
     unsigned char *second_export = NULL;
     size_t export_size = PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits);
@@ -10503,7 +10523,7 @@
                    int expected_error_arg)
 {
     psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
-    psa_pake_operation_t operation = psa_pake_operation_init();
+    psa_pake_operation_t operation = psa_pake_operation_init_short();
     psa_algorithm_t alg = alg_arg;
     psa_pake_primitive_t primitive = primitive_arg;
     psa_key_type_t key_type_pw = key_type_pw_arg;
@@ -10727,8 +10747,8 @@
                            data_t *pw_data)
 {
     psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
-    psa_pake_operation_t server = psa_pake_operation_init();
-    psa_pake_operation_t client = psa_pake_operation_init();
+    psa_pake_operation_t server = psa_pake_operation_init_short();
+    psa_pake_operation_t client = psa_pake_operation_init_short();
     psa_algorithm_t alg = alg_arg;
     psa_algorithm_t hash_alg = hash_arg;
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
@@ -10780,17 +10800,17 @@
                     int client_input_first, int inj_err_type_arg)
 {
     psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
-    psa_pake_operation_t server = psa_pake_operation_init();
-    psa_pake_operation_t client = psa_pake_operation_init();
+    psa_pake_operation_t server = psa_pake_operation_init_short();
+    psa_pake_operation_t client = psa_pake_operation_init_short();
     psa_algorithm_t alg = alg_arg;
     psa_algorithm_t hash_alg = hash_arg;
     psa_algorithm_t derive_alg = derive_alg_arg;
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_key_derivation_operation_t server_derive =
-        PSA_KEY_DERIVATION_OPERATION_INIT;
+        psa_key_derivation_operation_init_short();
     psa_key_derivation_operation_t client_derive =
-        PSA_KEY_DERIVATION_OPERATION_INIT;
+        psa_key_derivation_operation_init_short();
     ecjpake_injected_failure_t inj_err_type = inj_err_type_arg;
 
     PSA_INIT();
diff --git a/tests/suites/test_suite_psa_crypto.persistent.data b/tests/suites/test_suite_psa_crypto.persistent.data
new file mode 100644
index 0000000..378e147
--- /dev/null
+++ b/tests/suites/test_suite_psa_crypto.persistent.data
@@ -0,0 +1,39 @@
+PSA import persistent key: raw data, 8 bits
+depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
+persistent_key_load_key_from_storage:"2a":PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0:IMPORT_KEY
+
+PSA import persistent key: AES, 128 bits, exportable
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PSA_CRYPTO_STORAGE_C
+persistent_key_load_key_from_storage:"2b7e151628aed2a6abf7158809cf4f3c":PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:IMPORT_KEY
+
+PSA import persistent key: AES, 128 bits, non-exportable
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PSA_CRYPTO_STORAGE_C
+persistent_key_load_key_from_storage:"2b7e151628aed2a6abf7158809cf4f3c":PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR:IMPORT_KEY
+
+PSA generate persistent key: raw data, 8 bits, exportable
+depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
+persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0:GENERATE_KEY
+
+PSA generate persistent key: AES, 128 bits, exportable
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PSA_CRYPTO_STORAGE_C
+persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:GENERATE_KEY
+
+PSA generate persistent key: AES, 128 bits, non-exportable
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PSA_CRYPTO_STORAGE_C
+persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:GENERATE_KEY
+
+PSA generate persistent key: DES, 64 bits, exportable
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES:MBEDTLS_PSA_CRYPTO_STORAGE_C
+persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_DES:64:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_NO_PADDING:GENERATE_KEY
+
+PSA generate persistent key: RSA, minimum size key, exportable
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_CRYPTO_STORAGE_C:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS >= 512
+persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):GENERATE_KEY
+
+PSA generate persistent key: ECC, SECP256R1, exportable
+depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:MBEDTLS_PSA_CRYPTO_STORAGE_C
+persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_ECDSA_ANY:GENERATE_KEY
+
+PSA derive persistent key: HKDF SHA-256, exportable
+persistent_key_load_key_from_storage:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_TYPE_RAW_DATA:1024:PSA_KEY_USAGE_EXPORT:0:DERIVE_KEY
+
diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function
index 49b1c15..f5bed37 100644
--- a/tests/suites/test_suite_psa_crypto_driver_wrappers.function
+++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.function
@@ -1063,7 +1063,7 @@
     size_t output2_buffer_size = 0;
     size_t output2_length = 0;
     size_t function_output_length = 0;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
+    psa_cipher_operation_t operation = psa_cipher_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     mbedtls_test_driver_cipher_hooks = mbedtls_test_driver_cipher_hooks_init();
 
@@ -1158,7 +1158,7 @@
     size_t output_buffer_size = 0;
     size_t function_output_length = 0;
     size_t total_output_length = 0;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
+    psa_cipher_operation_t operation = psa_cipher_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     mbedtls_test_driver_cipher_hooks = mbedtls_test_driver_cipher_hooks_init();
     mbedtls_test_driver_cipher_hooks.forced_status = force_status;
@@ -1287,7 +1287,7 @@
     size_t output_buffer_size = 0;
     size_t function_output_length = 0;
     size_t total_output_length = 0;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
+    psa_cipher_operation_t operation = psa_cipher_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     mbedtls_test_driver_cipher_hooks = mbedtls_test_driver_cipher_hooks_init();
     mbedtls_test_driver_cipher_hooks.forced_status = force_status;
@@ -1475,7 +1475,7 @@
     unsigned char *output = NULL;
     size_t output_buffer_size = 0;
     size_t function_output_length = 0;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
+    psa_cipher_operation_t operation = psa_cipher_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     mbedtls_test_driver_cipher_hooks = mbedtls_test_driver_cipher_hooks_init();
 
@@ -1810,7 +1810,7 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
-    psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
+    psa_mac_operation_t operation = psa_mac_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     uint8_t *actual_mac = NULL;
     size_t mac_buffer_size =
@@ -1884,7 +1884,7 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
-    psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
+    psa_mac_operation_t operation = psa_mac_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     uint8_t *actual_mac = NULL;
     size_t mac_buffer_size =
@@ -2001,7 +2001,7 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
-    psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
+    psa_mac_operation_t operation = psa_mac_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_status_t status = PSA_ERROR_GENERIC_ERROR;
     psa_status_t forced_status = forced_status_arg;
@@ -2056,7 +2056,7 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
-    psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
+    psa_mac_operation_t operation = psa_mac_operation_init_short();
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_status_t status = PSA_ERROR_GENERIC_ERROR;
     psa_status_t forced_status = forced_status_arg;
@@ -2294,7 +2294,7 @@
     psa_status_t forced_status = forced_status_arg;
     psa_status_t expected_status = expected_status_arg;
     unsigned char *output = NULL;
-    psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
+    psa_hash_operation_t operation = psa_hash_operation_init_short();
     size_t output_length;
 
 
@@ -2341,7 +2341,7 @@
     psa_algorithm_t alg = alg_arg;
     psa_status_t forced_status = forced_status_arg;
     unsigned char *output = NULL;
-    psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
+    psa_hash_operation_t operation = psa_hash_operation_init_short();
     size_t output_length;
 
 
@@ -2398,7 +2398,7 @@
     psa_algorithm_t alg = alg_arg;
     psa_status_t forced_status = forced_status_arg;
     unsigned char *output = NULL;
-    psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
+    psa_hash_operation_t operation = psa_hash_operation_init_short();
     size_t output_length;
 
     PSA_ASSERT(psa_crypto_init());
@@ -2452,8 +2452,8 @@
     psa_algorithm_t alg = alg_arg;
     psa_status_t forced_status = forced_status_arg;
     unsigned char *output = NULL;
-    psa_hash_operation_t source_operation = PSA_HASH_OPERATION_INIT;
-    psa_hash_operation_t target_operation = PSA_HASH_OPERATION_INIT;
+    psa_hash_operation_t source_operation = psa_hash_operation_init_short();
+    psa_hash_operation_t target_operation = psa_hash_operation_init_short();
     size_t output_length;
 
     PSA_ASSERT(psa_crypto_init());
@@ -3019,7 +3019,7 @@
     psa_pake_operation_t operation = psa_pake_operation_init();
     psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
     psa_key_derivation_operation_t implicit_key =
-        PSA_KEY_DERIVATION_OPERATION_INIT;
+        psa_key_derivation_operation_init_short();
     psa_pake_primitive_t primitive = PSA_PAKE_PRIMITIVE(
         PSA_PAKE_PRIMITIVE_TYPE_ECC,
         PSA_ECC_FAMILY_SECP_R1, 256);
@@ -3214,9 +3214,9 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_key_derivation_operation_t server_derive =
-        PSA_KEY_DERIVATION_OPERATION_INIT;
+        psa_key_derivation_operation_init_short();
     psa_key_derivation_operation_t client_derive =
-        PSA_KEY_DERIVATION_OPERATION_INIT;
+        psa_key_derivation_operation_init_short();
     pake_in_driver = in_driver;
     /* driver setup is called indirectly through pake_output/pake_input */
     if (pake_in_driver) {
diff --git a/tests/suites/test_suite_psa_crypto_slot_management.function b/tests/suites/test_suite_psa_crypto_slot_management.function
index 604c4bd..aa375a2 100644
--- a/tests/suites/test_suite_psa_crypto_slot_management.function
+++ b/tests/suites/test_suite_psa_crypto_slot_management.function
@@ -377,8 +377,9 @@
     mbedtls_svc_key_id_t returned_id = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_key_type_t type1 = PSA_KEY_TYPE_RAW_DATA;
-    const uint8_t material1[5] = "a key";
-    const uint8_t material2[5] = "b key";
+    /* We need to tell the compiler that we meant to leave out the null character. */
+    const uint8_t material1[5] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING = "a key";
+    const uint8_t material2[5] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING = "b key";
     size_t bits1 = PSA_BYTES_TO_BITS(sizeof(material1));
     uint8_t reexported[sizeof(material1)];
     size_t reexported_length;
@@ -747,7 +748,7 @@
     psa_key_id_t key_id;
     psa_status_t close_status = close_status_arg;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    uint8_t material[1] = "a";
+    uint8_t material[1] = { 'a' };
 
     PSA_ASSERT(psa_crypto_init());
 
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index 8fa5120..6797a4d 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -2840,6 +2840,7 @@
 {
     enum { BUFFSIZE = 1024 };
     mbedtls_test_ssl_endpoint ep;
+    memset(&ep, 0, sizeof(ep));
     int ret = -1;
     mbedtls_test_handshake_test_options options;
     mbedtls_test_init_handshake_options(&options);
@@ -2871,6 +2872,8 @@
 {
     enum { BUFFSIZE = 1024 };
     mbedtls_test_ssl_endpoint base_ep, second_ep;
+    memset(&base_ep, 0, sizeof(base_ep));
+    memset(&second_ep, 0, sizeof(second_ep));
     int ret = -1;
     (void) tls_version;
 
@@ -2896,8 +2899,6 @@
 #endif
 
     MD_OR_USE_PSA_INIT();
-    mbedtls_platform_zeroize(&base_ep, sizeof(base_ep));
-    mbedtls_platform_zeroize(&second_ep, sizeof(second_ep));
 
     ret = mbedtls_test_ssl_endpoint_init(&base_ep, endpoint_type, &options,
                                          NULL, NULL, NULL);
@@ -3606,6 +3607,8 @@
     enum { BUFFSIZE = 1024 };
     mbedtls_test_handshake_test_options options;
     mbedtls_test_ssl_endpoint client, server;
+    memset(&client, 0, sizeof(client));
+    memset(&server, 0, sizeof(server));
     mbedtls_test_ssl_log_pattern srv_pattern, cli_pattern;
     mbedtls_test_message_socket_context server_context, client_context;
 
@@ -3616,9 +3619,6 @@
     options.srv_log_obj = &srv_pattern;
     options.srv_log_fun = mbedtls_test_ssl_log_analyzer;
 
-    mbedtls_platform_zeroize(&client, sizeof(client));
-    mbedtls_platform_zeroize(&server, sizeof(server));
-
     mbedtls_test_message_socket_init(&server_context);
     mbedtls_test_message_socket_init(&client_context);
     MD_OR_USE_PSA_INIT();
@@ -3803,6 +3803,8 @@
 {
     enum { BUFFSIZE = 17000 };
     mbedtls_test_ssl_endpoint client, server;
+    memset(&client, 0, sizeof(client));
+    memset(&server, 0, sizeof(server));
     mbedtls_psa_stats_t stats;
     size_t free_slots_before = -1;
     mbedtls_test_handshake_test_options client_options, server_options;
@@ -3812,8 +3814,6 @@
     uint16_t iana_tls_group_list[] = { MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1,
                                        MBEDTLS_SSL_IANA_TLS_GROUP_NONE };
     MD_OR_USE_PSA_INIT();
-    mbedtls_platform_zeroize(&client, sizeof(client));
-    mbedtls_platform_zeroize(&server, sizeof(server));
 
     /* Client side, force SECP256R1 to make one key bitflip fail
      * the raw key agreement. Flipping the first byte makes the
@@ -3877,6 +3877,8 @@
 {
     int ret = -1;
     mbedtls_test_ssl_endpoint client_ep, server_ep;
+    memset(&client_ep, 0, sizeof(client_ep));
+    memset(&server_ep, 0, sizeof(server_ep));
     unsigned char *buf, *end;
     size_t buf_len;
     int step = 0;
@@ -3888,8 +3890,6 @@
     /*
      * Test set-up
      */
-    mbedtls_platform_zeroize(&client_ep, sizeof(client_ep));
-    mbedtls_platform_zeroize(&server_ep, sizeof(server_ep));
 
     mbedtls_test_init_handshake_options(&client_options);
     MD_OR_USE_PSA_INIT();
@@ -4132,12 +4132,12 @@
 {
     int ret = -1;
     mbedtls_test_ssl_endpoint client_ep, server_ep;
+    memset(&client_ep, 0, sizeof(client_ep));
+    memset(&server_ep, 0, sizeof(server_ep));
     mbedtls_test_handshake_test_options client_options;
     mbedtls_test_handshake_test_options server_options;
     mbedtls_ssl_session saved_session;
 
-    mbedtls_platform_zeroize(&client_ep, sizeof(client_ep));
-    mbedtls_platform_zeroize(&server_ep, sizeof(server_ep));
     mbedtls_test_init_handshake_options(&client_options);
     mbedtls_test_init_handshake_options(&server_options);
     mbedtls_ssl_session_init(&saved_session);
@@ -4217,6 +4217,8 @@
     const char *early_data = "This is early data.";
     size_t early_data_len = strlen(early_data);
     mbedtls_test_ssl_endpoint client_ep, server_ep;
+    memset(&client_ep, 0, sizeof(client_ep));
+    memset(&server_ep, 0, sizeof(server_ep));
     mbedtls_test_handshake_test_options client_options;
     mbedtls_test_handshake_test_options server_options;
     mbedtls_ssl_session saved_session;
@@ -4227,8 +4229,6 @@
         MBEDTLS_SSL_IANA_TLS_GROUP_NONE
     };
 
-    mbedtls_platform_zeroize(&client_ep, sizeof(client_ep));
-    mbedtls_platform_zeroize(&server_ep, sizeof(server_ep));
     mbedtls_test_init_handshake_options(&client_options);
     mbedtls_test_init_handshake_options(&server_options);
     mbedtls_ssl_session_init(&saved_session);
@@ -4416,6 +4416,8 @@
 {
     int ret = -1;
     mbedtls_test_ssl_endpoint client_ep, server_ep;
+    memset(&client_ep, 0, sizeof(client_ep));
+    memset(&server_ep, 0, sizeof(server_ep));
     mbedtls_test_handshake_test_options client_options;
     mbedtls_test_handshake_test_options server_options;
     mbedtls_ssl_session saved_session;
@@ -4426,8 +4428,6 @@
     };
     uint8_t client_random[MBEDTLS_CLIENT_HELLO_RANDOM_LEN];
 
-    mbedtls_platform_zeroize(&client_ep, sizeof(client_ep));
-    mbedtls_platform_zeroize(&server_ep, sizeof(server_ep));
     mbedtls_test_init_handshake_options(&client_options);
     mbedtls_test_init_handshake_options(&server_options);
     mbedtls_ssl_session_init(&saved_session);
@@ -4789,6 +4789,8 @@
 {
     int ret = -1;
     mbedtls_test_ssl_endpoint client_ep, server_ep;
+    memset(&client_ep, 0, sizeof(client_ep));
+    memset(&server_ep, 0, sizeof(server_ep));
     mbedtls_test_handshake_test_options client_options;
     mbedtls_test_handshake_test_options server_options;
     mbedtls_ssl_session saved_session;
@@ -4799,8 +4801,6 @@
     };
     int beyond_first_hello = 0;
 
-    mbedtls_platform_zeroize(&client_ep, sizeof(client_ep));
-    mbedtls_platform_zeroize(&server_ep, sizeof(server_ep));
     mbedtls_test_init_handshake_options(&client_options);
     mbedtls_test_init_handshake_options(&server_options);
     mbedtls_ssl_session_init(&saved_session);
@@ -5138,6 +5138,8 @@
 {
     int ret = -1;
     mbedtls_test_ssl_endpoint client_ep, server_ep;
+    memset(&client_ep, 0, sizeof(client_ep));
+    memset(&server_ep, 0, sizeof(server_ep));
     mbedtls_test_handshake_test_options client_options;
     mbedtls_test_handshake_test_options server_options;
     mbedtls_ssl_session saved_session;
@@ -5147,8 +5149,6 @@
     uint32_t written_early_data_size = 0;
     uint32_t read_early_data_size = 0;
 
-    mbedtls_platform_zeroize(&client_ep, sizeof(client_ep));
-    mbedtls_platform_zeroize(&server_ep, sizeof(server_ep));
     mbedtls_test_init_handshake_options(&client_options);
     mbedtls_test_init_handshake_options(&server_options);
     mbedtls_ssl_session_init(&saved_session);
@@ -5291,6 +5291,8 @@
 {
     int ret = -1;
     mbedtls_test_ssl_endpoint client_ep, server_ep;
+    memset(&client_ep, 0, sizeof(client_ep));
+    memset(&server_ep, 0, sizeof(server_ep));
     mbedtls_test_handshake_test_options client_options;
     mbedtls_test_handshake_test_options server_options;
     mbedtls_ssl_session saved_session;
@@ -5309,8 +5311,6 @@
     uint32_t written_early_data_size = 0;
     uint32_t max_early_data_size;
 
-    mbedtls_platform_zeroize(&client_ep, sizeof(client_ep));
-    mbedtls_platform_zeroize(&server_ep, sizeof(server_ep));
     mbedtls_test_init_handshake_options(&client_options);
     mbedtls_test_init_handshake_options(&server_options);
     mbedtls_ssl_session_init(&saved_session);
@@ -5736,6 +5736,8 @@
     uint8_t *key_buffer_server = NULL;
     uint8_t *key_buffer_client = NULL;
     mbedtls_test_ssl_endpoint client_ep, server_ep;
+    memset(&client_ep, 0, sizeof(client_ep));
+    memset(&server_ep, 0, sizeof(server_ep));
     mbedtls_test_handshake_test_options options;
 
     MD_OR_USE_PSA_INIT();
@@ -5781,6 +5783,8 @@
 
     int ret = -1;
     mbedtls_test_ssl_endpoint client_ep, server_ep;
+    memset(&client_ep, 0, sizeof(client_ep));
+    memset(&server_ep, 0, sizeof(server_ep));
     mbedtls_test_handshake_test_options options;
 
     MD_OR_USE_PSA_INIT();
@@ -5820,6 +5824,8 @@
 
     int ret = -1;
     mbedtls_test_ssl_endpoint client_ep, server_ep;
+    memset(&client_ep, 0, sizeof(client_ep));
+    memset(&server_ep, 0, sizeof(server_ep));
     mbedtls_test_handshake_test_options options;
 
     MD_OR_USE_PSA_INIT();
@@ -5860,6 +5866,8 @@
 
     int ret = -1;
     mbedtls_test_ssl_endpoint client_ep, server_ep;
+    memset(&client_ep, 0, sizeof(client_ep));
+    memset(&server_ep, 0, sizeof(server_ep));
     mbedtls_test_handshake_test_options options;
 
     MD_OR_USE_PSA_INIT();
@@ -5903,6 +5911,8 @@
     char *label = NULL;
     uint8_t *context = NULL;
     mbedtls_test_ssl_endpoint client_ep, server_ep;
+    memset(&client_ep, 0, sizeof(client_ep));
+    memset(&server_ep, 0, sizeof(server_ep));
     mbedtls_test_handshake_test_options options;
 
     TEST_ASSERT(exported_key_length > 0);
@@ -5941,6 +5951,8 @@
 
     int ret = -1;
     mbedtls_test_ssl_endpoint server_ep, client_ep;
+    memset(&client_ep, 0, sizeof(client_ep));
+    memset(&server_ep, 0, sizeof(server_ep));
 
     mbedtls_test_handshake_test_options options;
     mbedtls_test_init_handshake_options(&options);
@@ -5966,7 +5978,9 @@
     } else {
         ret = mbedtls_test_move_handshake_to_state(&client_ep.ssl, &server_ep.ssl, state);
     }
-    TEST_ASSERT(ret == 0 || ret == MBEDTLS_ERR_SSL_WANT_READ || MBEDTLS_ERR_SSL_WANT_WRITE);
+    if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
+        TEST_EQUAL(ret, 0);
+    }
 
     char label[] = "test-label";
     uint8_t key_buffer[24] = { 0 };
diff --git a/tests/suites/test_suite_ssl_decrypt.function b/tests/suites/test_suite_ssl_decrypt.function
index 35f0adb..2d75a29 100644
--- a/tests/suites/test_suite_ssl_decrypt.function
+++ b/tests/suites/test_suite_ssl_decrypt.function
@@ -37,7 +37,8 @@
     mbedtls_ssl_write_version(rec_good.ver,
                               MBEDTLS_SSL_TRANSPORT_STREAM,
                               version);
-    const char sample_plaintext[3] = "ABC";
+    /* We need to tell the compiler that we meant to leave out the null character. */
+    const char sample_plaintext[3] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING = "ABC";
     mbedtls_ssl_context ssl;
     mbedtls_ssl_init(&ssl);
     uint8_t *buf = NULL;
diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data
index bdf6fa0..a45f353 100644
--- a/tests/suites/test_suite_version.data
+++ b/tests/suites/test_suite_version.data
@@ -1,8 +1,8 @@
 Check compile time library version
-check_compiletime_version:"3.6.3"
+check_compiletime_version:"3.6.4"
 
 Check runtime library version
-check_runtime_version:"3.6.3"
+check_runtime_version:"3.6.4"
 
 Check for MBEDTLS_VERSION_C
 check_feature:"MBEDTLS_VERSION_C":0
diff --git a/tests/suites/test_suite_x509write.data b/tests/suites/test_suite_x509write.data
index 0cbad4b..56af0ce 100644
--- a/tests/suites/test_suite_x509write.data
+++ b/tests/suites/test_suite_x509write.data
@@ -254,6 +254,27 @@
 X509 String to Names #20 (Reject empty AttributeValue)
 mbedtls_x509_string_to_names:"C=NL, O=, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME:0
 
+# Note: the behaviour is incorrect, output from string->names->string should be
+# the same as the input, rather than just the last component, see
+# https://github.com/Mbed-TLS/mbedtls/issues/10189
+# Still including tests for the current incorrect behaviour because of the
+# variants below where we want to ensure at least that no memory corruption
+# happens (which would be a lot worse than just a functional bug).
+X509 String to Names (repeated OID)
+mbedtls_x509_string_to_names:"CN=ab,CN=cd,CN=ef":"CN=ef":0:0
+
+# Note: when a value starts with a # sign, it's treated as the hex encoding of
+# the DER encoding of the value. Here, 0400 is a zero-length OCTET STRING.
+# The tag actually doesn't matter for our purposes, only the length.
+X509 String to Names (repeated OID, 1st is zero-length)
+mbedtls_x509_string_to_names:"CN=#0400,CN=cd,CN=ef":"CN=ef":0:0
+
+X509 String to Names (repeated OID, middle is zero-length)
+mbedtls_x509_string_to_names:"CN=ab,CN=#0400,CN=ef":"CN=ef":0:0
+
+X509 String to Names (repeated OID, last is zero-length)
+mbedtls_x509_string_to_names:"CN=ab,CN=cd,CN=#0400":"CN=#0000":0:MAY_FAIL_GET_NAME
+
 X509 Round trip test (Escaped characters)
 mbedtls_x509_string_to_names:"CN=Lu\\C4\\8Di\\C4\\87, O=Offspark, OU=PolarSSL":"CN=Lu\\C4\\8Di\\C4\\87, O=Offspark, OU=PolarSSL":0:0
 
diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function
index 81816fe..a22c486 100644
--- a/tests/suites/test_suite_x509write.function
+++ b/tests/suites/test_suite_x509write.function
@@ -731,6 +731,11 @@
     TEST_LE_S(1, ret);
     TEST_ASSERT(strcmp((char *) out, parsed_name) == 0);
 
+    /* Check that calling a 2nd time with the same param (now non-NULL)
+     * returns an error as expected. */
+    ret = mbedtls_x509_string_to_names(&names, name);
+    TEST_EQUAL(ret, MBEDTLS_ERR_X509_BAD_INPUT_DATA);
+
 exit:
     mbedtls_asn1_free_named_data_list(&names);