Merge pull request #5007 from mprse/pk_opaque

Add key_opaque option to ssl_server2.c + test
diff --git a/ChangeLog.d/check-return.txt b/ChangeLog.d/check-return.txt
new file mode 100644
index 0000000..045b180
--- /dev/null
+++ b/ChangeLog.d/check-return.txt
@@ -0,0 +1,17 @@
+Bugfix
+   * Failures of alternative implementations of AES or DES single-block
+     functions enabled with MBEDTLS_AES_ENCRYPT_ALT, MBEDTLS_AES_DECRYPT_ALT,
+     MBEDTLS_DES_CRYPT_ECB_ALT or MBEDTLS_DES3_CRYPT_ECB_ALT were ignored.
+     This does not concern the implementation provided with Mbed TLS,
+     where this function cannot fail, or full-module replacements with
+     MBEDTLS_AES_ALT or MBEDTLS_DES_ALT. Reported by Armelle Duboc in #1092.
+
+Features
+   * Warn if errors from certain functions are ignored. This is currently
+     supported on GCC-like compilers and on MSVC and can be configured through
+     the macro MBEDTLS_CHECK_RETURN. The warnings are always enabled
+     (where supported) for critical functions where ignoring the return
+     value is almost always a bug. Enable the new configuration option
+     MBEDTLS_CHECK_RETURN_WARNING to get warnings for other functions. This
+     is currently implemented in the AES and DES modules, and will be extended
+     to other modules in the future.
diff --git a/ChangeLog.d/fix-mbedtls_cipher_crypt-aes-ecb.txt b/ChangeLog.d/fix-mbedtls_cipher_crypt-aes-ecb.txt
new file mode 100644
index 0000000..6dc4724
--- /dev/null
+++ b/ChangeLog.d/fix-mbedtls_cipher_crypt-aes-ecb.txt
@@ -0,0 +1,2 @@
+Bugfix
+   * Fix mbedtls_cipher_crypt: AES-ECB when MBEDTLS_USE_PSA_CRYPTO is enabled.
diff --git a/ChangeLog.d/fix-psa_gen_key-status.txt b/ChangeLog.d/fix-psa_gen_key-status.txt
new file mode 100644
index 0000000..7860988
--- /dev/null
+++ b/ChangeLog.d/fix-psa_gen_key-status.txt
@@ -0,0 +1,2 @@
+Bugfix
+   * Fix the error returned by psa_generate_key() for a public key. Fixes #4551.
diff --git a/ChangeLog.d/issue5065.txt b/ChangeLog.d/issue5065.txt
new file mode 100644
index 0000000..943ee47
--- /dev/null
+++ b/ChangeLog.d/issue5065.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Fix compile-time or run-time errors in PSA
+     AEAD functions when ChachaPoly is disabled. Fixes #5065.
diff --git a/ChangeLog.d/psa_gcm_buffer_limitation.txt b/ChangeLog.d/psa_gcm_buffer_limitation.txt
new file mode 100644
index 0000000..0c07e24
--- /dev/null
+++ b/ChangeLog.d/psa_gcm_buffer_limitation.txt
@@ -0,0 +1,16 @@
+Bugfix
+   * Remove PSA'a AEAD finish/verify output buffer limitation for GCM.
+     The requirement of minimum 15 bytes for output buffer in
+     psa_aead_finish() and psa_aead_verify() does not apply to the built-in
+     implementation of GCM.
+   * Move GCM's update output buffer length verification from PSA AEAD to
+     the built-in implementation of the GCM.
+     The requirement for output buffer size to be equal or greater then
+     input buffer size is valid only for the built-in implementation of GCM.
+     Alternative GCM implementations can process whole blocks only.
+
+API changes
+   * New error code for GCM: MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL.
+     Alternative GCM implementations are expected to verify
+     the length of the provided output buffers and to return the
+     MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL in case the buffer length is too small.
diff --git a/ChangeLog.d/remove-ssl-export-keys.txt b/ChangeLog.d/remove-ssl-export-keys.txt
new file mode 100644
index 0000000..1a4b31d
--- /dev/null
+++ b/ChangeLog.d/remove-ssl-export-keys.txt
@@ -0,0 +1,5 @@
+Changes
+   * Remove MBEDTLS_SSL_EXPORT_KEYS, making it always on and increasing the
+     code size by about 80B on an M0 build. This option only gated an ability
+     to set a callback, but was deemed unnecessary as it was yet another define
+     to remember when writing tests, or test configurations. Fixes #4653.
diff --git a/README.md b/README.md
index b80ee11..dbe6a23 100644
--- a/README.md
+++ b/README.md
@@ -298,3 +298,10 @@
 ------------
 
 We gratefully accept bug reports and contributions from the community. Please see the [contributing guidelines](CONTRIBUTING.md) for details on how to do this.
+
+Contact
+-------
+
+* To report a security vulnerability in Mbed TLS, please email <mbed-tls-security@lists.trustedfirmware.org>. For more information, see [`SECURITY.md`](SECURITY.md).
+* To report a bug or request a feature in Mbed TLS, please [file an issue on GitHub](https://github.com/ARMmbed/mbedtls/issues/new/choose).
+* Please see [`SUPPORT.md`](SUPPORT.md) for other channels for discussion and support about Mbed TLS.
diff --git a/configs/config-thread.h b/configs/config-thread.h
index be889a1..36d8245 100644
--- a/configs/config-thread.h
+++ b/configs/config-thread.h
@@ -45,7 +45,6 @@
 #define MBEDTLS_SSL_PROTO_DTLS
 #define MBEDTLS_SSL_DTLS_ANTI_REPLAY
 #define MBEDTLS_SSL_DTLS_HELLO_VERIFY
-#define MBEDTLS_SSL_EXPORT_KEYS
 
 /* mbed TLS modules */
 #define MBEDTLS_AES_C
diff --git a/docs/architecture/tls13-experimental.md b/docs/architecture/tls13-experimental.md
index 5d7c14f..88d0b73 100644
--- a/docs/architecture/tls13-experimental.md
+++ b/docs/architecture/tls13-experimental.md
@@ -255,7 +255,7 @@
     Example 1: #define CLIENT_HELLO_RANDOM_LEN 32, macro for the length of the
         `random` field of the ClientHello message.
 
-    Example 2 (consistent abbreviation): `mbedtls_ssl_tls1_3_write_sig_alg_ext()`
+    Example 2 (consistent abbreviation): `mbedtls_ssl_tls13_write_sig_alg_ext()`
         and `MBEDTLS_TLS_EXT_SIG_ALG`, `sig_alg` standing for
         `signature_algorithms`.
 
@@ -279,7 +279,7 @@
     of another one which could potentially lead to some nasty issues.
 
     Example: `cipher_suites` vector of ClientHello in
-             `ssl_tls1_3_write_client_hello_cipher_suites()`
+             `ssl_tls13_write_client_hello_cipher_suites()`
     ```
     size_t cipher_suites_len;
     unsigned char *p_cipher_suites_len;
diff --git a/include/mbedtls/aes.h b/include/mbedtls/aes.h
index 879c3f2..becbfae 100644
--- a/include/mbedtls/aes.h
+++ b/include/mbedtls/aes.h
@@ -42,6 +42,7 @@
 #include "mbedtls/private_access.h"
 
 #include "mbedtls/build_info.h"
+#include "mbedtls/platform_util.h"
 
 #include <stddef.h>
 #include <stdint.h>
@@ -163,6 +164,7 @@
  * \return         \c 0 on success.
  * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
                     unsigned int keybits );
 
@@ -181,6 +183,7 @@
  * \return         \c 0 on success.
  * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
                     unsigned int keybits );
 
@@ -201,6 +204,7 @@
  * \return         \c 0 on success.
  * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
                                 const unsigned char *key,
                                 unsigned int keybits );
@@ -221,6 +225,7 @@
  * \return         \c 0 on success.
  * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
                                 const unsigned char *key,
                                 unsigned int keybits );
@@ -249,6 +254,7 @@
 
  * \return         \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
                     int mode,
                     const unsigned char input[16],
@@ -296,6 +302,7 @@
  * \return         #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
  *                 on failure.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
                     int mode,
                     size_t length,
@@ -340,6 +347,7 @@
  *                     smaller than an AES block in size (16 Bytes) or if \p
  *                     length is larger than 2^20 blocks (16 MiB).
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
                            int mode,
                            size_t length,
@@ -388,6 +396,7 @@
  *
  * \return         \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
                        int mode,
                        size_t length,
@@ -432,6 +441,7 @@
  *
  * \return         \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
                     int mode,
                     size_t length,
@@ -486,6 +496,7 @@
  *
  * \return         \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
                        size_t length,
                        size_t *iv_off,
@@ -572,6 +583,7 @@
  *
  * \return                 \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
                        size_t length,
                        size_t *nc_off,
@@ -592,6 +604,7 @@
  *
  * \return          \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
                                   const unsigned char input[16],
                                   unsigned char output[16] );
@@ -607,6 +620,7 @@
  *
  * \return          \c 0 on success.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
                                   const unsigned char input[16],
                                   unsigned char output[16] );
@@ -618,6 +632,7 @@
  * \return         \c 0 on success.
  * \return         \c 1 on failure.
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 int mbedtls_aes_self_test( int verbose );
 
 #endif /* MBEDTLS_SELF_TEST */
diff --git a/include/mbedtls/des.h b/include/mbedtls/des.h
index 63a8e00..be74cb1 100644
--- a/include/mbedtls/des.h
+++ b/include/mbedtls/des.h
@@ -29,6 +29,7 @@
 #include "mbedtls/private_access.h"
 
 #include "mbedtls/build_info.h"
+#include "mbedtls/platform_util.h"
 
 #include <stddef.h>
 #include <stdint.h>
@@ -139,6 +140,7 @@
  *                 security risk. We recommend considering stronger ciphers
  *                 instead.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
 
 /**
@@ -152,6 +154,7 @@
  *                 security risk. We recommend considering stronger ciphers
  *                 instead.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
 
 /**
@@ -166,6 +169,7 @@
  *                 security risk. We recommend considering stronger ciphers
  *                 instead.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
 
 /**
@@ -180,6 +184,7 @@
  *                 security risk. We recommend considering stronger ciphers
  *                 instead.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
 
 /**
@@ -190,6 +195,7 @@
  *
  * \return         0
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
                       const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
 
@@ -201,6 +207,7 @@
  *
  * \return         0
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
                       const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
 
@@ -212,6 +219,7 @@
  *
  * \return         0
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
                       const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
 
@@ -223,6 +231,7 @@
  *
  * \return         0
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
                       const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
 
@@ -239,6 +248,7 @@
  *                 security risk. We recommend considering stronger ciphers
  *                 instead.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
                     const unsigned char input[8],
                     unsigned char output[8] );
@@ -266,6 +276,7 @@
  *                 security risk. We recommend considering stronger ciphers
  *                 instead.
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
                     int mode,
                     size_t length,
@@ -283,6 +294,7 @@
  *
  * \return         0 if successful
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
                      const unsigned char input[8],
                      unsigned char output[8] );
@@ -308,6 +320,7 @@
  *
  * \return         0 if successful, or MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH
  */
+MBEDTLS_CHECK_RETURN_TYPICAL
 int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
                      int mode,
                      size_t length,
@@ -338,6 +351,7 @@
  *
  * \return         0 if successful, or 1 if the test failed
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 int mbedtls_des_self_test( int verbose );
 
 #endif /* MBEDTLS_SELF_TEST */
diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h
index 27420ce..8b2b9ea 100644
--- a/include/mbedtls/error.h
+++ b/include/mbedtls/error.h
@@ -56,7 +56,7 @@
  * Module   Nr  Codes assigned
  * ERROR     2  0x006E          0x0001
  * MPI       7  0x0002-0x0010
- * GCM       3  0x0012-0x0014   0x0013-0x0013
+ * GCM       3  0x0012-0x0016   0x0013-0x0013
  * THREADING 3  0x001A-0x001E
  * AES       5  0x0020-0x0022   0x0021-0x0025
  * CAMELLIA  3  0x0024-0x0026   0x0027-0x0027
diff --git a/include/mbedtls/gcm.h b/include/mbedtls/gcm.h
index 9d9155f..7dc9dfb 100644
--- a/include/mbedtls/gcm.h
+++ b/include/mbedtls/gcm.h
@@ -45,6 +45,8 @@
 #define MBEDTLS_ERR_GCM_AUTH_FAILED                       -0x0012
 /** Bad input parameters to function. */
 #define MBEDTLS_ERR_GCM_BAD_INPUT                         -0x0014
+/** An output buffer is too small. */
+#define MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL                  -0x0016
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index adc317d..c2f4587 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -521,6 +521,29 @@
 //#define MBEDTLS_CAMELLIA_SMALL_MEMORY
 
 /**
+ * \def MBEDTLS_CHECK_RETURN_WARNING
+ *
+ * If this macro is defined, emit a compile-time warning if application code
+ * calls a function without checking its return value, but the return value
+ * should generally be checked in portable applications.
+ *
+ * This is only supported on platforms where #MBEDTLS_CHECK_RETURN is
+ * implemented. Otherwise this option has no effect.
+ *
+ * Uncomment to get warnings on using fallible functions without checking
+ * their return value.
+ *
+ * \note  This feature is a work in progress.
+ *        Warnings will be added to more functions in the future.
+ *
+ * \note  A few functions are considered critical, and ignoring the return
+ *        value of these functions will trigger a warning even if this
+ *        macro is not defined. To completely disable return value check
+ *        warnings, define #MBEDTLS_CHECK_RETURN with an empty expansion.
+ */
+//#define MBEDTLS_CHECK_RETURN_WARNING
+
+/**
  * \def MBEDTLS_CIPHER_MODE_CBC
  *
  * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers.
@@ -1599,16 +1622,6 @@
 #define MBEDTLS_SSL_SESSION_TICKETS
 
 /**
- * \def MBEDTLS_SSL_EXPORT_KEYS
- *
- * Enable support for exporting key block and master secret.
- * This is required for certain users of TLS, e.g. EAP-TLS.
- *
- * Comment this macro to disable support for key export
- */
-#define MBEDTLS_SSL_EXPORT_KEYS
-
-/**
  * \def MBEDTLS_SSL_SERVER_NAME_INDICATION
  *
  * Enable support for RFC 6066 server name indication (SNI) in SSL.
@@ -3067,6 +3080,29 @@
 //#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO   mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
 //#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO  mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
 
+/** \def MBEDTLS_CHECK_RETURN
+ *
+ * This macro is used at the beginning of the declaration of a function
+ * to indicate that its return value should be checked. It should
+ * instruct the compiler to emit a warning or an error if the function
+ * is called without checking its return value.
+ *
+ * There is a default implementation for popular compilers in platform_util.h.
+ * You can override the default implementation by defining your own here.
+ *
+ * If the implementation here is empty, this will effectively disable the
+ * checking of functions' return values.
+ */
+//#define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__))
+
+/** \def MBEDTLS_IGNORE_RETURN
+ *
+ * This macro requires one argument, which should be a C function call.
+ * If that function call would cause a #MBEDTLS_CHECK_RETURN warning, this
+ * warning is suppressed.
+ */
+//#define MBEDTLS_IGNORE_RETURN( result ) ((void) !(result))
+
 /* PSA options */
 /**
  * Use HMAC_DRBG with the specified hash algorithm for HMAC_DRBG for the
diff --git a/include/mbedtls/platform_util.h b/include/mbedtls/platform_util.h
index 1a0a135..36e3718 100644
--- a/include/mbedtls/platform_util.h
+++ b/include/mbedtls/platform_util.h
@@ -60,6 +60,95 @@
 #endif /* MBEDTLS_DEPRECATED_WARNING */
 #endif /* MBEDTLS_DEPRECATED_REMOVED */
 
+/* Implementation of the check-return facility.
+ * See the user documentation in mbedtls_config.h.
+ *
+ * Do not use this macro directly to annotate function: instead,
+ * use one of MBEDTLS_CHECK_RETURN_CRITICAL or MBEDTLS_CHECK_RETURN_TYPICAL
+ * depending on how important it is to check the return value.
+ */
+#if !defined(MBEDTLS_CHECK_RETURN)
+#if defined(__GNUC__)
+#define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__))
+#elif defined(_MSC_VER) && _MSC_VER >= 1700
+#include <sal.h>
+#define MBEDTLS_CHECK_RETURN _Check_return_
+#else
+#define MBEDTLS_CHECK_RETURN
+#endif
+#endif
+
+/** Critical-failure function
+ *
+ * This macro appearing at the beginning of the declaration of a function
+ * indicates that its return value should be checked in all applications.
+ * Omitting the check is very likely to indicate a bug in the application
+ * and will result in a compile-time warning if #MBEDTLS_CHECK_RETURN
+ * is implemented for the compiler in use.
+ *
+ * \note  The use of this macro is a work in progress.
+ *        This macro may be added to more functions in the future.
+ *        Such an extension is not considered an API break, provided that
+ *        there are near-unavoidable circumstances under which the function
+ *        can fail. For example, signature/MAC/AEAD verification functions,
+ *        and functions that require a random generator, are considered
+ *        return-check-critical.
+ */
+#define MBEDTLS_CHECK_RETURN_CRITICAL MBEDTLS_CHECK_RETURN
+
+/** Ordinary-failure function
+ *
+ * This macro appearing at the beginning of the declaration of a function
+ * indicates that its return value should be generally be checked in portable
+ * applications. Omitting the check will result in a compile-time warning if
+ * #MBEDTLS_CHECK_RETURN is implemented for the compiler in use and
+ * #MBEDTLS_CHECK_RETURN_WARNING is enabled in the compile-time configuration.
+ *
+ * You can use #MBEDTLS_IGNORE_RETURN to explicitly ignore the return value
+ * of a function that is annotated with #MBEDTLS_CHECK_RETURN.
+ *
+ * \note  The use of this macro is a work in progress.
+ *        This macro will be added to more functions in the future.
+ *        Eventually this should appear before most functions returning
+ *        an error code (as \c int in the \c mbedtls_xxx API or
+ *        as ::psa_status_t in the \c psa_xxx API).
+ */
+#if defined(MBEDTLS_CHECK_RETURN_WARNING)
+#define MBEDTLS_CHECK_RETURN_TYPICAL MBEDTLS_CHECK_RETURN
+#else
+#define MBEDTLS_CHECK_RETURN_TYPICAL
+#endif
+
+/** Benign-failure function
+ *
+ * This macro appearing at the beginning of the declaration of a function
+ * indicates that it is rarely useful to check its return value.
+ *
+ * This macro has an empty expansion. It exists for documentation purposes:
+ * a #MBEDTLS_CHECK_RETURN_OPTIONAL annotation indicates that the function
+ * has been analyzed for return-check usefuless, whereas the lack of
+ * an annotation indicates that the function has not been analyzed and its
+ * return-check usefulness is unknown.
+ */
+#define MBEDTLS_CHECK_RETURN_OPTIONAL
+
+/** \def MBEDTLS_IGNORE_RETURN
+ *
+ * Call this macro with one argument, a function call, to suppress a warning
+ * from #MBEDTLS_CHECK_RETURN due to that function call.
+ */
+#if !defined(MBEDTLS_IGNORE_RETURN)
+/* GCC doesn't silence the warning with just (void)(result).
+ * (void)!(result) is known to work up at least up to GCC 10, as well
+ * as with Clang and MSVC.
+ *
+ * https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Non_002dbugs.html
+ * https://stackoverflow.com/questions/40576003/ignoring-warning-wunused-result
+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425#c34
+ */
+#define MBEDTLS_IGNORE_RETURN(result) ( (void) !( result ) )
+#endif
+
 /**
  * \brief       Securely zeroize a buffer
  *
diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h
index 6f63545..80bcd72 100644
--- a/include/mbedtls/psa_util.h
+++ b/include/mbedtls/psa_util.h
@@ -57,6 +57,9 @@
         case MBEDTLS_CIPHER_AES_128_CBC:
         case MBEDTLS_CIPHER_AES_192_CBC:
         case MBEDTLS_CIPHER_AES_256_CBC:
+        case MBEDTLS_CIPHER_AES_128_ECB:
+        case MBEDTLS_CIPHER_AES_192_ECB:
+        case MBEDTLS_CIPHER_AES_256_ECB:
             return( PSA_KEY_TYPE_AES );
 
         /* ARIA not yet supported in PSA. */
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 2349245..fa2429d 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -593,6 +593,9 @@
 
 #define MBEDTLS_PREMASTER_SIZE     sizeof( union mbedtls_ssl_premaster_secret )
 
+/* Length in number of bytes of the TLS sequence number */
+#define MBEDTLS_SSL_SEQUENCE_NUMBER_LEN 8
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -1140,7 +1143,6 @@
 }
 mbedtls_tls_prf_types;
 
-#if defined(MBEDTLS_SSL_EXPORT_KEYS)
 typedef enum
 {
     MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET = 0,
@@ -1176,7 +1178,6 @@
                                         const unsigned char client_random[32],
                                         const unsigned char server_random[32],
                                         mbedtls_tls_prf_types tls_prf_type );
-#endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
 /**
  * SSL/TLS configuration to be shared between mbedtls_ssl_context structures.
@@ -1566,7 +1567,7 @@
     size_t MBEDTLS_PRIVATE(out_buf_len);         /*!< length of output buffer          */
 #endif
 
-    unsigned char MBEDTLS_PRIVATE(cur_out_ctr)[8]; /*!<  Outgoing record sequence  number. */
+    unsigned char MBEDTLS_PRIVATE(cur_out_ctr)[MBEDTLS_SSL_SEQUENCE_NUMBER_LEN]; /*!<  Outgoing record sequence  number. */
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
     uint16_t MBEDTLS_PRIVATE(mtu);               /*!< path mtu, used to fragment outgoing messages */
@@ -1631,11 +1632,9 @@
                             *   and #MBEDTLS_SSL_CID_DISABLED. */
 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
 
-#if defined(MBEDTLS_SSL_EXPORT_KEYS)
     /** Callback to export key block and master secret                      */
     mbedtls_ssl_export_keys_t *MBEDTLS_PRIVATE(f_export_keys);
     void *MBEDTLS_PRIVATE(p_export_keys);            /*!< context for key export callback    */
-#endif
 };
 
 /**
@@ -2208,7 +2207,6 @@
         void *p_ticket );
 #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */
 
-#if defined(MBEDTLS_SSL_EXPORT_KEYS)
 /**
  * \brief   Configure a key export callback.
  *          (Default: none.)
@@ -2230,7 +2228,6 @@
 void mbedtls_ssl_set_export_keys_cb( mbedtls_ssl_context *ssl,
                                      mbedtls_ssl_export_keys_t *f_export_keys,
                                      void *p_export_keys );
-#endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
 #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
 /**
diff --git a/library/aes.c b/library/aes.c
index 8e3358c..4afc3c4 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -1011,6 +1011,7 @@
                     unsigned char *output )
 {
     int i;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char temp[16];
 
     AES_VALIDATE_RET( ctx != NULL );
@@ -1040,7 +1041,9 @@
         while( length > 0 )
         {
             memcpy( temp, input, 16 );
-            mbedtls_aes_crypt_ecb( ctx, mode, input, output );
+            ret = mbedtls_aes_crypt_ecb( ctx, mode, input, output );
+            if( ret != 0 )
+                goto exit;
 
             for( i = 0; i < 16; i++ )
                 output[i] = (unsigned char)( output[i] ^ iv[i] );
@@ -1059,7 +1062,9 @@
             for( i = 0; i < 16; i++ )
                 output[i] = (unsigned char)( input[i] ^ iv[i] );
 
-            mbedtls_aes_crypt_ecb( ctx, mode, output, output );
+            ret = mbedtls_aes_crypt_ecb( ctx, mode, output, output );
+            if( ret != 0 )
+                goto exit;
             memcpy( iv, output, 16 );
 
             input  += 16;
@@ -1067,8 +1072,10 @@
             length -= 16;
         }
     }
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
 
@@ -1222,6 +1229,7 @@
                        unsigned char *output )
 {
     int c;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t n;
 
     AES_VALIDATE_RET( ctx != NULL );
@@ -1242,7 +1250,11 @@
         while( length-- )
         {
             if( n == 0 )
-                mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+            {
+                ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+                if( ret != 0 )
+                    goto exit;
+            }
 
             c = *input++;
             *output++ = (unsigned char)( c ^ iv[n] );
@@ -1256,7 +1268,11 @@
         while( length-- )
         {
             if( n == 0 )
-                mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+            {
+                ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+                if( ret != 0 )
+                    goto exit;
+            }
 
             iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
 
@@ -1265,8 +1281,10 @@
     }
 
     *iv_off = n;
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 
 /*
@@ -1279,6 +1297,7 @@
                             const unsigned char *input,
                             unsigned char *output )
 {
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char c;
     unsigned char ov[17];
 
@@ -1291,7 +1310,9 @@
     while( length-- )
     {
         memcpy( ov, iv, 16 );
-        mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+        ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+        if( ret != 0 )
+            goto exit;
 
         if( mode == MBEDTLS_AES_DECRYPT )
             ov[16] = *input;
@@ -1303,8 +1324,10 @@
 
         memcpy( iv, ov + 1, 16 );
     }
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 #endif /* MBEDTLS_CIPHER_MODE_CFB */
 
@@ -1366,6 +1389,7 @@
                        unsigned char *output )
 {
     int c, i;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t n;
 
     AES_VALIDATE_RET( ctx != NULL );
@@ -1383,7 +1407,9 @@
     while( length-- )
     {
         if( n == 0 ) {
-            mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
+            ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
+            if( ret != 0 )
+                goto exit;
 
             for( i = 16; i > 0; i-- )
                 if( ++nonce_counter[i - 1] != 0 )
@@ -1396,8 +1422,10 @@
     }
 
     *nc_off = n;
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 #endif /* MBEDTLS_CIPHER_MODE_CTR */
 
diff --git a/library/cipher.c b/library/cipher.c
index 546cace..dc80189 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -1266,9 +1266,12 @@
         if( status != PSA_SUCCESS )
             return( MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED );
 
-        status = psa_cipher_set_iv( &cipher_op, iv, iv_len );
-        if( status != PSA_SUCCESS )
-            return( MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED );
+        if( ctx->cipher_info->mode != MBEDTLS_MODE_ECB )
+        {
+            status = psa_cipher_set_iv( &cipher_op, iv, iv_len );
+            if( status != PSA_SUCCESS )
+                return( MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED );
+        }
 
         status = psa_cipher_update( &cipher_op,
                                     input, ilen,
diff --git a/library/des.c b/library/des.c
index 7f90faa..91d22b5 100644
--- a/library/des.c
+++ b/library/des.c
@@ -28,6 +28,7 @@
 #if defined(MBEDTLS_DES_C)
 
 #include "mbedtls/des.h"
+#include "mbedtls/error.h"
 #include "mbedtls/platform_util.h"
 
 #include <string.h>
@@ -642,6 +643,7 @@
                     unsigned char *output )
 {
     int i;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char temp[8];
 
     if( length % 8 )
@@ -654,7 +656,9 @@
             for( i = 0; i < 8; i++ )
                 output[i] = (unsigned char)( input[i] ^ iv[i] );
 
-            mbedtls_des_crypt_ecb( ctx, output, output );
+            ret = mbedtls_des_crypt_ecb( ctx, output, output );
+            if( ret != 0 )
+                goto exit;
             memcpy( iv, output, 8 );
 
             input  += 8;
@@ -667,7 +671,9 @@
         while( length > 0 )
         {
             memcpy( temp, input, 8 );
-            mbedtls_des_crypt_ecb( ctx, input, output );
+            ret = mbedtls_des_crypt_ecb( ctx, input, output );
+            if( ret != 0 )
+                goto exit;
 
             for( i = 0; i < 8; i++ )
                 output[i] = (unsigned char)( output[i] ^ iv[i] );
@@ -679,8 +685,10 @@
             length -= 8;
         }
     }
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
 
@@ -741,6 +749,7 @@
                      unsigned char *output )
 {
     int i;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char temp[8];
 
     if( length % 8 )
@@ -753,7 +762,9 @@
             for( i = 0; i < 8; i++ )
                 output[i] = (unsigned char)( input[i] ^ iv[i] );
 
-            mbedtls_des3_crypt_ecb( ctx, output, output );
+            ret = mbedtls_des3_crypt_ecb( ctx, output, output );
+            if( ret != 0 )
+                goto exit;
             memcpy( iv, output, 8 );
 
             input  += 8;
@@ -766,7 +777,9 @@
         while( length > 0 )
         {
             memcpy( temp, input, 8 );
-            mbedtls_des3_crypt_ecb( ctx, input, output );
+            ret = mbedtls_des3_crypt_ecb( ctx, input, output );
+            if( ret != 0 )
+                goto exit;
 
             for( i = 0; i < 8; i++ )
                 output[i] = (unsigned char)( output[i] ^ iv[i] );
@@ -778,8 +791,10 @@
             length -= 8;
         }
     }
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
 
@@ -872,39 +887,43 @@
         switch( i )
         {
         case 0:
-            mbedtls_des_setkey_dec( &ctx, des3_test_keys );
+            ret = mbedtls_des_setkey_dec( &ctx, des3_test_keys );
             break;
 
         case 1:
-            mbedtls_des_setkey_enc( &ctx, des3_test_keys );
+            ret = mbedtls_des_setkey_enc( &ctx, des3_test_keys );
             break;
 
         case 2:
-            mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
             break;
 
         case 3:
-            mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
             break;
 
         case 4:
-            mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
             break;
 
         case 5:
-            mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
             break;
 
         default:
             return( 1 );
         }
+        if( ret != 0 )
+            goto exit;
 
         for( j = 0; j < 100; j++ )
         {
             if( u == 0 )
-                mbedtls_des_crypt_ecb( &ctx, buf, buf );
+                ret = mbedtls_des_crypt_ecb( &ctx, buf, buf );
             else
-                mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
+                ret = mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
+            if( ret != 0 )
+                goto exit;
         }
 
         if( ( v == MBEDTLS_DES_DECRYPT &&
@@ -947,41 +966,45 @@
         switch( i )
         {
         case 0:
-            mbedtls_des_setkey_dec( &ctx, des3_test_keys );
+            ret = mbedtls_des_setkey_dec( &ctx, des3_test_keys );
             break;
 
         case 1:
-            mbedtls_des_setkey_enc( &ctx, des3_test_keys );
+            ret = mbedtls_des_setkey_enc( &ctx, des3_test_keys );
             break;
 
         case 2:
-            mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
             break;
 
         case 3:
-            mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
             break;
 
         case 4:
-            mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
             break;
 
         case 5:
-            mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
             break;
 
         default:
             return( 1 );
         }
+        if( ret != 0 )
+            goto exit;
 
         if( v == MBEDTLS_DES_DECRYPT )
         {
             for( j = 0; j < 100; j++ )
             {
                 if( u == 0 )
-                    mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
+                    ret = mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
                 else
-                    mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
+                    ret = mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
+                if( ret != 0 )
+                    goto exit;
             }
         }
         else
@@ -991,9 +1014,11 @@
                 unsigned char tmp[8];
 
                 if( u == 0 )
-                    mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
+                    ret = mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
                 else
-                    mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
+                    ret = mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
+                if( ret != 0 )
+                    goto exit;
 
                 memcpy( tmp, prv, 8 );
                 memcpy( prv, buf, 8 );
@@ -1027,6 +1052,8 @@
     mbedtls_des_free( &ctx );
     mbedtls_des3_free( &ctx3 );
 
+    if( ret != 0 )
+        ret = 1;
     return( ret );
 }
 
diff --git a/library/gcm.c b/library/gcm.c
index 910646b..6d62564 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -431,7 +431,7 @@
     unsigned char ectr[16];
 
     if( output_size < input_length )
-        return( MBEDTLS_ERR_GCM_BAD_INPUT );
+        return( MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL );
     GCM_VALIDATE_RET( output_length != NULL );
     *output_length = input_length;
 
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index ece64b1..2556085 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -201,6 +201,8 @@
 
         case MBEDTLS_ERR_GCM_AUTH_FAILED:
             return( PSA_ERROR_INVALID_SIGNATURE );
+        case MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL:
+            return( PSA_ERROR_BUFFER_TOO_SMALL );
         case MBEDTLS_ERR_GCM_BAD_INPUT:
             return( PSA_ERROR_INVALID_ARGUMENT );
 
@@ -3621,34 +3623,35 @@
 {
     psa_algorithm_t base_alg = psa_aead_get_base_algorithm( alg );
 
-#if defined(PSA_WANT_ALG_GCM)
-    if( base_alg == PSA_ALG_GCM )
+    switch(base_alg)
     {
-        /* Not checking max nonce size here as GCM spec allows almost
-         * arbitrarily large nonces. Please note that we do not generally
-         * recommend the usage of nonces of greater length than
-         * PSA_AEAD_NONCE_MAX_SIZE, as large nonces are hashed to a shorter
-         * size, which can then lead to collisions if you encrypt a very
-         * large number of messages.*/
-        if( nonce_length != 0 )
-            return( PSA_SUCCESS );
-    }
+#if defined(PSA_WANT_ALG_GCM)
+        case PSA_ALG_GCM:
+            /* Not checking max nonce size here as GCM spec allows almost
+            * arbitrarily large nonces. Please note that we do not generally
+            * recommend the usage of nonces of greater length than
+            * PSA_AEAD_NONCE_MAX_SIZE, as large nonces are hashed to a shorter
+            * size, which can then lead to collisions if you encrypt a very
+            * large number of messages.*/
+            if( nonce_length != 0 )
+                return( PSA_SUCCESS );
+            break;
 #endif /* PSA_WANT_ALG_GCM */
 #if defined(PSA_WANT_ALG_CCM)
-    if( base_alg == PSA_ALG_CCM )
-    {
-        if( nonce_length >= 7 && nonce_length <= 13 )
-            return( PSA_SUCCESS );
-    }
-    else
+        case PSA_ALG_CCM:
+            if( nonce_length >= 7 && nonce_length <= 13 )
+                return( PSA_SUCCESS );
+            break;
 #endif /* PSA_WANT_ALG_CCM */
 #if defined(PSA_WANT_ALG_CHACHA20_POLY1305)
-    if( base_alg == PSA_ALG_CHACHA20_POLY1305 )
-    {
-        if( nonce_length == 12 )
-            return( PSA_SUCCESS );
-    }
+        case PSA_ALG_CHACHA20_POLY1305:
+            if( nonce_length == 12 )
+                return( PSA_SUCCESS );
+            break;
 #endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */
+        default:
+            break;
+    }
 
     return( PSA_ERROR_NOT_SUPPORTED );
 }
@@ -3950,40 +3953,40 @@
         goto exit;
     }
 
-#if defined(PSA_WANT_ALG_GCM)
-    if( operation->alg == PSA_ALG_GCM )
+    switch(operation->alg)
     {
-        /* Lengths can only be too large for GCM if size_t is bigger than 32
-         * bits. Without the guard this code will generate warnings on 32bit
-         * builds. */
+#if defined(PSA_WANT_ALG_GCM)
+        case PSA_ALG_GCM:
+            /* Lengths can only be too large for GCM if size_t is bigger than 32
+            * bits. Without the guard this code will generate warnings on 32bit
+            * builds. */
 #if SIZE_MAX > UINT32_MAX
-        if( (( uint64_t ) ad_length ) >> 61 != 0 ||
-            (( uint64_t ) plaintext_length ) > 0xFFFFFFFE0ull )
-        {
-            status = PSA_ERROR_INVALID_ARGUMENT;
-            goto exit;
-        }
+            if( (( uint64_t ) ad_length ) >> 61 != 0 ||
+                (( uint64_t ) plaintext_length ) > 0xFFFFFFFE0ull )
+            {
+                status = PSA_ERROR_INVALID_ARGUMENT;
+                goto exit;
+            }
 #endif
-    }
-    else
+            break;
 #endif /* PSA_WANT_ALG_GCM */
 #if defined(PSA_WANT_ALG_CCM)
-    if( operation->alg == PSA_ALG_CCM )
-    {
-        if( ad_length > 0xFF00 )
-        {
-            status = PSA_ERROR_INVALID_ARGUMENT;
-            goto exit;
-        }
-    }
-    else
+        case PSA_ALG_CCM:
+            if( ad_length > 0xFF00 )
+            {
+                status = PSA_ERROR_INVALID_ARGUMENT;
+                goto exit;
+            }
+            break;
 #endif /* PSA_WANT_ALG_CCM */
 #if defined(PSA_WANT_ALG_CHACHA20_POLY1305)
-    if( operation->alg == PSA_ALG_CHACHA20_POLY1305 )
-    {
-        /* No length restrictions for ChaChaPoly. */
-    }
+        case PSA_ALG_CHACHA20_POLY1305:
+            /* No length restrictions for ChaChaPoly. */
+            break;
 #endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */
+        default:
+            break;
+    }
 
     status = psa_driver_wrapper_aead_set_lengths( operation, ad_length,
                                                   plaintext_length );
@@ -5703,6 +5706,10 @@
     if( psa_get_key_bits( attributes ) == 0 )
         return( PSA_ERROR_INVALID_ARGUMENT );
 
+    /* Reject any attempt to create a public key. */
+    if( PSA_KEY_TYPE_IS_PUBLIC_KEY(attributes->core.type) )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
     status = psa_start_key_creation( PSA_KEY_CREATION_GENERATE, attributes,
                                      &slot, &driver );
     if( status != PSA_SUCCESS )
diff --git a/library/psa_crypto_aead.c b/library/psa_crypto_aead.c
index a72865c..c7f7352 100644
--- a/library/psa_crypto_aead.c
+++ b/library/psa_crypto_aead.c
@@ -510,9 +510,6 @@
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
     if( operation->alg == PSA_ALG_GCM )
     {
-        if( output_size < input_length )
-            return( PSA_ERROR_BUFFER_TOO_SMALL );
-
         status =  mbedtls_to_psa_error(
             mbedtls_gcm_update( &operation->ctx.gcm,
                                 input, input_length,
@@ -567,9 +564,6 @@
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
     if( operation->alg == PSA_ALG_GCM )
     {
-        if( ciphertext_size < 15 )
-            return( PSA_ERROR_BUFFER_TOO_SMALL );
-
         status =  mbedtls_to_psa_error(
             mbedtls_gcm_finish( &operation->ctx.gcm,
                                 ciphertext, ciphertext_size, ciphertext_length,
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index a1128ed..9041c51 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -307,6 +307,10 @@
       + ( MBEDTLS_SSL_CID_OUT_LEN_MAX ) )
 #endif
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+#define MBEDTLS_TLS1_3_MD_MAX_SIZE         MBEDTLS_MD_MAX_SIZE
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
 /**
  * \brief          Return the maximum fragment length (payload, in bytes) for
@@ -409,6 +413,32 @@
         }                                                                \
     } while( 0 )
 
+/**
+ * \brief        This macro checks if the remaining length in an input buffer is
+ *               greater or equal than a needed length. If it is not the case, it
+ *               returns #MBEDTLS_ERR_SSL_DECODE_ERROR error and pends a
+ *               #MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR alert message.
+ *
+ *               This is a function-like macro. It is guaranteed to evaluate each
+ *               argument exactly once.
+ *
+ * \param cur    Pointer to the current position in the buffer.
+ * \param end    Pointer to one past the end of the buffer.
+ * \param need   Needed length in bytes.
+ *
+ */
+#define MBEDTLS_SSL_CHK_BUF_READ_PTR( cur, end, need )                          \
+    do {                                                                        \
+        if( mbedtls_ssl_chk_buf_ptr( ( cur ), ( end ), ( need ) ) != 0 )        \
+        {                                                                       \
+            MBEDTLS_SSL_DEBUG_MSG( 1,                                           \
+                                   ( "missing input data in %s", __func__ ) );  \
+            MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,   \
+                                          MBEDTLS_ERR_SSL_DECODE_ERROR );       \
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );                             \
+        }                                                                       \
+    } while( 0 )
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -486,6 +516,9 @@
     /*
      * Handshake specific crypto variables
      */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+    int tls1_3_kex_modes; /*!< key exchange modes for TLS 1.3 */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
     defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
@@ -573,8 +606,8 @@
                                               flight being received          */
     mbedtls_ssl_transform *alt_transform_out;   /*!<  Alternative transform for
                                               resending messages             */
-    unsigned char alt_out_ctr[8];       /*!<  Alternative record epoch/counter
-                                              for resending messages         */
+    unsigned char alt_out_ctr[MBEDTLS_SSL_SEQUENCE_NUMBER_LEN]; /*!<  Alternative record epoch/counter
+                                                                      for resending messages         */
 
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
     /* The state of CID configuration in this handshake. */
@@ -675,6 +708,13 @@
     int extensions_present;             /*!< extension presence; Each bitfield
                                              represents an extension and defined
                                              as \c MBEDTLS_SSL_EXT_XXX */
+
+    union
+    {
+        unsigned char early    [MBEDTLS_TLS1_3_MD_MAX_SIZE];
+        unsigned char handshake[MBEDTLS_TLS1_3_MD_MAX_SIZE];
+        unsigned char app      [MBEDTLS_TLS1_3_MD_MAX_SIZE];
+    } tls1_3_master_secrets;
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
@@ -866,14 +906,14 @@
 
 typedef struct
 {
-    uint8_t ctr[8];         /* In TLS:  The implicit record sequence number.
-                             * In DTLS: The 2-byte epoch followed by
-                             *          the 6-byte sequence number.
-                             * This is stored as a raw big endian byte array
-                             * as opposed to a uint64_t because we rarely
-                             * need to perform arithmetic on this, but do
-                             * need it as a Byte array for the purpose of
-                             * MAC computations.                             */
+    uint8_t ctr[MBEDTLS_SSL_SEQUENCE_NUMBER_LEN];  /* In TLS:  The implicit record sequence number.
+                                                    * In DTLS: The 2-byte epoch followed by
+                                                    *          the 6-byte sequence number.
+                                                    * This is stored as a raw big endian byte array
+                                                    * as opposed to a uint64_t because we rarely
+                                                    * need to perform arithmetic on this, but do
+                                                    * need it as a Byte array for the purpose of
+                                                    * MAC computations.                             */
     uint8_t type;           /* The record content type.                      */
     uint8_t ver[2];         /* SSL/TLS version as present on the wire.
                              * Convert to internal presentation of versions
@@ -956,6 +996,14 @@
  */
 void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl );
 
+/* set inbound transform of ssl context */
+void mbedtls_ssl_set_inbound_transform( mbedtls_ssl_context *ssl,
+                                        mbedtls_ssl_transform *transform );
+
+/* set outbound transform of ssl context */
+void mbedtls_ssl_set_outbound_transform( mbedtls_ssl_context *ssl,
+                                         mbedtls_ssl_transform *transform );
+
 int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl );
 int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl );
 void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl );
@@ -1415,6 +1463,53 @@
                    MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_ALL ) );
 }
 
+/**
+ * Given a list of key exchange modes, check if at least one of them is
+ * supported.
+ *
+ * \param[in] ssl  SSL context
+ * \param kex_modes_mask  Mask of the key exchange modes to check
+ *
+ * \return 0 if at least one of the key exchange modes is supported,
+ *         !=0 otherwise.
+ */
+static inline unsigned mbedtls_ssl_tls1_3_check_kex_modes( mbedtls_ssl_context *ssl,
+                                                           int kex_modes_mask )
+{
+    return( ( ssl->handshake->tls1_3_kex_modes & kex_modes_mask ) == 0 );
+}
+
+static inline int mbedtls_ssl_tls1_3_psk_enabled( mbedtls_ssl_context *ssl )
+{
+    return( ! mbedtls_ssl_tls1_3_check_kex_modes( ssl,
+                   MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK ) );
+}
+
+static inline int mbedtls_ssl_tls1_3_psk_ephemeral_enabled(
+                                                    mbedtls_ssl_context *ssl )
+{
+    return( ! mbedtls_ssl_tls1_3_check_kex_modes( ssl,
+                   MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_EPHEMERAL ) );
+}
+
+static inline int mbedtls_ssl_tls1_3_ephemeral_enabled( mbedtls_ssl_context *ssl )
+{
+    return( ! mbedtls_ssl_tls1_3_check_kex_modes( ssl,
+                   MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL ) );
+}
+
+static inline int mbedtls_ssl_tls1_3_some_ephemeral_enabled( mbedtls_ssl_context *ssl )
+{
+    return( ! mbedtls_ssl_tls1_3_check_kex_modes( ssl,
+                   MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL_ALL ) );
+}
+
+static inline int mbedtls_ssl_tls1_3_some_psk_enabled( mbedtls_ssl_context *ssl )
+{
+    return( ! mbedtls_ssl_tls1_3_check_kex_modes( ssl,
+                   MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_ALL ) );
+}
+
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
 
 /**
@@ -1490,6 +1585,14 @@
 }
 
 /*
+ * Fetch TLS 1.3 handshake message header
+ */
+int mbedtls_ssl_tls1_3_fetch_handshake_msg( mbedtls_ssl_context *ssl,
+                                            unsigned hs_type,
+                                            unsigned char **buf,
+                                            size_t *buf_len );
+
+/*
  * Write TLS 1.3 handshake message header
  */
 int mbedtls_ssl_tls13_start_handshake_msg( mbedtls_ssl_context *ssl,
@@ -1502,13 +1605,19 @@
 int mbedtls_ssl_tls13_finish_handshake_msg( mbedtls_ssl_context *ssl,
                                             size_t buf_len,
                                             size_t msg_len );
-/*
- * Update checksum with handshake header
- */
+
 void mbedtls_ssl_tls13_add_hs_hdr_to_checksum( mbedtls_ssl_context *ssl,
                                                unsigned hs_type,
                                                size_t total_hs_len );
 
+/*
+ * Update checksum of handshake messages.
+ */
+void mbedtls_ssl_tls1_3_add_hs_msg_to_checksum( mbedtls_ssl_context *ssl,
+                                                unsigned hs_type,
+                                                unsigned char const *msg,
+                                                size_t msg_len );
+
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
 /*
  * Write TLS 1.3 Signature Algorithm extension
@@ -1522,4 +1631,11 @@
 
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
 
+/* Get handshake transcript */
+int mbedtls_ssl_get_handshake_transcript( mbedtls_ssl_context *ssl,
+                                          const mbedtls_md_type_t md,
+                                          unsigned char *dst,
+                                          size_t dst_len,
+                                          size_t *olen );
+
 #endif /* ssl_misc.h */
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index 3bf4a60..3795c65 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -2101,7 +2101,7 @@
 static int ssl_swap_epochs( mbedtls_ssl_context *ssl )
 {
     mbedtls_ssl_transform *tmp_transform;
-    unsigned char tmp_out_ctr[8];
+    unsigned char tmp_out_ctr[MBEDTLS_SSL_SEQUENCE_NUMBER_LEN];
 
     if( ssl->transform_out == ssl->handshake->alt_transform_out )
     {
@@ -2117,9 +2117,11 @@
     ssl->handshake->alt_transform_out = tmp_transform;
 
     /* Swap epoch + sequence_number */
-    memcpy( tmp_out_ctr,                 ssl->cur_out_ctr,            8 );
-    memcpy( ssl->cur_out_ctr,            ssl->handshake->alt_out_ctr, 8 );
-    memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr,                 8 );
+    memcpy( tmp_out_ctr, ssl->cur_out_ctr, sizeof( tmp_out_ctr ) );
+    memcpy( ssl->cur_out_ctr, ssl->handshake->alt_out_ctr,
+            sizeof( ssl->cur_out_ctr ) );
+    memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr,
+            sizeof( ssl->handshake->alt_out_ctr ) );
 
     /* Adjust to the newly activated transform */
     mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out );
@@ -2562,7 +2564,7 @@
         mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
                            ssl->conf->transport, ssl->out_hdr + 1 );
 
-        memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 );
+        memcpy( ssl->out_ctr, ssl->cur_out_ctr, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN );
         MBEDTLS_PUT_UINT16_BE( len, ssl->out_len, 0);
 
         if( ssl->transform_out != NULL )
@@ -2574,7 +2576,7 @@
             rec.data_len    = ssl->out_msglen;
             rec.data_offset = ssl->out_msg - rec.buf;
 
-            memcpy( &rec.ctr[0], ssl->out_ctr, 8 );
+            memcpy( &rec.ctr[0], ssl->out_ctr, sizeof( rec.ctr ) );
             mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
                                        ssl->conf->transport, rec.ver );
             rec.type = ssl->out_msgtype;
@@ -3649,9 +3651,12 @@
 #endif
         {
             unsigned i;
-            for( i = 8; i > mbedtls_ssl_ep_len( ssl ); i-- )
+            for( i = MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
+                 i > mbedtls_ssl_ep_len( ssl ); i-- )
+            {
                 if( ++ssl->in_ctr[i - 1] != 0 )
                     break;
+            }
 
             /* The loop goes to its end iff the counter is wrapping */
             if( i == mbedtls_ssl_ep_len( ssl ) )
@@ -4791,7 +4796,7 @@
     }
     else
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
-    memset( ssl->in_ctr, 0, 8 );
+    memset( ssl->in_ctr, 0, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN );
 
     mbedtls_ssl_update_in_pointers( ssl );
 
@@ -4827,12 +4832,12 @@
     {
         ssl->out_ctr = ssl->out_hdr +  3;
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
-        ssl->out_cid = ssl->out_ctr +  8;
+        ssl->out_cid = ssl->out_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
         ssl->out_len = ssl->out_cid;
         if( transform != NULL )
             ssl->out_len += transform->out_cid_len;
 #else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
-        ssl->out_len = ssl->out_ctr + 8;
+        ssl->out_len = ssl->out_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
         ssl->out_iv  = ssl->out_len + 2;
     }
@@ -4881,17 +4886,17 @@
          * ssl_parse_record_header(). */
         ssl->in_ctr = ssl->in_hdr +  3;
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
-        ssl->in_cid = ssl->in_ctr +  8;
+        ssl->in_cid = ssl->in_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
         ssl->in_len = ssl->in_cid; /* Default: no CID */
 #else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
-        ssl->in_len = ssl->in_ctr + 8;
+        ssl->in_len = ssl->in_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
         ssl->in_iv  = ssl->in_len + 2;
     }
     else
 #endif
     {
-        ssl->in_ctr = ssl->in_hdr - 8;
+        ssl->in_ctr = ssl->in_hdr - MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
         ssl->in_len = ssl->in_hdr + 3;
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
         ssl->in_cid = ssl->in_len;
@@ -5065,9 +5070,11 @@
     }
 
     in_ctr_cmp = memcmp( ssl->in_ctr + ep_len,
-                        ssl->conf->renego_period + ep_len, 8 - ep_len );
-    out_ctr_cmp = memcmp( ssl->cur_out_ctr + ep_len,
-                          ssl->conf->renego_period + ep_len, 8 - ep_len );
+                         &ssl->conf->renego_period[ep_len],
+                         MBEDTLS_SSL_SEQUENCE_NUMBER_LEN - ep_len );
+    out_ctr_cmp = memcmp( &ssl->cur_out_ctr[ep_len],
+                          &ssl->conf->renego_period[ep_len],
+                          sizeof( ssl->cur_out_ctr ) - ep_len );
 
     if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 )
     {
@@ -5551,6 +5558,20 @@
     mbedtls_platform_zeroize( transform, sizeof( mbedtls_ssl_transform ) );
 }
 
+void mbedtls_ssl_set_inbound_transform( mbedtls_ssl_context *ssl,
+                                        mbedtls_ssl_transform *transform )
+{
+    ssl->transform_in = transform;
+    memset( ssl->in_ctr, 0, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN );
+}
+
+void mbedtls_ssl_set_outbound_transform( mbedtls_ssl_context *ssl,
+                                         mbedtls_ssl_transform *transform )
+{
+    ssl->transform_out = transform;
+    memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) );
+}
+
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
 
 void mbedtls_ssl_buffering_free( mbedtls_ssl_context *ssl )
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index b8c4314..e27fdff 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -1220,7 +1220,8 @@
             return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
 
-        memcpy( ssl->cur_out_ctr + 2, ssl->in_ctr + 2, 6 );
+        memcpy( &ssl->cur_out_ctr[2], ssl->in_ctr + 2,
+                sizeof( ssl->cur_out_ctr ) - 2 );
 
 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
         if( mbedtls_ssl_dtls_replay_check( ssl ) != 0 )
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index f33f106..c507950 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -587,7 +587,6 @@
 #endif /* MBEDTLS_USE_PSA_CRYPTO &&
           MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
 
-#if defined(MBEDTLS_SSL_EXPORT_KEYS)
 static mbedtls_tls_prf_types tls_prf_get_type( mbedtls_ssl_tls_prf_cb *tls_prf )
 {
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
@@ -608,7 +607,6 @@
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
     return( MBEDTLS_SSL_TLS_PRF_NONE );
 }
-#endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
 int  mbedtls_ssl_tls_prf( const mbedtls_tls_prf_types prf,
                           const unsigned char *secret, size_t slen,
@@ -660,8 +658,9 @@
  * - [in] randbytes: buffer holding ServerHello.random + ClientHello.random
  * - [in] minor_ver: SSL/TLS minor version
  * - [in] endpoint: client or server
- * - [in] ssl: optionally used for:
- *        - MBEDTLS_SSL_EXPORT_KEYS: ssl->conf->{f,p}_export_keys
+ * - [in] ssl: used for:
+ *        - ssl->conf->{f,p}_export_keys
+ *      [in] optionally used for:
  *        - MBEDTLS_DEBUG_C: ssl->conf->{f,p}_dbg
  */
 static int ssl_tls12_populate_transform( mbedtls_ssl_transform *transform,
@@ -694,10 +693,13 @@
     const mbedtls_cipher_info_t *cipher_info;
     const mbedtls_md_info_t *md_info;
 
-#if !defined(MBEDTLS_SSL_EXPORT_KEYS) && \
-    !defined(MBEDTLS_DEBUG_C)
-    ssl = NULL; /* make sure we don't use it except for those cases */
-    (void) ssl;
+#if !defined(MBEDTLS_DEBUG_C) && \
+    !defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+    if( ssl->f_export_keys == NULL )
+    {
+        ssl = NULL; /* make sure we don't use it except for these cases */
+        (void) ssl;
+    }
 #endif
 
     /*
@@ -960,8 +962,7 @@
     ((void) mac_dec);
     ((void) mac_enc);
 
-#if defined(MBEDTLS_SSL_EXPORT_KEYS)
-    if( ssl->f_export_keys != NULL )
+    if( ssl != NULL && ssl->f_export_keys != NULL )
     {
         ssl->f_export_keys( ssl->p_export_keys,
                             MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET,
@@ -970,42 +971,26 @@
                             randbytes,
                             tls_prf_get_type( tls_prf ) );
     }
-#endif
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-
-    /* Only use PSA-based ciphers for TLS-1.2.
-     * That's relevant at least for TLS-1.0, where
-     * we assume that mbedtls_cipher_crypt() updates
-     * the structure field for the IV, which the PSA-based
-     * implementation currently doesn't. */
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-    if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+    ret = mbedtls_cipher_setup_psa( &transform->cipher_ctx_enc,
+                                    cipher_info, transform->taglen );
+    if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE )
     {
-        ret = mbedtls_cipher_setup_psa( &transform->cipher_ctx_enc,
-                                        cipher_info, transform->taglen );
-        if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE )
-        {
-            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup_psa", ret );
-            goto end;
-        }
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup_psa", ret );
+        goto end;
+    }
 
-        if( ret == 0 )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "Successfully setup PSA-based encryption cipher context" ) );
-            psa_fallthrough = 0;
-        }
-        else
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to setup PSA-based cipher context for record encryption - fall through to default setup." ) );
-            psa_fallthrough = 1;
-        }
+    if( ret == 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "Successfully setup PSA-based encryption cipher context" ) );
+        psa_fallthrough = 0;
     }
     else
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to setup PSA-based cipher context for record encryption - fall through to default setup." ) );
         psa_fallthrough = 1;
-#else
-    psa_fallthrough = 1;
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+    }
 
     if( psa_fallthrough == 1 )
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
@@ -1017,38 +1002,24 @@
     }
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-    /* Only use PSA-based ciphers for TLS-1.2.
-     * That's relevant at least for TLS-1.0, where
-     * we assume that mbedtls_cipher_crypt() updates
-     * the structure field for the IV, which the PSA-based
-     * implementation currently doesn't. */
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-    if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+    ret = mbedtls_cipher_setup_psa( &transform->cipher_ctx_dec,
+                                    cipher_info, transform->taglen );
+    if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE )
     {
-        ret = mbedtls_cipher_setup_psa( &transform->cipher_ctx_dec,
-                                        cipher_info, transform->taglen );
-        if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE )
-        {
-            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup_psa", ret );
-            goto end;
-        }
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup_psa", ret );
+        goto end;
+    }
 
-        if( ret == 0 )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "Successfully setup PSA-based decryption cipher context" ) );
-            psa_fallthrough = 0;
-        }
-        else
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to setup PSA-based cipher context for record decryption - fall through to default setup." ) );
-            psa_fallthrough = 1;
-        }
+    if( ret == 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "Successfully setup PSA-based decryption cipher context" ) );
+        psa_fallthrough = 0;
     }
     else
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to setup PSA-based cipher context for record decryption - fall through to default setup." ) );
         psa_fallthrough = 1;
-#else
-    psa_fallthrough = 1;
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+    }
 
     if( psa_fallthrough == 1 )
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
@@ -2820,10 +2791,12 @@
 
         /* Remember current epoch settings for resending */
         ssl->handshake->alt_transform_out = ssl->transform_out;
-        memcpy( ssl->handshake->alt_out_ctr, ssl->cur_out_ctr, 8 );
+        memcpy( ssl->handshake->alt_out_ctr, ssl->cur_out_ctr,
+                sizeof( ssl->handshake->alt_out_ctr ) );
 
         /* Set sequence_number to zero */
-        memset( ssl->cur_out_ctr + 2, 0, 6 );
+        memset( &ssl->cur_out_ctr[2], 0, sizeof( ssl->cur_out_ctr ) - 2 );
+
 
         /* Increment epoch */
         for( i = 2; i > 0; i-- )
@@ -2839,7 +2812,7 @@
     }
     else
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
-    memset( ssl->cur_out_ctr, 0, 8 );
+    memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) );
 
     ssl->transform_out = ssl->transform_negotiate;
     ssl->session_out = ssl->session_negotiate;
@@ -4229,7 +4202,6 @@
 #endif
 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
 
-#if defined(MBEDTLS_SSL_EXPORT_KEYS)
 void mbedtls_ssl_set_export_keys_cb( mbedtls_ssl_context *ssl,
                                      mbedtls_ssl_export_keys_t *f_export_keys,
                                      void *p_export_keys )
@@ -4237,7 +4209,6 @@
     ssl->f_export_keys = f_export_keys;
     ssl->p_export_keys = p_export_keys;
 }
-#endif
 
 #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
 void mbedtls_ssl_conf_async_private_cb(
@@ -5792,11 +5763,11 @@
     }
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
-    used += 8;
+    used += MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
     if( used <= buf_len )
     {
-        memcpy( p, ssl->cur_out_ctr, 8 );
-        p += 8;
+        memcpy( p, ssl->cur_out_ctr, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN );
+        p += MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
     }
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
@@ -6052,11 +6023,10 @@
     ssl->disable_datagram_packing = *p++;
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
-    if( (size_t)( end - p ) < 8 )
+    if( (size_t)( end - p ) < sizeof( ssl->cur_out_ctr ) )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-    memcpy( ssl->cur_out_ctr, p, 8 );
-    p += 8;
+    memcpy( ssl->cur_out_ctr, p, sizeof( ssl->cur_out_ctr ) );
+    p += sizeof( ssl->cur_out_ctr );
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
     if( (size_t)( end - p ) < 2 )
@@ -6995,4 +6965,106 @@
 
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+int mbedtls_ssl_get_handshake_transcript( mbedtls_ssl_context *ssl,
+                                          const mbedtls_md_type_t md,
+                                          unsigned char *dst,
+                                          size_t dst_len,
+                                          size_t *olen )
+{
+    ((void) ssl);
+    ((void) md);
+    ((void) dst);
+    ((void) dst_len);
+    *olen = 0;
+    return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE);
+}
+#else /* MBEDTLS_USE_PSA_CRYPTO */
+
+#if defined(MBEDTLS_SHA384_C)
+static int ssl_get_handshake_transcript_sha384( mbedtls_ssl_context *ssl,
+                                                unsigned char *dst,
+                                                size_t dst_len,
+                                                size_t *olen )
+{
+    int ret;
+    mbedtls_sha512_context sha512;
+
+    if( dst_len < 48 )
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+
+    mbedtls_sha512_init( &sha512 );
+    mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
+
+    if( ( ret = mbedtls_sha512_finish( &sha512, dst ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha512_finish", ret );
+        goto exit;
+    }
+
+    *olen = 48;
+
+exit:
+
+    mbedtls_sha512_free( &sha512 );
+    return( ret );
+}
+#endif /* MBEDTLS_SHA384_C */
+
+#if defined(MBEDTLS_SHA256_C)
+static int ssl_get_handshake_transcript_sha256( mbedtls_ssl_context *ssl,
+                                                unsigned char *dst,
+                                                size_t dst_len,
+                                                size_t *olen )
+{
+    int ret;
+    mbedtls_sha256_context sha256;
+
+    if( dst_len < 32 )
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+
+    mbedtls_sha256_init( &sha256 );
+    mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
+
+    if( ( ret = mbedtls_sha256_finish( &sha256, dst ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha256_finish", ret );
+        goto exit;
+    }
+
+    *olen = 32;
+
+exit:
+
+    mbedtls_sha256_free( &sha256 );
+    return( ret );
+}
+#endif /* MBEDTLS_SHA256_C */
+
+int mbedtls_ssl_get_handshake_transcript( mbedtls_ssl_context *ssl,
+                                          const mbedtls_md_type_t md,
+                                          unsigned char *dst,
+                                          size_t dst_len,
+                                          size_t *olen )
+{
+    switch( md )
+    {
+
+#if defined(MBEDTLS_SHA384_C)
+    case MBEDTLS_MD_SHA384:
+        return( ssl_get_handshake_transcript_sha384( ssl, dst, dst_len, olen ) );
+#endif /* MBEDTLS_SHA384_C */
+
+#if defined(MBEDTLS_SHA256_C)
+    case MBEDTLS_MD_SHA256:
+        return( ssl_get_handshake_transcript_sha256( ssl, dst, dst_len, olen ) );
+#endif /* MBEDTLS_SHA256_C */
+
+    default:
+        break;
+    }
+    return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+}
+#endif /* !MBEDTLS_USE_PSA_CRYPTO */
+
 #endif /* MBEDTLS_SSL_TLS_C */
diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c
index 5c20f29..b3a4a09 100644
--- a/library/ssl_tls13_generic.c
+++ b/library/ssl_tls13_generic.c
@@ -28,6 +28,44 @@
 
 #include "ssl_misc.h"
 
+int mbedtls_ssl_tls1_3_fetch_handshake_msg( mbedtls_ssl_context *ssl,
+                                            unsigned hs_type,
+                                            unsigned char **buf,
+                                            size_t *buflen )
+{
+    int ret;
+
+    if( ( ret = mbedtls_ssl_read_record( ssl, 0 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+        goto cleanup;
+    }
+
+    if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ||
+        ssl->in_msg[0]  != hs_type )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Receive unexpected handshake message." ) );
+        MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
+                                      MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+        ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
+        goto cleanup;
+    }
+
+    /*
+     * Jump handshake header (4 bytes, see Section 4 of RFC 8446).
+     *    ...
+     *    HandshakeType msg_type;
+     *    uint24 length;
+     *    ...
+     */
+    *buf    = ssl->in_msg   + 4;
+    *buflen = ssl->in_hslen - 4;
+
+cleanup:
+
+    return( ret );
+}
+
 int mbedtls_ssl_tls13_start_handshake_msg( mbedtls_ssl_context *ssl,
                                            unsigned hs_type,
                                            unsigned char **buf,
@@ -66,6 +104,15 @@
     return( ret );
 }
 
+void mbedtls_ssl_tls1_3_add_hs_msg_to_checksum( mbedtls_ssl_context *ssl,
+                                                unsigned hs_type,
+                                                unsigned char const *msg,
+                                                size_t msg_len )
+{
+    mbedtls_ssl_tls13_add_hs_hdr_to_checksum( ssl, hs_type, msg_len );
+    ssl->handshake->update_checksum( ssl, msg, msg_len );
+}
+
 void mbedtls_ssl_tls13_add_hs_hdr_to_checksum( mbedtls_ssl_context *ssl,
                                                unsigned hs_type,
                                                size_t total_hs_len )
diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c
index 7aec21d..b07c1c3 100644
--- a/library/ssl_tls13_keys.c
+++ b/library/ssl_tls13_keys.c
@@ -21,14 +21,16 @@
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
 
-#include "mbedtls/hkdf.h"
-#include "ssl_misc.h"
-#include "ssl_tls13_keys.h"
-#include "mbedtls/debug.h"
-
 #include <stdint.h>
 #include <string.h>
 
+#include "mbedtls/hkdf.h"
+#include "mbedtls/debug.h"
+#include "mbedtls/error.h"
+
+#include "ssl_misc.h"
+#include "ssl_tls13_keys.h"
+
 #define MBEDTLS_SSL_TLS1_3_LABEL( name, string )       \
     .name = string,
 
@@ -820,4 +822,28 @@
     return( 0 );
 }
 
+int mbedtls_ssl_tls1_3_key_schedule_stage_early( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    mbedtls_md_type_t md_type;
+
+    if( ssl->handshake->ciphersuite_info == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher suite info not found" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    md_type = ssl->handshake->ciphersuite_info->mac;
+
+    ret = mbedtls_ssl_tls1_3_evolve_secret( md_type, NULL, NULL, 0,
+                                ssl->handshake->tls1_3_master_secrets.early );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls1_3_evolve_secret", ret );
+        return( ret );
+    }
+
+    return( 0 );
+}
+
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
diff --git a/library/ssl_tls13_keys.h b/library/ssl_tls13_keys.h
index ca892b1..866aae9 100644
--- a/library/ssl_tls13_keys.h
+++ b/library/ssl_tls13_keys.h
@@ -531,4 +531,26 @@
                                           mbedtls_ssl_key_set const *traffic_keys,
                                           mbedtls_ssl_context *ssl );
 
+/*
+ * TLS 1.3 key schedule evolutions
+ *
+ *   Early -> Handshake -> Application
+ *
+ * Small wrappers around mbedtls_ssl_tls1_3_evolve_secret().
+ */
+
+/**
+ * \brief Begin TLS 1.3 key schedule by calculating early secret.
+ *
+ *        The TLS 1.3 key schedule can be viewed as a simple state machine
+ *        with states Initial -> Early -> Handshake -> Application, and
+ *        this function represents the Initial -> Early transition.
+ *
+ * \param ssl  The SSL context to operate on.
+ *
+ * \returns    \c 0 on success.
+ * \returns    A negative error code on failure.
+ */
+int mbedtls_ssl_tls1_3_key_schedule_stage_early( mbedtls_ssl_context *ssl );
+
 #endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */
diff --git a/programs/pkey/dh_client.c b/programs/pkey/dh_client.c
index eccb42a..d633e4d 100644
--- a/programs/pkey/dh_client.c
+++ b/programs/pkey/dh_client.c
@@ -270,7 +270,9 @@
     mbedtls_printf( "...\n  . Receiving and decrypting the ciphertext" );
     fflush( stdout );
 
-    mbedtls_aes_setkey_dec( &aes, buf, 256 );
+    ret = mbedtls_aes_setkey_dec( &aes, buf, 256 );
+    if( ret != 0 )
+        goto exit;
 
     memset( buf, 0, sizeof( buf ) );
 
@@ -280,7 +282,9 @@
         goto exit;
     }
 
-    mbedtls_aes_crypt_ecb( &aes, MBEDTLS_AES_DECRYPT, buf, buf );
+    ret = mbedtls_aes_crypt_ecb( &aes, MBEDTLS_AES_DECRYPT, buf, buf );
+    if( ret != 0 )
+        goto exit;
     buf[16] = '\0';
     mbedtls_printf( "\n  . Plaintext is \"%s\"\n\n", (char *) buf );
 
diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c
index 0ddb85c..75713ff 100644
--- a/programs/pkey/dh_server.c
+++ b/programs/pkey/dh_server.c
@@ -290,9 +290,13 @@
     mbedtls_printf( "...\n  . Encrypting and sending the ciphertext" );
     fflush( stdout );
 
-    mbedtls_aes_setkey_enc( &aes, buf, 256 );
+    ret = mbedtls_aes_setkey_enc( &aes, buf, 256 );
+    if( ret != 0 )
+        goto exit;
     memcpy( buf, PLAINTEXT, 16 );
-    mbedtls_aes_crypt_ecb( &aes, MBEDTLS_AES_ENCRYPT, buf, buf );
+    ret = mbedtls_aes_crypt_ecb( &aes, MBEDTLS_AES_ENCRYPT, buf, buf );
+    if( ret != 0 )
+        goto exit;
 
     if( ( ret = mbedtls_net_send( &client_fd, buf, 16 ) ) != 16 )
     {
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index cd9c8bf..f872e60 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -207,7 +207,6 @@
 #define USAGE_TICKETS ""
 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
 
-#if defined(MBEDTLS_SSL_EXPORT_KEYS)
 #define USAGE_EAP_TLS                                       \
     "    eap_tls=%%d          default: 0 (disabled)\n"
 #define USAGE_NSS_KEYLOG                                    \
@@ -230,12 +229,6 @@
 #else /* MBEDTLS_SSL_DTLS_SRTP */
 #define USAGE_SRTP ""
 #endif
-#else /* MBEDTLS_SSL_EXPORT_KEYS */
-#define USAGE_EAP_TLS ""
-#define USAGE_NSS_KEYLOG ""
-#define USAGE_NSS_KEYLOG_FILE ""
-#define USAGE_SRTP ""
-#endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
 #define USAGE_MAX_FRAG_LEN                                      \
@@ -729,7 +722,6 @@
     unsigned char *context_buf = NULL;
     size_t context_buf_len;
 #endif
-#if defined(MBEDTLS_SSL_EXPORT_KEYS)
     unsigned char eap_tls_keymaterial[16];
     unsigned char eap_tls_iv[8];
     const char* eap_tls_label = "client EAP encryption";
@@ -747,7 +739,6 @@
         MBEDTLS_TLS_SRTP_UNSET
     };
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
-#endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
     mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
@@ -1962,7 +1953,6 @@
         goto exit;
     }
 
-#if defined(MBEDTLS_SSL_EXPORT_KEYS)
     if( opt.eap_tls != 0 )
     {
         mbedtls_ssl_set_export_keys_cb( &ssl, eap_tls_key_derivation,
@@ -1981,7 +1971,6 @@
                                         &dtls_srtp_keying );
     }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
-#endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
     if( ( ret = mbedtls_ssl_set_hostname( &ssl, opt.server_name ) ) != 0 )
@@ -2169,7 +2158,6 @@
     }
 #endif
 
-#if defined(MBEDTLS_SSL_EXPORT_KEYS)
     if( opt.eap_tls != 0  )
     {
         size_t j = 0;
@@ -2286,7 +2274,6 @@
         }
     }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
-#endif /* MBEDTLS_SSL_EXPORT_KEYS */
     if( opt.reconnect != 0 )
     {
         mbedtls_printf("  . Saving session for reuse..." );
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 1700405..c0f3196 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -286,7 +286,6 @@
 #define USAGE_TICKETS ""
 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
 
-#if defined(MBEDTLS_SSL_EXPORT_KEYS)
 #define USAGE_EAP_TLS                                       \
     "    eap_tls=%%d          default: 0 (disabled)\n"
 #define USAGE_NSS_KEYLOG                                    \
@@ -307,12 +306,6 @@
 #else /* MBEDTLS_SSL_DTLS_SRTP */
 #define USAGE_SRTP ""
 #endif
-#else /* MBEDTLS_SSL_EXPORT_KEYS */
-#define USAGE_EAP_TLS ""
-#define USAGE_NSS_KEYLOG ""
-#define USAGE_NSS_KEYLOG_FILE ""
-#define USAGE_SRTP ""
-#endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
 #if defined(MBEDTLS_SSL_CACHE_C)
 #define USAGE_CACHE                                             \
@@ -1379,7 +1372,6 @@
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_status_t status;
 #endif
-#if defined(MBEDTLS_SSL_EXPORT_KEYS)
     unsigned char eap_tls_keymaterial[16];
     unsigned char eap_tls_iv[8];
     const char* eap_tls_label = "client EAP encryption";
@@ -1397,7 +1389,6 @@
          MBEDTLS_TLS_SRTP_UNSET
      };
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
-#endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
     mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
@@ -3012,7 +3003,6 @@
         goto exit;
     }
 
-#if defined(MBEDTLS_SSL_EXPORT_KEYS)
     if( opt.eap_tls != 0 )
     {
         mbedtls_ssl_set_export_keys_cb( &ssl, eap_tls_key_derivation,
@@ -3031,7 +3021,6 @@
                                         &dtls_srtp_keying );
     }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
-#endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
     io_ctx.ssl = &ssl;
     io_ctx.net = &client_fd;
@@ -3297,7 +3286,6 @@
 #endif /* MBEDTLS_X509_REMOVE_INFO */
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
-#if defined(MBEDTLS_SSL_EXPORT_KEYS)
     if( opt.eap_tls != 0 )
     {
         size_t j = 0;
@@ -3415,7 +3403,6 @@
         }
     }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
-#endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
     ret = report_cid_usage( &ssl, "initial handshake" );
diff --git a/programs/ssl/ssl_test_common_source.c b/programs/ssl/ssl_test_common_source.c
index 6ec4171..62cd35d 100644
--- a/programs/ssl/ssl_test_common_source.c
+++ b/programs/ssl/ssl_test_common_source.c
@@ -24,7 +24,6 @@
  *  limitations under the License.
  */
 
-#if defined(MBEDTLS_SSL_EXPORT_KEYS)
 void eap_tls_key_derivation( void *p_expkey,
                              mbedtls_ssl_key_export_type secret_type,
                              const unsigned char *secret,
@@ -140,8 +139,6 @@
 }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
-#endif /* MBEDTLS_SSL_EXPORT_KEYS */
-
 int ssl_check_record( mbedtls_ssl_context const *ssl,
                       unsigned char const *buf, size_t len )
 {
diff --git a/programs/ssl/ssl_test_lib.h b/programs/ssl/ssl_test_lib.h
index f9e031b..6b9e7b8 100644
--- a/programs/ssl/ssl_test_lib.h
+++ b/programs/ssl/ssl_test_lib.h
@@ -95,8 +95,6 @@
 
 #include "../test/query_config.h"
 
-#if defined(MBEDTLS_SSL_EXPORT_KEYS)
-
 typedef struct eap_tls_keys
 {
     unsigned char master_secret[48];
@@ -122,8 +120,6 @@
 
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
-#endif /* MBEDTLS_SSL_EXPORT_KEYS */
-
 typedef struct
 {
     mbedtls_ssl_context *ssl;
diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c
index 5985caf..d3faad9 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -674,7 +674,8 @@
     {
         mbedtls_des3_context des3;
         mbedtls_des3_init( &des3 );
-        mbedtls_des3_set3key_enc( &des3, tmp );
+        if( mbedtls_des3_set3key_enc( &des3, tmp ) != 0 )
+            mbedtls_exit( 1 );
         TIME_AND_TSC( "3DES",
                 mbedtls_des3_crypt_cbc( &des3, MBEDTLS_DES_ENCRYPT, BUFSIZE, tmp, buf, buf ) );
         mbedtls_des3_free( &des3 );
@@ -684,7 +685,8 @@
     {
         mbedtls_des_context des;
         mbedtls_des_init( &des );
-        mbedtls_des_setkey_enc( &des, tmp );
+        if( mbedtls_des_setkey_enc( &des, tmp ) != 0 )
+            mbedtls_exit( 1 );
         TIME_AND_TSC( "DES",
                 mbedtls_des_crypt_cbc( &des, MBEDTLS_DES_ENCRYPT, BUFSIZE, tmp, buf, buf ) );
         mbedtls_des_free( &des );
@@ -722,7 +724,7 @@
 
             memset( buf, 0, sizeof( buf ) );
             memset( tmp, 0, sizeof( tmp ) );
-            mbedtls_aes_setkey_enc( &aes, tmp, keysize );
+            CHECK_AND_CONTINUE( mbedtls_aes_setkey_enc( &aes, tmp, keysize ) );
 
             TIME_AND_TSC( title,
                 mbedtls_aes_crypt_cbc( &aes, MBEDTLS_AES_ENCRYPT, BUFSIZE, tmp, buf, buf ) );
@@ -743,7 +745,7 @@
 
             memset( buf, 0, sizeof( buf ) );
             memset( tmp, 0, sizeof( tmp ) );
-            mbedtls_aes_xts_setkey_enc( &ctx, tmp, keysize * 2 );
+            CHECK_AND_CONTINUE( mbedtls_aes_xts_setkey_enc( &ctx, tmp, keysize * 2 ) );
 
             TIME_AND_TSC( title,
                     mbedtls_aes_crypt_xts( &ctx, MBEDTLS_AES_ENCRYPT, BUFSIZE,
diff --git a/tests/Makefile b/tests/Makefile
index 449fca2..db642c7 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -5,6 +5,9 @@
 WARNING_CFLAGS ?= -Wall -Wextra -Wformat=2 -Wno-format-nonliteral
 LDFLAGS ?=
 
+# Set this to -v to see the details of failing test cases
+TEST_FLAGS ?= $(if $(filter-out 0 OFF Off off NO No no FALSE False false N n,$(CTEST_OUTPUT_ON_FAILURE)),-v,)
+
 default: all
 
 # Include public header files from ../include, test-specific header files
@@ -195,7 +198,7 @@
 
 # Test suites caught by SKIP_TEST_SUITES are built but not executed.
 check: $(BINARIES)
-	perl scripts/run-test-suites.pl --skip=$(SKIP_TEST_SUITES)
+	perl scripts/run-test-suites.pl $(TEST_FLAGS) --skip=$(SKIP_TEST_SUITES)
 
 test: check
 
diff --git a/tests/configs/user-config-for-test.h b/tests/configs/user-config-for-test.h
new file mode 100644
index 0000000..444a4bf
--- /dev/null
+++ b/tests/configs/user-config-for-test.h
@@ -0,0 +1,57 @@
+/* MBEDTLS_USER_CONFIG_FILE for testing.
+ * Only used for a few test configurations.
+ *
+ * Typical usage (note multiple levels of quoting):
+ *     make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/user-config-for-test.h\"'"
+ */
+
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#if defined(PSA_CRYPTO_DRIVER_TEST_ALL)
+
+/* Enable the use of the test driver in the library, and build the generic
+ * part of the test driver. */
+#define PSA_CRYPTO_DRIVER_TEST
+
+/* Use the accelerator driver for all cryptographic mechanisms for which
+ * the test driver implemented. */
+#define MBEDTLS_PSA_ACCEL_KEY_TYPE_AES
+#define MBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA
+#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR
+#define MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR
+#define MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING
+#define MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7
+#define MBEDTLS_PSA_ACCEL_ALG_CTR
+#define MBEDTLS_PSA_ACCEL_ALG_CFB
+#define MBEDTLS_PSA_ACCEL_ALG_ECDSA
+#define MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA
+#define MBEDTLS_PSA_ACCEL_ALG_MD5
+#define MBEDTLS_PSA_ACCEL_ALG_OFB
+#define MBEDTLS_PSA_ACCEL_ALG_RIPEMD160
+#define MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN
+#define MBEDTLS_PSA_ACCEL_ALG_RSA_PSS
+#define MBEDTLS_PSA_ACCEL_ALG_SHA_1
+#define MBEDTLS_PSA_ACCEL_ALG_SHA_224
+#define MBEDTLS_PSA_ACCEL_ALG_SHA_256
+#define MBEDTLS_PSA_ACCEL_ALG_SHA_384
+#define MBEDTLS_PSA_ACCEL_ALG_SHA_512
+#define MBEDTLS_PSA_ACCEL_ALG_XTS
+#define MBEDTLS_PSA_ACCEL_ALG_CMAC
+#define MBEDTLS_PSA_ACCEL_ALG_HMAC
+
+#endif  /* PSA_CRYPTO_DRIVER_TEST_ALL */
diff --git a/tests/include/test/helpers.h b/tests/include/test/helpers.h
index 27e5599..ef32cdf 100644
--- a/tests/include/test/helpers.h
+++ b/tests/include/test/helpers.h
@@ -73,6 +73,8 @@
     const char *filename;
     int line_no;
     unsigned long step;
+    char line1[76];
+    char line2[76];
 #if defined(MBEDTLS_TEST_MUTEX_USAGE)
     const char *mutex_usage_error;
 #endif
@@ -132,6 +134,27 @@
 void mbedtls_test_info_reset( void );
 
 /**
+ * \brief           Record the current test case as a failure if two integers
+ *                  have a different value.
+ *
+ *                  This function is usually called via the macro
+ *                  #TEST_EQUAL.
+ *
+ * \param test      Description of the failure or assertion that failed. This
+ *                  MUST be a string literal. This normally has the form
+ *                  "EXPR1 == EXPR2" where EXPR1 has the value \p value1
+ *                  and EXPR2 has the value \p value2.
+ * \param line_no   Line number where the failure originated.
+ * \param filename  Filename where the failure originated.
+ * \param value1    The first value to compare.
+ * \param value2    The second value to compare.
+ *
+ * \return          \c 1 if the values are equal, otherwise \c 0.
+ */
+int mbedtls_test_equal( const char *test, int line_no, const char* filename,
+                        unsigned long long value1, unsigned long long value2 );
+
+/**
  * \brief          This function decodes the hexadecimal representation of
  *                 data.
  *
diff --git a/tests/include/test/macros.h b/tests/include/test/macros.h
index 9b3fc9c..a88b2e8 100644
--- a/tests/include/test/macros.h
+++ b/tests/include/test/macros.h
@@ -73,15 +73,21 @@
        }                                                    \
     } while( 0 )
 
-/** Evaluate two expressions and fail the test case if they have different
- * values.
+/** Evaluate two integer expressions and fail the test case if they have
+ * different values.
  *
- * \param expr1     An expression to evaluate.
- * \param expr2     The expected value of \p expr1. This can be any
- *                  expression, but it is typically a constant.
+ * The two expressions should have the same signedness, otherwise the
+ * comparison is not meaningful if the signed value is negative.
+ *
+ * \param expr1     An integral-typed expression to evaluate.
+ * \param expr2     Another integral-typed expression to evaluate.
  */
-#define TEST_EQUAL( expr1, expr2 )              \
-    TEST_ASSERT( ( expr1 ) == ( expr2 ) )
+#define TEST_EQUAL( expr1, expr2 )                                      \
+    do {                                                                \
+        if( ! mbedtls_test_equal( #expr1 " == " #expr2, __LINE__, __FILE__, \
+                                  expr1, expr2 ) )                      \
+            goto exit;                                                  \
+    } while( 0 )
 
 /** Allocate memory dynamically and fail the test case if this fails.
  * The allocated memory will be filled with zeros.
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index f30795c..0991743 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -175,10 +175,10 @@
 
     # if MAKEFLAGS is not set add the -j option to speed up invocations of make
     if [ -z "${MAKEFLAGS+set}" ]; then
-        export MAKEFLAGS="-j"
+        export MAKEFLAGS="-j$(all_sh_nproc)"
     fi
 
-    # Include more verbose output for failing tests run by CMake
+    # Include more verbose output for failing tests run by CMake or make
     export CTEST_OUTPUT_ON_FAILURE=1
 
     # CFLAGS and LDFLAGS for Asan builds that don't use CMake
@@ -343,6 +343,18 @@
 trap 'fatal_signal INT' INT
 trap 'fatal_signal TERM' TERM
 
+# Number of processors on this machine. Used as the default setting
+# for parallel make.
+all_sh_nproc ()
+{
+    {
+        nproc || # Linux
+        sysctl -n hw.ncpuonline || # NetBSD, OpenBSD
+        sysctl -n hw.ncpu || # FreeBSD
+        echo 1
+    } 2>/dev/null
+}
+
 msg()
 {
     if [ -n "${current_component:-}" ]; then
@@ -1560,31 +1572,8 @@
     scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_KEY_TYPE_DES
     scripts/config.py unset MBEDTLS_DES_C
 
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    loc_cflags="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_AES"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CTR"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CFB"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_ECDSA"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD5"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_OFB"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RIPEMD160"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PSS"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_1"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_224"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_256"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_384"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_512"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_XTS"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CMAC"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_HMAC"
+    loc_cflags="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST_ALL"
+    loc_cflags="${loc_cflags} '-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/user-config-for-test.h\"'"
     loc_cflags="${loc_cflags} -I../tests/include -O2"
 
     make CC=gcc CFLAGS="$loc_cflags" LDFLAGS="$ASAN_CFLAGS"
@@ -1607,6 +1596,19 @@
     make test
 }
 
+component_test_psa_crypto_config_chachapoly_disabled() {
+    # full minus MBEDTLS_CHACHAPOLY_C without PSA_WANT_ALG_GCM and PSA_WANT_ALG_CHACHA20_POLY1305
+    msg "build: full minus MBEDTLS_CHACHAPOLY_C without PSA_WANT_ALG_GCM and PSA_WANT_ALG_CHACHA20_POLY1305"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_CHACHAPOLY_C
+    scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_GCM
+    scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_CHACHA20_POLY1305
+    make CC=gcc CFLAGS="$ASAN_CFLAGS -O2" LDFLAGS="$ASAN_CFLAGS"
+
+    msg "test: full minus MBEDTLS_CHACHAPOLY_C without PSA_WANT_ALG_GCM and PSA_WANT_ALG_CHACHA20_POLY1305"
+    make test
+}
+
 # This should be renamed to test and updated once the accelerator ECDSA code is in place and ready to test.
 component_build_psa_accel_alg_ecdsa() {
     # full plus MBEDTLS_PSA_CRYPTO_CONFIG with PSA_WANT_ALG_ECDSA
@@ -2083,6 +2085,18 @@
     tests/compat.sh
 }
 
+component_test_CID_no_debug() {
+    msg "build: Connection ID enabled, debug disabled"
+    scripts/config.py unset MBEDTLS_DEBUG_C
+    scripts/config.py set MBEDTLS_SSL_DTLS_CONNECTION_ID
+
+    CC=gcc cmake .
+    make
+
+    msg "test: Connection ID enabled, debug disabled"
+    make test
+}
+
 component_test_ssl_alloc_buffer_and_mfl () {
     msg "build: default config with memory buffer allocator and MFL extension"
     scripts/config.py set MBEDTLS_MEMORY_BUFFER_ALLOC_C
@@ -2237,31 +2251,8 @@
     scripts/config.py full
     scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
     scripts/config.py set MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS
-    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    loc_cflags="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_AES"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CTR"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CFB"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_ECDSA"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD5"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_OFB"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RIPEMD160"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PSS"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_1"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_224"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_256"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_384"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_512"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_XTS"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CMAC"
-    loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_HMAC"
+    loc_cflags="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST_ALL"
+    loc_cflags="${loc_cflags} '-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/user-config-for-test.h\"'"
     loc_cflags="${loc_cflags} -I../tests/include -O2"
 
     make CC=gcc CFLAGS="${loc_cflags}" LDFLAGS="$ASAN_CFLAGS"
diff --git a/tests/scripts/check_names.py b/tests/scripts/check_names.py
index a9aa118..ac2490f 100755
--- a/tests/scripts/check_names.py
+++ b/tests/scripts/check_names.py
@@ -44,6 +44,7 @@
 
 import abc
 import argparse
+import fnmatch
 import glob
 import textwrap
 import os
@@ -222,8 +223,9 @@
         # Memo for storing "glob expression": set(filepaths)
         self.files = {}
 
-        # Globally excluded filenames
-        self.excluded_files = ["**/bn_mul", "**/compat-2.x.h"]
+        # Globally excluded filenames.
+        # Note that "*" can match directory separators in exclude lists.
+        self.excluded_files = ["*/bn_mul", "*/compat-2.x.h"]
 
     @staticmethod
     def check_repo_path():
@@ -302,6 +304,15 @@
             "mbed_words": mbed_words
         }
 
+    def is_file_excluded(self, path, exclude_wildcards):
+        """Whether the given file path is excluded."""
+        # exclude_wildcards may be None. Also, consider the global exclusions.
+        exclude_wildcards = (exclude_wildcards or []) + self.excluded_files
+        for pattern in exclude_wildcards:
+            if fnmatch.fnmatch(path, pattern):
+                return True
+        return False
+
     def get_files(self, include_wildcards, exclude_wildcards):
         """
         Get all files that match any of the UNIX-style wildcards. While the
@@ -317,25 +328,11 @@
         """
         accumulator = set()
 
-        # exclude_wildcards may be None. Also, consider the global exclusions.
-        exclude_wildcards = (exclude_wildcards or []) + self.excluded_files
-
-        # Internal function to hit the memoisation cache or add to it the result
-        # of a glob operation. Used both for inclusion and exclusion since the
-        # only difference between them is whether they perform set union or
-        # difference on the return value of this function.
-        def hit_cache(wildcard):
-            if wildcard not in self.files:
-                self.files[wildcard] = set(glob.glob(wildcard, recursive=True))
-            return self.files[wildcard]
-
         for include_wildcard in include_wildcards:
-            accumulator = accumulator.union(hit_cache(include_wildcard))
+            accumulator = accumulator.union(glob.iglob(include_wildcard))
 
-        for exclude_wildcard in exclude_wildcards:
-            accumulator = accumulator.difference(hit_cache(exclude_wildcard))
-
-        return list(accumulator)
+        return list(path for path in accumulator
+                    if not self.is_file_excluded(path, exclude_wildcards))
 
     def parse_macros(self, include, exclude=None):
         """
diff --git a/tests/scripts/generate_psa_tests.py b/tests/scripts/generate_psa_tests.py
index c788ce6..4c8143f 100755
--- a/tests/scripts/generate_psa_tests.py
+++ b/tests/scripts/generate_psa_tests.py
@@ -155,8 +155,30 @@
     tc.set_arguments([key_type] + list(args))
     return tc
 
+def test_case_for_key_type_invalid_argument(
+        verb: str, key_type: str, bits: int,
+        dependencies: List[str],
+        *args: str,
+        param_descr: str = ''
+) -> test_case.TestCase:
+    """Return one test case exercising a key creation method
+    for an invalid argument when key is public.
+    """
+    hack_dependencies_not_implemented(dependencies)
+    tc = test_case.TestCase()
+    short_key_type = re.sub(r'PSA_(KEY_TYPE|ECC_FAMILY)_', r'', key_type)
+    adverb = 'not' if dependencies else 'never'
+    if param_descr:
+        adverb = param_descr + ' ' + adverb
+    tc.set_description('PSA {} {} {}-bit invalid argument'
+                       .format(verb, short_key_type, bits))
+    tc.set_function(verb + '_invalid_argument')
+    tc.set_dependencies(dependencies)
+    tc.set_arguments([key_type] + list(args))
+    return tc
+
 class NotSupported:
-    """Generate test cases for when something is not supported."""
+    """Generate test cases for when something is not supported or argument is inavlid."""
 
     def __init__(self, info: Information) -> None:
         self.constructors = info.constructors
@@ -171,11 +193,13 @@
             param: Optional[int] = None,
             param_descr: str = '',
     ) -> Iterator[test_case.TestCase]:
-        """Return test cases exercising key creation when the given type is unsupported.
+        """Return test cases exercising key creation when the given type is unsupported
+        or argument is invalid.
 
         If param is present and not None, emit test cases conditioned on this
         parameter not being supported. If it is absent or None, emit test cases
-        conditioned on the base type not being supported.
+        conditioned on the base type not being supported. If key is public emit test
+        case for invalid argument.
         """
         if kt.name in self.ALWAYS_SUPPORTED:
             # Don't generate test cases for key types that are always supported.
@@ -203,12 +227,20 @@
                 # supported or not depending on implementation capabilities,
                 # only generate the test case once.
                 continue
-            yield test_case_for_key_type_not_supported(
-                'generate', kt.expression, bits,
-                finish_family_dependencies(generate_dependencies, bits),
-                str(bits),
-                param_descr=param_descr,
-            )
+            if kt.name.endswith('_PUBLIC_KEY'):
+                yield test_case_for_key_type_invalid_argument(
+                    'generate', kt.expression, bits,
+                    finish_family_dependencies(generate_dependencies, bits),
+                    str(bits),
+                    param_descr=param_descr,
+                )
+            else:
+                yield test_case_for_key_type_not_supported(
+                    'generate', kt.expression, bits,
+                    finish_family_dependencies(generate_dependencies, bits),
+                    str(bits),
+                    param_descr=param_descr,
+                )
             # To be added: derive
 
     ECC_KEY_TYPES = ('PSA_KEY_TYPE_ECC_KEY_PAIR',
@@ -229,7 +261,6 @@
                 yield from self.test_cases_for_key_type_not_supported(
                     kt, 0, param_descr='curve')
 
-
 class StorageKey(psa_storage.Key):
     """Representation of a key for storage format testing."""
 
diff --git a/tests/src/helpers.c b/tests/src/helpers.c
index 4d3d53d..ec4d84e 100644
--- a/tests/src/helpers.c
+++ b/tests/src/helpers.c
@@ -95,6 +95,31 @@
     mbedtls_test_info.test = 0;
     mbedtls_test_info.line_no = 0;
     mbedtls_test_info.filename = 0;
+    memset( mbedtls_test_info.line1, 0, sizeof( mbedtls_test_info.line1 ) );
+    memset( mbedtls_test_info.line2, 0, sizeof( mbedtls_test_info.line2 ) );
+}
+
+int mbedtls_test_equal( const char *test, int line_no, const char* filename,
+                        unsigned long long value1, unsigned long long value2 )
+{
+    if( value1 == value2 )
+        return( 1 );
+    if( mbedtls_test_info.result == MBEDTLS_TEST_RESULT_FAILED )
+    {
+        /* We've already recorded the test as having failed. Don't
+         * overwrite any previous information about the failure. */
+        return( 0 );
+    }
+    mbedtls_test_fail( test, line_no, filename );
+    (void) mbedtls_snprintf( mbedtls_test_info.line1,
+                             sizeof( mbedtls_test_info.line1 ),
+                             "lhs = 0x%016llx = %lld",
+                             value1, (long long) value1 );
+    (void) mbedtls_snprintf( mbedtls_test_info.line2,
+                             sizeof( mbedtls_test_info.line2 ),
+                             "rhs = 0x%016llx = %lld",
+                             value2, (long long) value2 );
+    return( 0 );
 }
 
 int mbedtls_test_unhexify( unsigned char *obuf,
diff --git a/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c
index e4e55c9..923d2c1 100644
--- a/tests/src/psa_exercise_key.c
+++ b/tests/src/psa_exercise_key.c
@@ -663,7 +663,7 @@
         TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
                                           MBEDTLS_ASN1_SEQUENCE |
                                           MBEDTLS_ASN1_CONSTRUCTED ), 0 );
-        TEST_EQUAL( p + len, end );
+        TEST_EQUAL( len, end - p );
         if( ! mbedtls_test_asn1_skip_integer( &p, end, 0, 0, 0 ) )
             goto exit;
         if( ! mbedtls_test_asn1_skip_integer( &p, end, bits, bits, 1 ) )
@@ -684,7 +684,7 @@
             goto exit;
         if( ! mbedtls_test_asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
             goto exit;
-        TEST_EQUAL( p, end );
+        TEST_EQUAL( p - end, 0 );
 
         TEST_ASSERT( exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE );
     }
@@ -716,12 +716,12 @@
                                           MBEDTLS_ASN1_SEQUENCE |
                                           MBEDTLS_ASN1_CONSTRUCTED ),
                     0 );
-        TEST_EQUAL( p + len, end );
+        TEST_EQUAL( len, end - p );
         if( ! mbedtls_test_asn1_skip_integer( &p, end, bits, bits, 1 ) )
             goto exit;
         if( ! mbedtls_test_asn1_skip_integer( &p, end, 2, bits, 1 ) )
             goto exit;
-        TEST_EQUAL( p, end );
+        TEST_EQUAL( p - end, 0 );
 
 
         TEST_ASSERT( exported_length <=
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index e0abd3f..e7cd9f8 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -626,6 +626,8 @@
 # Wait for process $2 named $3 to be listening on port $1. Print error to $4.
 if type lsof >/dev/null 2>/dev/null; then
     wait_app_start() {
+        newline='
+'
         START_TIME=$(date +%s)
         if [ "$DTLS" -eq 1 ]; then
             proto=UDP
@@ -633,7 +635,15 @@
             proto=TCP
         fi
         # Make a tight loop, server normally takes less than 1s to start.
-        while ! lsof -a -n -b -i "$proto:$1" -p "$2" >/dev/null 2>/dev/null; do
+        while true; do
+              SERVER_PIDS=$(lsof -a -n -b -i "$proto:$1" -F p)
+              # When we use a proxy, it will be listening on the same port we
+              # are checking for as well as the server and lsof will list both.
+              # If multiple PIDs are returned, each one will be on a separate
+              # line, each prepended with 'p'.
+             case ${newline}${SERVER_PIDS}${newline} in
+                  *${newline}p${2}${newline}*) break;;
+              esac
               if [ $(( $(date +%s) - $START_TIME )) -gt $DOG_DELAY ]; then
                   echo "$3 START TIMEOUT"
                   echo "$3 START TIMEOUT" >> $4
@@ -753,7 +763,7 @@
 # check if the given command uses dtls and sets global variable DTLS
 detect_dtls() {
     case "$1" in
-        *dtls=1*|-dtls|-u) DTLS=1;;
+        *dtls=1*|*-dtls*|*-u*) DTLS=1;;
         *) DTLS=0;;
     esac
 }
@@ -1309,22 +1319,24 @@
 
 # fix commands to use this port, force IPv4 while at it
 # +SRV_PORT will be replaced by either $SRV_PORT or $PXY_PORT later
+# Note: Using 'localhost' rather than 127.0.0.1 here is unwise, as on many
+# machines that will resolve to ::1, and we don't want ipv6 here.
 P_SRV="$P_SRV server_addr=127.0.0.1 server_port=$SRV_PORT"
 P_CLI="$P_CLI server_addr=127.0.0.1 server_port=+SRV_PORT"
 P_PXY="$P_PXY server_addr=127.0.0.1 server_port=$SRV_PORT listen_addr=127.0.0.1 listen_port=$PXY_PORT ${SEED:+"seed=$SEED"}"
 O_SRV="$O_SRV -accept $SRV_PORT"
-O_CLI="$O_CLI -connect localhost:+SRV_PORT"
+O_CLI="$O_CLI -connect 127.0.0.1:+SRV_PORT"
 G_SRV="$G_SRV -p $SRV_PORT"
 G_CLI="$G_CLI -p +SRV_PORT"
 
 if [ -n "${OPENSSL_LEGACY:-}" ]; then
     O_LEGACY_SRV="$O_LEGACY_SRV -accept $SRV_PORT -dhparam data_files/dhparams.pem"
-    O_LEGACY_CLI="$O_LEGACY_CLI -connect localhost:+SRV_PORT"
+    O_LEGACY_CLI="$O_LEGACY_CLI -connect 127.0.0.1:+SRV_PORT"
 fi
 
 if [ -n "${OPENSSL_NEXT:-}" ]; then
     O_NEXT_SRV="$O_NEXT_SRV -accept $SRV_PORT"
-    O_NEXT_CLI="$O_NEXT_CLI -connect localhost:+SRV_PORT"
+    O_NEXT_CLI="$O_NEXT_CLI -connect 127.0.0.1:+SRV_PORT"
 fi
 
 if [ -n "${GNUTLS_NEXT_SERV:-}" ]; then
@@ -2735,10 +2747,13 @@
             -c "parse new session ticket" \
             -c "a session has been resumed"
 
+# For reasons that aren't fully understood, this test randomly fails with high
+# probability with OpenSSL 1.0.2g on the CI, see #5012.
+requires_openssl_next
 run_test    "Session resume using tickets, DTLS: openssl client" \
             "$P_SRV dtls=1 debug_level=3 tickets=1" \
-            "( $O_CLI -dtls -sess_out $SESSION; \
-               $O_CLI -dtls -sess_in $SESSION; \
+            "( $O_NEXT_CLI -dtls -sess_out $SESSION; \
+               $O_NEXT_CLI -dtls -sess_in $SESSION; \
                rm -f $SESSION )" \
             0 \
             -s "found session ticket extension" \
@@ -2935,10 +2950,13 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
+# For reasons that aren't fully understood, this test randomly fails with high
+# probability with OpenSSL 1.0.2g on the CI, see #5012.
+requires_openssl_next
 run_test    "Session resume using cache, DTLS: openssl client" \
             "$P_SRV dtls=1 debug_level=3 tickets=0" \
-            "( $O_CLI -dtls -sess_out $SESSION; \
-               $O_CLI -dtls -sess_in $SESSION; \
+            "( $O_NEXT_CLI -dtls -sess_out $SESSION; \
+               $O_NEXT_CLI -dtls -sess_in $SESSION; \
                rm -f $SESSION )" \
             0 \
             -s "found session ticket extension" \
@@ -8654,7 +8672,6 @@
             -s "Extra-header:" \
             -c "Extra-header:"
 
-requires_config_enabled MBEDTLS_SSL_EXPORT_KEYS
 run_test    "export keys functionality" \
             "$P_SRV eap_tls=1 debug_level=3" \
             "$P_CLI eap_tls=1 debug_level=3" \
diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function
index a5fd717..17926eb 100644
--- a/tests/suites/host_test.function
+++ b/tests/suites/host_test.function
@@ -778,6 +778,12 @@
                     mbedtls_fprintf( stdout, "line %d, %s",
                                      mbedtls_test_info.line_no,
                                      mbedtls_test_info.filename );
+                    if( mbedtls_test_info.line1[0] != 0 )
+                        mbedtls_fprintf( stdout, "\n  %s",
+                                         mbedtls_test_info.line1 );
+                    if( mbedtls_test_info.line2[0] != 0 )
+                        mbedtls_fprintf( stdout, "\n  %s",
+                                         mbedtls_test_info.line2 );
                 }
                 fflush( stdout );
             }
diff --git a/tests/suites/test_suite_aes.function b/tests/suites/test_suite_aes.function
index 1892c25..52af8e0 100644
--- a/tests/suites/test_suite_aes.function
+++ b/tests/suites/test_suite_aes.function
@@ -67,7 +67,7 @@
 
     mbedtls_aes_init( &ctx );
 
-    mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
+    TEST_ASSERT( mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 ) == 0 );
     TEST_ASSERT( mbedtls_aes_crypt_cbc( &ctx, MBEDTLS_AES_ENCRYPT, src_str->len, iv_str->x, src_str->x, output ) == cbc_result );
     if( cbc_result == 0 )
     {
@@ -92,7 +92,7 @@
     memset(output, 0x00, 100);
     mbedtls_aes_init( &ctx );
 
-    mbedtls_aes_setkey_dec( &ctx, key_str->x, key_str->len * 8 );
+    TEST_ASSERT( mbedtls_aes_setkey_dec( &ctx, key_str->x, key_str->len * 8 ) == 0 );
     TEST_ASSERT( mbedtls_aes_crypt_cbc( &ctx, MBEDTLS_AES_DECRYPT, src_str->len, iv_str->x, src_str->x, output ) == cbc_result );
     if( cbc_result == 0)
     {
@@ -241,7 +241,7 @@
     mbedtls_aes_init( &ctx );
 
 
-    mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
+    TEST_ASSERT( mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 ) == 0 );
     TEST_ASSERT( mbedtls_aes_crypt_cfb128( &ctx, MBEDTLS_AES_ENCRYPT, 16, &iv_offset, iv_str->x, src_str->x, output ) == 0 );
 
     TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
@@ -263,7 +263,7 @@
     mbedtls_aes_init( &ctx );
 
 
-    mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
+    TEST_ASSERT( mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 ) == 0 );
     TEST_ASSERT( mbedtls_aes_crypt_cfb128( &ctx, MBEDTLS_AES_DECRYPT, 16, &iv_offset, iv_str->x, src_str->x, output ) == 0 );
 
     TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
@@ -284,7 +284,7 @@
     mbedtls_aes_init( &ctx );
 
 
-    mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
+    TEST_ASSERT( mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 ) == 0 );
     TEST_ASSERT( mbedtls_aes_crypt_cfb8( &ctx, MBEDTLS_AES_ENCRYPT, src_str->len, iv_str->x, src_str->x, output ) == 0 );
 
     TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
@@ -306,7 +306,7 @@
     mbedtls_aes_init( &ctx );
 
 
-    mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
+    TEST_ASSERT( mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 ) == 0 );
     TEST_ASSERT( mbedtls_aes_crypt_cfb8( &ctx, MBEDTLS_AES_DECRYPT, src_str->len, iv_str->x, src_str->x, output ) == 0 );
 
     TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
diff --git a/tests/suites/test_suite_cipher.aes.data b/tests/suites/test_suite_cipher.aes.data
index 4dbdd52..c8fbca2 100644
--- a/tests/suites/test_suite_cipher.aes.data
+++ b/tests/suites/test_suite_cipher.aes.data
@@ -1798,6 +1798,102 @@
 depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
 test_vec_crypt:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"5c9d844ed46f9885085e5d6a4f94c7d7":"014730f80ac625fe84f026c60bfd547d":0:1
 
+AES-128-ECB crypt Encrypt NIST KAT #1 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_ENCRYPT:"00000000000000000000000000000000":"":"80000000000000000000000000000000":"3ad78e726c1ec02b7ebfe92b23d9ec34":0:1
+
+AES-128-ECB crypt Encrypt NIST KAT #2 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_ENCRYPT:"ffffffffffffffffffffffffffffe000":"":"00000000000000000000000000000000":"323994cfb9da285a5d9642e1759b224a":0:1
+
+AES-128-ECB crypt Encrypt NIST KAT #3 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_ENCRYPT:"10a58869d74be5a374cf867cfb473859":"":"00000000000000000000000000000000":"6d251e6944b051e04eaa6fb4dbf78465":0:1
+
+AES-128-ECB crypt Encrypt NIST KAT #4 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_ENCRYPT:"00000000000000000000000000000000":"":"f34481ec3cc627bacd5dc3fb08f273e6":"0336763e966d92595a567cc9ce537f5e":0:1
+
+AES-128-ECB crypt Decrypt NIST KAT #1 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"00000000000000000000000000000000":"":"3ad78e726c1ec02b7ebfe92b23d9ec34":"80000000000000000000000000000000":0:1
+
+AES-128-ECB crypt Decrypt NIST KAT #2 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"ffffc000000000000000000000000000":"":"df556a33438db87bc41b1752c55e5e49":"00000000000000000000000000000000":0:1
+
+AES-128-ECB crypt Decrypt NIST KAT #3 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"10a58869d74be5a374cf867cfb473859":"":"6d251e6944b051e04eaa6fb4dbf78465":"00000000000000000000000000000000":0:1
+
+AES-128-ECB crypt Decrypt NIST KAT #4 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_ECB:MBEDTLS_DECRYPT:"00000000000000000000000000000000":"":"0336763e966d92595a567cc9ce537f5e":"f34481ec3cc627bacd5dc3fb08f273e6":0:1
+
+AES-192-ECB crypt Encrypt NIST KAT #1 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_ENCRYPT:"000000000000000000000000000000000000000000000000":"":"80000000000000000000000000000000":"6cd02513e8d4dc986b4afe087a60bd0c":0:1
+
+AES-192-ECB crypt Encrypt NIST KAT #2 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_ENCRYPT:"ff0000000000000000000000000000000000000000000000":"":"00000000000000000000000000000000":"833f71258d53036b02952c76c744f5a1":0:1
+
+AES-192-ECB crypt Encrypt NIST KAT #3 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_ENCRYPT:"e9f065d7c13573587f7875357dfbb16c53489f6a4bd0f7cd":"":"00000000000000000000000000000000":"0956259c9cd5cfd0181cca53380cde06":0:1
+
+AES-192-ECB crypt Encrypt NIST KAT #4 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_ENCRYPT:"000000000000000000000000000000000000000000000000":"":"1b077a6af4b7f98229de786d7516b639":"275cfc0413d8ccb70513c3859b1d0f72":0:1
+
+AES-192-ECB crypt Decrypt NIST KAT #1 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"000000000000000000000000000000000000000000000000":"":"6cd02513e8d4dc986b4afe087a60bd0c":"80000000000000000000000000000000":0:1
+
+AES-192-ECB crypt Decrypt NIST KAT #2 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"ffe000000000000000000000000000000000000000000000":"":"7ababc4b3f516c9aafb35f4140b548f9":"00000000000000000000000000000000":0:1
+
+AES-192-ECB crypt Decrypt NIST KAT #3 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"e9f065d7c13573587f7875357dfbb16c53489f6a4bd0f7cd":"":"0956259c9cd5cfd0181cca53380cde06":"00000000000000000000000000000000":0:1
+
+AES-192-ECB crypt Decrypt NIST KAT #4 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_ECB:MBEDTLS_DECRYPT:"000000000000000000000000000000000000000000000000":"":"275cfc0413d8ccb70513c3859b1d0f72":"1b077a6af4b7f98229de786d7516b639":0:1
+
+AES-256-ECB crypt Encrypt NIST KAT #1 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_ENCRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"":"80000000000000000000000000000000":"ddc6bf790c15760d8d9aeb6f9a75fd4e":0:1
+
+AES-256-ECB crypt Encrypt NIST KAT #2 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_ENCRYPT:"ff00000000000000000000000000000000000000000000000000000000000000":"":"00000000000000000000000000000000":"ec52a212f80a09df6317021bc2a9819e":0:1
+
+AES-256-ECB crypt Encrypt NIST KAT #3 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_ENCRYPT:"c47b0294dbbbee0fec4757f22ffeee3587ca4730c3d33b691df38bab076bc558":"":"00000000000000000000000000000000":"46f2fb342d6f0ab477476fc501242c5f":0:1
+
+AES-256-ECB crypt Encrypt NIST KAT #4 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_ENCRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"":"014730f80ac625fe84f026c60bfd547d":"5c9d844ed46f9885085e5d6a4f94c7d7":0:1
+
+AES-256-ECB crypt Decrypt NIST KAT #1 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"":"ddc6bf790c15760d8d9aeb6f9a75fd4e":"80000000000000000000000000000000":0:1
+
+AES-256-ECB crypt Decrypt NIST KAT #2 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"ffe0000000000000000000000000000000000000000000000000000000000000":"":"d1ccb9b1337002cbac42c520b5d67722":"00000000000000000000000000000000":0:1
+
+AES-256-ECB crypt Decrypt NIST KAT #3 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"c47b0294dbbbee0fec4757f22ffeee3587ca4730c3d33b691df38bab076bc558":"":"46f2fb342d6f0ab477476fc501242c5f":"00000000000000000000000000000000":0:1
+
+AES-256-ECB crypt Decrypt NIST KAT #4 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"":"5c9d844ed46f9885085e5d6a4f94c7d7":"014730f80ac625fe84f026c60bfd547d":0:1
+
 Cipher Corner Case behaviours
 depends_on:MBEDTLS_AES_C
 cipher_special_behaviours:
diff --git a/tests/suites/test_suite_des.function b/tests/suites/test_suite_des.function
index 5b24935..7256fb5 100644
--- a/tests/suites/test_suite_des.function
+++ b/tests/suites/test_suite_des.function
@@ -24,7 +24,7 @@
     mbedtls_des_init( &ctx );
 
 
-    mbedtls_des_setkey_enc( &ctx, key_str->x );
+    TEST_ASSERT( mbedtls_des_setkey_enc( &ctx, key_str->x ) == 0 );
     TEST_ASSERT( mbedtls_des_crypt_ecb( &ctx, src_str->x, output ) == 0 );
 
     TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
@@ -44,7 +44,7 @@
     mbedtls_des_init( &ctx );
 
 
-    mbedtls_des_setkey_dec( &ctx, key_str->x );
+    TEST_ASSERT( mbedtls_des_setkey_dec( &ctx, key_str->x ) == 0 );
     TEST_ASSERT( mbedtls_des_crypt_ecb( &ctx, src_str->x, output ) == 0 );
 
     TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
@@ -65,7 +65,7 @@
     mbedtls_des_init( &ctx );
 
 
-    mbedtls_des_setkey_enc( &ctx, key_str->x );
+    TEST_ASSERT( mbedtls_des_setkey_enc( &ctx, key_str->x ) == 0 );
     TEST_ASSERT( mbedtls_des_crypt_cbc( &ctx, MBEDTLS_DES_ENCRYPT, src_str->len, iv_str->x, src_str->x, output ) == cbc_result );
     if( cbc_result == 0 )
     {
@@ -91,7 +91,7 @@
     mbedtls_des_init( &ctx );
 
 
-    mbedtls_des_setkey_dec( &ctx, key_str->x );
+    TEST_ASSERT( mbedtls_des_setkey_dec( &ctx, key_str->x ) == 0 );
     TEST_ASSERT( mbedtls_des_crypt_cbc( &ctx, MBEDTLS_DES_DECRYPT, src_str->len, iv_str->x, src_str->x, output ) == cbc_result );
     if( cbc_result == 0 )
     {
@@ -117,9 +117,9 @@
 
 
     if( key_count == 2 )
-        mbedtls_des3_set2key_enc( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set2key_enc( &ctx, key_str->x ) == 0 );
     else if( key_count == 3 )
-        mbedtls_des3_set3key_enc( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set3key_enc( &ctx, key_str->x ) == 0 );
     else
         TEST_ASSERT( 0 );
 
@@ -144,9 +144,9 @@
 
 
     if( key_count == 2 )
-        mbedtls_des3_set2key_dec( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set2key_dec( &ctx, key_str->x ) == 0 );
     else if( key_count == 3 )
-        mbedtls_des3_set3key_dec( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set3key_dec( &ctx, key_str->x ) == 0 );
     else
         TEST_ASSERT( 0 );
 
@@ -172,9 +172,9 @@
 
 
     if( key_count == 2 )
-        mbedtls_des3_set2key_enc( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set2key_enc( &ctx, key_str->x ) == 0 );
     else if( key_count == 3 )
-        mbedtls_des3_set3key_enc( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set3key_enc( &ctx, key_str->x ) == 0 );
     else
         TEST_ASSERT( 0 );
 
@@ -205,9 +205,9 @@
 
 
     if( key_count == 2 )
-        mbedtls_des3_set2key_dec( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set2key_dec( &ctx, key_str->x ) == 0 );
     else if( key_count == 3 )
-        mbedtls_des3_set3key_dec( &ctx, key_str->x );
+        TEST_ASSERT( mbedtls_des3_set3key_dec( &ctx, key_str->x ) == 0 );
     else
         TEST_ASSERT( 0 );
 
diff --git a/tests/suites/test_suite_gcm.aes128_de.data b/tests/suites/test_suite_gcm.aes128_de.data
index 3df31e5..ede6f24 100644
--- a/tests/suites/test_suite_gcm.aes128_de.data
+++ b/tests/suites/test_suite_gcm.aes128_de.data
@@ -726,6 +726,10 @@
 depends_on:MBEDTLS_AES_C
 gcm_bad_parameters:MBEDTLS_CIPHER_ID_AES:MBEDTLS_GCM_DECRYPT:"d0194b6ee68f0ed8adc4b22ed15dbf14":"":"":"":32:MBEDTLS_ERR_GCM_BAD_INPUT
 
+AES-GCM, output buffer too small, NIST Validation (AES-128,128,1024,0,128) #0
+depends_on:MBEDTLS_AES_C
+gcm_update_output_buffer_too_small:MBEDTLS_CIPHER_ID_AES:MBEDTLS_GCM_DECRYPT:"0dd358bc3f992f26e81e3a2f3aa2d517":"87cc4fd75788c9d5cc83bae5d764dd249d178ab23224049795d4288b5ed9ea3f317068a39a7574b300c8544226e87b08e008fbe241d094545c211d56ac44437d41491a438272738968c8d371aa7787b5f606c8549a9d868d8a71380e9657d3c0337979feb01de5991fc1470dfc59eb02511efbbff3fcb479a862ba3844a25aaa":"d8c750bb443ee1a169dfe97cfe4d855b"
+
 AES-GCM Selftest
 depends_on:MBEDTLS_AES_C
 gcm_selftest:
diff --git a/tests/suites/test_suite_gcm.aes128_en.data b/tests/suites/test_suite_gcm.aes128_en.data
index d60c458..273642c 100644
--- a/tests/suites/test_suite_gcm.aes128_en.data
+++ b/tests/suites/test_suite_gcm.aes128_en.data
@@ -726,6 +726,9 @@
 depends_on:MBEDTLS_AES_C
 gcm_bad_parameters:MBEDTLS_CIPHER_ID_AES:MBEDTLS_GCM_ENCRYPT:"d0194b6ee68f0ed8adc4b22ed15dbf14":"":"":"":32:MBEDTLS_ERR_GCM_BAD_INPUT
 
+AES-GCM, output buffer too small, NIST Validation (AES-128,128,1024,0,128) #0
+gcm_update_output_buffer_too_small:MBEDTLS_CIPHER_ID_AES:MBEDTLS_GCM_ENCRYPT:"ce0f8cfe9d64c4f4c045d11b97c2d918":"dfff250d380f363880963b42d6913c1ba11e8edf7c4ab8b76d79ccbaac628f548ee542f48728a9a2620a0d69339c8291e8d398440d740e310908cdee7c273cc91275ce7271ba12f69237998b07b789b3993aaac8dc4ec1914432a30f5172f79ea0539bd1f70b36d437e5170bc63039a5280816c05e1e41760b58e35696cebd55":"ad4c3627a494fc628316dc03faf81db8"
+
 AES-GCM Selftest
 depends_on:MBEDTLS_AES_C
 gcm_selftest:
diff --git a/tests/suites/test_suite_gcm.function b/tests/suites/test_suite_gcm.function
index c530e6b..5696679 100644
--- a/tests/suites/test_suite_gcm.function
+++ b/tests/suites/test_suite_gcm.function
@@ -431,6 +431,29 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE */
+void gcm_update_output_buffer_too_small( int cipher_id, int mode,
+                                         data_t * key_str, const data_t *input,
+                                         const data_t *iv )
+{
+    mbedtls_gcm_context ctx;
+    uint8_t *output = NULL;
+    size_t olen = 0;
+    size_t output_len = input->len - 1;
+
+    mbedtls_gcm_init( &ctx );
+    TEST_EQUAL( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ), 0 );
+    TEST_EQUAL( 0, mbedtls_gcm_starts( &ctx, mode, iv->x, iv->len ) );
+
+    ASSERT_ALLOC( output, output_len );
+    TEST_EQUAL( MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL, mbedtls_gcm_update( &ctx, input->x, input->len, output, output_len, &olen ) );
+
+exit:
+    mbedtls_free( output );
+    mbedtls_gcm_free( &ctx );
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
 void gcm_selftest(  )
 {
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 063629e..820bed7 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -3348,7 +3348,7 @@
 
 PSA AEAD finish buffer test: AES - GCM, BUF = 8, TAG = 16
 depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
-aead_multipart_finish_buffer_test:PSA_KEY_TYPE_AES:"fbc0b4c56a714c83217b2d1bcadd2ed2e9efb0dcac6cc19f":PSA_ALG_GCM:8:16:"5f4b43e811da9c470d6a9b01":"":"d2ae38c4375954835d75b8e4c2f9bbb4":PSA_ERROR_BUFFER_TOO_SMALL
+aead_multipart_finish_buffer_test:PSA_KEY_TYPE_AES:"fbc0b4c56a714c83217b2d1bcadd2ed2e9efb0dcac6cc19f":PSA_ALG_GCM:8:16:"5f4b43e811da9c470d6a9b01":"":"d2ae38c4375954835d75b8e4c2f9bbb4":PSA_SUCCESS
 
 PSA AEAD finish buffer test: AES - GCM, BUF = 15, TAG = 20
 depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
@@ -4422,19 +4422,19 @@
 
 PSA key derivation: HKDF SHA-256, request maximum capacity
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
-derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:"000102030405060708090a0b0c":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"f0f1f2f3f4f5f6f7f8f9":255 * 32:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865":""
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:"000102030405060708090a0b0c":PSA_KEY_DERIVATION_INPUT_SECRET:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_DERIVATION_INPUT_INFO:"f0f1f2f3f4f5f6f7f8f9":255 * PSA_HASH_LENGTH(PSA_ALG_SHA_256):"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865":""
 
 PSA key derivation: HKDF SHA-1, request maximum capacity
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_1
-derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_1):PSA_KEY_DERIVATION_INPUT_SALT:"":PSA_KEY_DERIVATION_INPUT_SECRET:"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":PSA_KEY_DERIVATION_INPUT_INFO:"":255 * 20:"2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48":""
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_1):PSA_KEY_DERIVATION_INPUT_SALT:"":PSA_KEY_DERIVATION_INPUT_SECRET:"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":PSA_KEY_DERIVATION_INPUT_INFO:"":255 * PSA_HASH_LENGTH(PSA_ALG_SHA_1):"2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48":""
 
 PSA key derivation: HKDF SHA-256, request too much capacity
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
-derive_set_capacity:PSA_ALG_HKDF(PSA_ALG_SHA_256):255 * 32 + 1:PSA_ERROR_INVALID_ARGUMENT
+derive_set_capacity:PSA_ALG_HKDF(PSA_ALG_SHA_256):255 * PSA_HASH_LENGTH(PSA_ALG_SHA_256) + 1:PSA_ERROR_INVALID_ARGUMENT
 
 PSA key derivation: HKDF SHA-1, request too much capacity
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_1
-derive_set_capacity:PSA_ALG_HKDF(PSA_ALG_SHA_1):255 * 20 + 1:PSA_ERROR_INVALID_ARGUMENT
+derive_set_capacity:PSA_ALG_HKDF(PSA_ALG_SHA_1):255 * PSA_HASH_LENGTH(PSA_ALG_SHA_1) + 1:PSA_ERROR_INVALID_ARGUMENT
 
 PSA key derivation: over capacity 42: output 42+1
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
@@ -4454,19 +4454,19 @@
 
 PSA key derivation: HKDF SHA-256, read maximum capacity minus 1
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
-derive_full:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * 32 - 1
+derive_full:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * PSA_HASH_LENGTH(PSA_ALG_SHA_256) - 1
 
 PSA key derivation: HKDF SHA-256, read maximum capacity
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
-derive_full:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * 32
+derive_full:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * PSA_HASH_LENGTH(PSA_ALG_SHA_256)
 
 PSA key derivation: TLS 1.2 PRF SHA-256, read maximum capacity minus 1
 depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF
-derive_full:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * 32 - 1
+derive_full:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * PSA_HASH_LENGTH(PSA_ALG_SHA_256) - 1
 
 PSA key derivation: TLS 1.2 PRF SHA-256, read maximum capacity
 depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF
-derive_full:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * 32
+derive_full:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * PSA_HASH_LENGTH(PSA_ALG_SHA_256)
 
 PSA key derivation: HKDF SHA-256, exercise AES128-CTR
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_AES
@@ -4705,7 +4705,7 @@
 
 PSA generate key: bad type (RSA public key)
 depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY
-generate_key:PSA_KEY_TYPE_RSA_PUBLIC_KEY:512:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_NOT_SUPPORTED:0
+generate_key:PSA_KEY_TYPE_RSA_PUBLIC_KEY:512:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT:0
 
 PSA generate key: raw data, 0 bits: invalid argument
 # The spec allows either INVALID_ARGUMENT or NOT_SUPPORTED
diff --git a/tests/suites/test_suite_psa_crypto_not_supported.function b/tests/suites/test_suite_psa_crypto_not_supported.function
index e3253d8..0665230 100644
--- a/tests/suites/test_suite_psa_crypto_not_supported.function
+++ b/tests/suites/test_suite_psa_crypto_not_supported.function
@@ -50,3 +50,22 @@
     PSA_DONE( );
 }
 /* END_CASE */
+
+/* BEGIN_CASE */
+void generate_invalid_argument( int key_type, int bits )
+{
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    mbedtls_svc_key_id_t key_id = INVALID_KEY_ID;
+
+    PSA_ASSERT( psa_crypto_init( ) );
+    psa_set_key_type( &attributes, key_type );
+    psa_set_key_bits( &attributes, bits );
+    TEST_EQUAL( psa_generate_key( &attributes, &key_id ),
+                PSA_ERROR_INVALID_ARGUMENT );
+    TEST_ASSERT( mbedtls_svc_key_id_equal( key_id, MBEDTLS_SVC_KEY_ID_INIT ) );
+
+exit:
+    psa_destroy_key( key_id );
+    PSA_DONE( );
+}
+/* END_CASE */