Merge branch 'development-restricted'
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f8df140..8833246 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -152,6 +152,8 @@
 
 string(REGEX MATCH "Clang" CMAKE_COMPILER_IS_CLANG "${CMAKE_C_COMPILER_ID}")
 
+include(CheckCCompilerFlag)
+
 if(CMAKE_COMPILER_IS_GNU)
     # some warnings we want are not available with old GCC versions
     # note: starting with CMake 2.8 we could use CMAKE_C_COMPILER_VERSION
@@ -168,7 +170,10 @@
         set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow")
     endif()
     if (GCC_VERSION VERSION_GREATER 5.0)
-        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat-signedness")
+        CHECK_C_COMPILER_FLAG("-Wformat-signedness" C_COMPILER_SUPPORTS_WFORMAT_SIGNEDNESS)
+        if(C_COMPILER_SUPPORTS_WFORMAT_SIGNEDNESS)
+            set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat-signedness")
+        endif()
     endif()
     set(CMAKE_C_FLAGS_RELEASE     "-O2")
     set(CMAKE_C_FLAGS_DEBUG       "-O0 -g3")
diff --git a/ChangeLog.d/crl-revocationDate.txt b/ChangeLog.d/crl-revocationDate.txt
new file mode 100644
index 0000000..a8ad532
--- /dev/null
+++ b/ChangeLog.d/crl-revocationDate.txt
@@ -0,0 +1,11 @@
+Security
+   * When checking X.509 CRLs, a certificate was only considered as revoked if
+     its revocationDate was in the past according to the local clock if
+     available. In particular, on builds without MBEDTLS_HAVE_TIME_DATE,
+     certificates were never considered as revoked. On builds with
+     MBEDTLS_HAVE_TIME_DATE, an attacker able to control the local clock (for
+     example, an untrusted OS attacking a secure enclave) could prevent
+     revocation of certificates via CRLs. Fixed by no longer checking the
+     revocationDate field, in accordance with RFC 5280. Reported by
+     yuemonangong in #3340. Reported independently and fixed by
+     Raoul Strackx and Jethro Beekman in #3433.
diff --git a/ChangeLog.d/e2k-support.txt b/ChangeLog.d/e2k-support.txt
new file mode 100644
index 0000000..023b188
--- /dev/null
+++ b/ChangeLog.d/e2k-support.txt
@@ -0,0 +1,5 @@
+Features
+   * Support building on e2k (Elbrus) architecture: correctly enable
+     -Wformat-signedness, and fix the code that causes signed-one-bit-field
+     and sign-compare warnings. Contributed by makise-homura (Igor Molchanov)
+     <akemi_homura@kurisa.ch>.
diff --git a/ChangeLog.d/md_setup-leak.txt b/ChangeLog.d/md_setup-leak.txt
new file mode 100644
index 0000000..5111d8e
--- /dev/null
+++ b/ChangeLog.d/md_setup-leak.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Fix a memory leak in mbedtls_md_setup() when using HMAC under low memory
+     conditions. Reported and fix suggested by Guido Vranken in #3486.
diff --git a/ChangeLog.d/pw_protected_key_file_ssl_clisrv2.txt b/ChangeLog.d/pw_protected_key_file_ssl_clisrv2.txt
new file mode 100644
index 0000000..ad1ad30
--- /dev/null
+++ b/ChangeLog.d/pw_protected_key_file_ssl_clisrv2.txt
@@ -0,0 +1,8 @@
+Changes
+   * Add the command line parameter key_pwd to the ssl_client2 and ssl_server2
+     example applications which allows to provide a password for the key file
+     specified through the existing key_file argument. This allows the use of
+     these applications with password-protected key files. Analogously but for
+     ssl_server2 only, add the command line parameter key_pwd2 which allows to
+     set a password for the key file provided through the existing key_file2
+     argument.
diff --git a/ChangeLog.d/stdout-macro.txt b/ChangeLog.d/stdout-macro.txt
new file mode 100644
index 0000000..9456240
--- /dev/null
+++ b/ChangeLog.d/stdout-macro.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Fix bug in redirection of unit test outputs on platforms where stdout is
+     defined as a macro. First reported in #2311 and fix contributed in #3528.
diff --git a/undef_assert_before_defining_it.txt b/ChangeLog.d/undef_assert_before_defining_it.txt
similarity index 100%
rename from undef_assert_before_defining_it.txt
rename to ChangeLog.d/undef_assert_before_defining_it.txt
diff --git a/library/md.c b/library/md.c
index 430ba5d..de77b16 100644
--- a/library/md.c
+++ b/library/md.c
@@ -411,6 +411,10 @@
     if( md_info == NULL || ctx == NULL )
         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
 
+    ctx->md_info = md_info;
+    ctx->md_ctx = NULL;
+    ctx->hmac_ctx = NULL;
+
     switch( md_info->type )
     {
 #if defined(MBEDTLS_MD2_C)
@@ -466,8 +470,6 @@
         }
     }
 
-    ctx->md_info = md_info;
-
     return( 0 );
 }
 #undef ALLOC
diff --git a/library/psa_crypto_storage.c b/library/psa_crypto_storage.c
index 3782053..103c9bb 100644
--- a/library/psa_crypto_storage.c
+++ b/library/psa_crypto_storage.c
@@ -174,7 +174,13 @@
 
 exit:
     if( status != PSA_SUCCESS )
-        psa_its_remove( data_identifier );
+    {
+        /* Remove the file in case we managed to create it but something
+         * went wrong. It's ok if the file doesn't exist. If the file exists
+         * but the removal fails, we're already reporting an error so there's
+         * nothing else we can do. */
+        (void) psa_its_remove( data_identifier );
+    }
     return( status );
 }
 
diff --git a/library/psa_its_file.c b/library/psa_its_file.c
index 34a75dc..2fbff20 100644
--- a/library/psa_its_file.c
+++ b/library/psa_its_file.c
@@ -233,7 +233,12 @@
         if( rename_replace_existing( PSA_ITS_STORAGE_TEMP, filename ) != 0 )
             status = PSA_ERROR_STORAGE_FAILURE;
     }
-    remove( PSA_ITS_STORAGE_TEMP );
+    /* The temporary file may still exist, but only in failure cases where
+     * we're already reporting an error. So there's nothing we can do on
+     * failure. If the function succeeded, and in some error cases, the
+     * temporary file doesn't exist and so remove() is expected to fail.
+     * Thus we just ignore the return status of remove(). */
+    (void) remove( PSA_ITS_STORAGE_TEMP );
     return( status );
 }
 
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 8d95789..083b720 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1061,8 +1061,8 @@
                                       ssl->conf->max_minor_ver ) != 0 )
             continue;
 
-        MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x",
-                                    ciphersuites[i] ) );
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %#04x (%s)",
+                                    ciphersuites[i], ciphersuite_info->name ) );
 
 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index 3578265..2ea3580 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -2096,7 +2096,7 @@
             if( ret < 0 )
                 return( ret );
 
-            if ( (size_t)ret > len || ( INT_MAX > SIZE_MAX && ret > SIZE_MAX ) )
+            if ( (size_t)ret > len || ( INT_MAX > SIZE_MAX && ret > (int)SIZE_MAX ) )
             {
                 MBEDTLS_SSL_DEBUG_MSG( 1,
                     ( "f_recv returned %d bytes but only %lu were requested",
@@ -2150,7 +2150,7 @@
         if( ret <= 0 )
             return( ret );
 
-        if( (size_t)ret > ssl->out_left || ( INT_MAX > SIZE_MAX && ret > SIZE_MAX ) )
+        if( (size_t)ret > ssl->out_left || ( INT_MAX > SIZE_MAX && ret > (int)SIZE_MAX ) )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1,
                 ( "f_send returned %d bytes but only %lu bytes were sent",
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 8c1ec6b..2e63fce 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -927,7 +927,8 @@
         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
     }
 
-    MBEDTLS_SSL_DEBUG_MSG( 3, ( "trying ciphersuite: %s", suite_info->name ) );
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "trying ciphersuite: %#04x (%s)",
+                                suite_id, suite_info->name ) );
 
     if( suite_info->min_minor_ver > ssl->minor_ver ||
         suite_info->max_minor_ver < ssl->minor_ver )
diff --git a/library/x509_crt.c b/library/x509_crt.c
index fcc2ed2..71e9cec 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -2322,8 +2322,7 @@
         if( crt->serial.len == cur->serial.len &&
             memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
         {
-            if( mbedtls_x509_time_is_past( &cur->revocation_date ) )
-                return( 1 );
+            return( 1 );
         }
 
         cur = cur->next;
diff --git a/programs/pkey/dh_genprime.c b/programs/pkey/dh_genprime.c
index 796ba4b..a481e32 100644
--- a/programs/pkey/dh_genprime.c
+++ b/programs/pkey/dh_genprime.c
@@ -89,7 +89,7 @@
     {
     usage:
         mbedtls_printf( USAGE );
-        mbedtls_exit( exit_code );
+        goto exit;
     }
 
     for( i = 1; i < argc; i++ )
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 32ca22e..a26dd51 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -101,6 +101,7 @@
 #define DFL_CRT_FILE            ""
 #define DFL_KEY_FILE            ""
 #define DFL_KEY_OPAQUE          0
+#define DFL_KEY_PWD             ""
 #define DFL_PSK                 ""
 #define DFL_PSK_OPAQUE          0
 #define DFL_PSK_IDENTITY        "Client_identity"
@@ -173,7 +174,9 @@
     "                        use \"none\" to skip loading any top-level CAs.\n" \
     "    crt_file=%%s         Your own cert and chain (in bottom to top order, top may be omitted)\n" \
     "                        default: \"\" (pre-loaded)\n" \
-    "    key_file=%%s         default: \"\" (pre-loaded)\n"
+    "    key_file=%%s         default: \"\" (pre-loaded)\n"\
+    "    key_pwd=%%s          Password for key specified by key_file argument\n"\
+    "                        default: none\n"
 #else
 #define USAGE_IO \
     "    No file operations available (MBEDTLS_FS_IO not defined)\n"
@@ -485,6 +488,7 @@
 #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
     int ca_callback;            /* Use callback for trusted certificate list */
 #endif
+    const char *key_pwd;        /* the password for the client key          */
     const char *psk;            /* the pre-shared key                       */
     const char *psk_identity;   /* the pre-shared key identity              */
     const char *ecjpake_pw;     /* the EC J-PAKE password                   */
@@ -1249,6 +1253,7 @@
     opt.crt_file            = DFL_CRT_FILE;
     opt.key_file            = DFL_KEY_FILE;
     opt.key_opaque          = DFL_KEY_OPAQUE;
+    opt.key_pwd             = DFL_KEY_PWD;
     opt.psk                 = DFL_PSK;
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     opt.psk_opaque          = DFL_PSK_OPAQUE;
@@ -1368,6 +1373,8 @@
             opt.crt_file = q;
         else if( strcmp( p, "key_file" ) == 0 )
             opt.key_file = q;
+        else if( strcmp( p, "key_pwd" ) == 0 )
+            opt.key_pwd = q;
 #if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_X509_CRT_PARSE_C)
         else if( strcmp( p, "key_opaque" ) == 0 )
             opt.key_opaque = atoi( q );
@@ -2077,7 +2084,7 @@
     else
 #if defined(MBEDTLS_FS_IO)
     if( strlen( opt.key_file ) )
-        ret = mbedtls_pk_parse_keyfile( &pkey, opt.key_file, "" );
+        ret = mbedtls_pk_parse_keyfile( &pkey, opt.key_file, opt.key_pwd );
     else
 #endif
 #if defined(MBEDTLS_CERTS_C)
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 2637a6c..c445ddb 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -122,8 +122,10 @@
 #define DFL_CA_PATH             ""
 #define DFL_CRT_FILE            ""
 #define DFL_KEY_FILE            ""
+#define DFL_KEY_PWD             ""
 #define DFL_CRT_FILE2           ""
 #define DFL_KEY_FILE2           ""
+#define DFL_KEY_PWD2            ""
 #define DFL_ASYNC_OPERATIONS    "-"
 #define DFL_ASYNC_PRIVATE_DELAY1 ( -1 )
 #define DFL_ASYNC_PRIVATE_DELAY2 ( -1 )
@@ -216,11 +218,15 @@
     "    crt_file=%%s         Your own cert and chain (in bottom to top order, top may be omitted)\n" \
     "                        default: see note after key_file2\n" \
     "    key_file=%%s         default: see note after key_file2\n" \
+    "    key_pwd=%%s          Password for key specified by key_file argument\n"\
+    "                        default: none\n" \
     "    crt_file2=%%s        Your second cert and chain (in bottom to top order, top may be omitted)\n" \
     "                        default: see note after key_file2\n" \
     "    key_file2=%%s        default: see note below\n" \
     "                        note: if neither crt_file/key_file nor crt_file2/key_file2 are used,\n" \
     "                              preloaded certificate(s) and key(s) are used if available\n" \
+    "    key_pwd2=%%s         Password for key specified by key_file2 argument\n"\
+    "                        default: none\n" \
     "    dhm_file=%%s        File containing Diffie-Hellman parameters\n" \
     "                       default: preloaded parameters\n"
 #else
@@ -493,8 +499,6 @@
     "    cert_req_ca_list=%%d default: 1 (send ca list)\n"  \
     "                        options: 1 (send ca list), 0 (don't send)\n" \
     USAGE_IO                                                \
-    USAGE_SSL_ASYNC                                         \
-    USAGE_SNI                                               \
     "\n"                                                    \
     USAGE_PSK                                               \
     USAGE_CA_CALLBACK                                       \
@@ -519,6 +523,8 @@
     USAGE_CURVES                                            \
     "\n"
 #define USAGE4 \
+    USAGE_SSL_ASYNC                                         \
+    USAGE_SNI                                               \
     "    arc4=%%d             default: (library default: 0)\n" \
     "    allow_sha1=%%d       default: 0\n"                             \
     "    min_version=%%s      default: (library default: tls1)\n"       \
@@ -570,8 +576,10 @@
     const char *ca_path;        /* the path with the CA certificate(s) reside */
     const char *crt_file;       /* the file with the server certificate     */
     const char *key_file;       /* the file with the server key             */
+    const char *key_pwd;        /* the password for the server key          */
     const char *crt_file2;      /* the file with the 2nd server certificate */
     const char *key_file2;      /* the file with the 2nd server key         */
+    const char *key_pwd2;       /* the password for the 2nd server key      */
     const char *async_operations; /* supported SSL asynchronous operations  */
     int async_private_delay1;   /* number of times f_async_resume needs to be called for key 1, or -1 for no async */
     int async_private_delay2;   /* number of times f_async_resume needs to be called for key 2, or -1 for no async */
@@ -1905,8 +1913,10 @@
     opt.ca_path             = DFL_CA_PATH;
     opt.crt_file            = DFL_CRT_FILE;
     opt.key_file            = DFL_KEY_FILE;
+    opt.key_pwd             = DFL_KEY_PWD;
     opt.crt_file2           = DFL_CRT_FILE2;
     opt.key_file2           = DFL_KEY_FILE2;
+    opt.key_pwd2            = DFL_KEY_PWD2;
     opt.async_operations    = DFL_ASYNC_OPERATIONS;
     opt.async_private_delay1 = DFL_ASYNC_PRIVATE_DELAY1;
     opt.async_private_delay2 = DFL_ASYNC_PRIVATE_DELAY2;
@@ -2026,10 +2036,14 @@
             opt.crt_file = q;
         else if( strcmp( p, "key_file" ) == 0 )
             opt.key_file = q;
+        else if( strcmp( p, "key_pwd" ) == 0 )
+            opt.key_pwd = q;
         else if( strcmp( p, "crt_file2" ) == 0 )
             opt.crt_file2 = q;
         else if( strcmp( p, "key_file2" ) == 0 )
             opt.key_file2 = q;
+        else if( strcmp( p, "key_pwd2" ) == 0 )
+            opt.key_pwd2 = q;
         else if( strcmp( p, "dhm_file" ) == 0 )
             opt.dhm_file = q;
 #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
@@ -2815,7 +2829,8 @@
     if( strlen( opt.key_file ) && strcmp( opt.key_file, "none" ) != 0 )
     {
         key_cert_init++;
-        if( ( ret = mbedtls_pk_parse_keyfile( &pkey, opt.key_file, "" ) ) != 0 )
+        if( ( ret = mbedtls_pk_parse_keyfile( &pkey, opt.key_file,
+                                              opt.key_pwd ) ) != 0 )
         {
             mbedtls_printf( " failed\n  !  mbedtls_pk_parse_keyfile returned -0x%x\n\n", (unsigned int) -ret );
             goto exit;
@@ -2840,7 +2855,8 @@
     if( strlen( opt.key_file2 ) && strcmp( opt.key_file2, "none" ) != 0 )
     {
         key_cert_init2++;
-        if( ( ret = mbedtls_pk_parse_keyfile( &pkey2, opt.key_file2, "" ) ) != 0 )
+        if( ( ret = mbedtls_pk_parse_keyfile( &pkey2, opt.key_file2,
+                                              opt.key_pwd2 ) ) != 0 )
         {
             mbedtls_printf( " failed\n  !  mbedtls_pk_parse_keyfile(2) returned -0x%x\n\n",
                             (unsigned int) -ret );
diff --git a/tests/compat.sh b/tests/compat.sh
index 9f2798e..68b9f74 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -907,7 +907,7 @@
     M_SERVER_ARGS="server_port=$PORT server_addr=0.0.0.0 force_version=$MODE arc4=1"
     O_SERVER_ARGS="-accept $PORT -cipher NULL,ALL -$MODE -dhparam data_files/dhparams.pem"
     G_SERVER_ARGS="-p $PORT --http $G_MODE"
-    G_SERVER_PRIO="NORMAL:${G_PRIO_CCM}+ARCFOUR-128:+NULL:+MD5:+PSK:+DHE-PSK:+ECDHE-PSK:+RSA-PSK:-VERS-TLS-ALL:$G_PRIO_MODE"
+    G_SERVER_PRIO="NORMAL:${G_PRIO_CCM}+ARCFOUR-128:+NULL:+MD5:+PSK:+DHE-PSK:+ECDHE-PSK:+SHA256:+SHA384:+RSA-PSK:-VERS-TLS-ALL:$G_PRIO_MODE"
 
     # with OpenSSL 1.0.1h, -www, -WWW and -HTTP break DTLS handshakes
     if is_dtls "$MODE"; then
@@ -956,39 +956,29 @@
             ;;
 
         "RSA")
-            M_SERVER_ARGS="$M_SERVER_ARGS crt_file=data_files/server2.crt key_file=data_files/server2.key"
-            O_SERVER_ARGS="$O_SERVER_ARGS -cert data_files/server2.crt -key data_files/server2.key"
-            G_SERVER_ARGS="$G_SERVER_ARGS --x509certfile data_files/server2.crt --x509keyfile data_files/server2.key"
+            M_SERVER_ARGS="$M_SERVER_ARGS crt_file=data_files/server2-sha256.crt key_file=data_files/server2.key"
+            O_SERVER_ARGS="$O_SERVER_ARGS -cert data_files/server2-sha256.crt -key data_files/server2.key"
+            G_SERVER_ARGS="$G_SERVER_ARGS --x509certfile data_files/server2-sha256.crt --x509keyfile data_files/server2.key"
 
             if [ "X$VERIFY" = "XYES" ]; then
-                M_CLIENT_ARGS="$M_CLIENT_ARGS crt_file=data_files/server1.crt key_file=data_files/server1.key"
-                O_CLIENT_ARGS="$O_CLIENT_ARGS -cert data_files/server1.crt -key data_files/server1.key"
-                G_CLIENT_ARGS="$G_CLIENT_ARGS --x509certfile data_files/server1.crt --x509keyfile data_files/server1.key"
+                M_CLIENT_ARGS="$M_CLIENT_ARGS crt_file=data_files/cert_sha256.crt key_file=data_files/server1.key"
+                O_CLIENT_ARGS="$O_CLIENT_ARGS -cert data_files/cert_sha256.crt -key data_files/server1.key"
+                G_CLIENT_ARGS="$G_CLIENT_ARGS --x509certfile data_files/cert_sha256.crt --x509keyfile data_files/server1.key"
             else
                 M_CLIENT_ARGS="$M_CLIENT_ARGS crt_file=none key_file=none"
             fi
-
-            # Allow SHA-1. It's disabled by default for security reasons but
-            # our tests still use certificates signed with it.
-            M_SERVER_ARGS="$M_SERVER_ARGS allow_sha1=1"
-            M_CLIENT_ARGS="$M_CLIENT_ARGS allow_sha1=1"
             ;;
 
         "PSK")
             # give RSA-PSK-capable server a RSA cert
             # (should be a separate type, but harder to close with openssl)
-            M_SERVER_ARGS="$M_SERVER_ARGS psk=6162636465666768696a6b6c6d6e6f70 ca_file=none crt_file=data_files/server2.crt key_file=data_files/server2.key"
+            M_SERVER_ARGS="$M_SERVER_ARGS psk=6162636465666768696a6b6c6d6e6f70 ca_file=none crt_file=data_files/server2-sha256.crt key_file=data_files/server2.key"
             O_SERVER_ARGS="$O_SERVER_ARGS -psk 6162636465666768696a6b6c6d6e6f70 -nocert"
-            G_SERVER_ARGS="$G_SERVER_ARGS --x509certfile data_files/server2.crt --x509keyfile data_files/server2.key --pskpasswd data_files/passwd.psk"
+            G_SERVER_ARGS="$G_SERVER_ARGS --x509certfile data_files/server2-sha256.crt --x509keyfile data_files/server2.key --pskpasswd data_files/passwd.psk"
 
             M_CLIENT_ARGS="$M_CLIENT_ARGS psk=6162636465666768696a6b6c6d6e6f70 crt_file=none key_file=none"
             O_CLIENT_ARGS="$O_CLIENT_ARGS -psk 6162636465666768696a6b6c6d6e6f70"
             G_CLIENT_ARGS="$G_CLIENT_ARGS --pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70"
-
-            # Allow SHA-1. It's disabled by default for security reasons but
-            # our tests still use certificates signed with it.
-            M_SERVER_ARGS="$M_SERVER_ARGS allow_sha1=1"
-            M_CLIENT_ARGS="$M_CLIENT_ARGS allow_sha1=1"
             ;;
     esac
 }
diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile
index 40c22f5..88f265c 100644
--- a/tests/data_files/Makefile
+++ b/tests/data_files/Makefile
@@ -244,6 +244,8 @@
 	$(OPENSSL) pkey -in $< -out $@ -inform PEM -outform DER
 all_final += cli2.key.der
 
+server5_pwd_ec = PolarSSLTest
+
 server5.crt.der: server5.crt
 	$(OPENSSL) x509 -in $< -out $@ -inform PEM -outform DER
 all_final += server5.crt.der
@@ -252,6 +254,10 @@
 	$(OPENSSL) pkey -in $< -out $@ -inform PEM -outform DER
 all_final += server5.key.der
 
+server5.key.enc: server5.key
+	$(OPENSSL) ec -aes256 -in $< -out $@ -passout "pass:$(server5_pwd_ec)"
+all_final += server5.key.enc
+
 server5-ss-expired.crt: server5.key
 	$(FAKETIME) -f -3653d $(OPENSSL) req -x509 -new -subj "/C=UK/O=mbed TLS/OU=testsuite/CN=localhost" -days 3653 -sha256 -key $< -out $@
 all_final += server5-ss-expired.crt
@@ -927,6 +933,8 @@
 
 # server2*
 
+server2_pwd_ec = PolarSSLTest
+
 server2.req.sha256: server2.key
 	$(MBEDTLS_CERT_REQ) output_file=$@ filename=$< subject_name="C=NL,O=PolarSSL,CN=localhost" md=SHA256
 all_intermediate += server2.req.sha256
@@ -943,6 +951,10 @@
 	$(OPENSSL) pkey -in $< -out $@ -inform PEM -outform DER
 all_final += server2.key.der
 
+server2.key.enc: server2.key
+	$(OPENSSL) rsa -aes256 -in $< -out $@ -passout "pass:$(server2_pwd_ec)"
+all_final += server2.key.enc
+
 # server5*
 
 # The use of 'Server 1' in the DN is intentional here, as the DN is hardcoded in the x509_write test suite.'
@@ -1058,7 +1070,10 @@
 crl.pem: $(test_ca_crt) $(test_ca_key_file_rsa) $(test_ca_config_file)
 	$(OPENSSL) ca -gencrl -batch -cert $(test_ca_crt) -keyfile $(test_ca_key_file_rsa) -key $(test_ca_pwd_rsa) -config $(test_ca_server1_config_file) -md sha1 -crldays 3653 -out $@
 
-server1_all: crl.pem server1.crt server1.noauthid.crt server1.crt.openssl server1.v1.crt server1.v1.crt.openssl server1.key_usage.crt server1.key_usage_noauthid.crt server1.key_usage.crt.openssl server1.cert_type.crt server1.cert_type_noauthid.crt server1.cert_type.crt.openssl server1.der server1.der.openssl server1.v1.der server1.v1.der.openssl server1.key_usage.der server1.key_usage.der.openssl server1.cert_type.der server1.cert_type.der.openssl
+crl-futureRevocationDate.pem: $(test_ca_crt) $(test_ca_key_file_rsa) $(test_ca_config_file) test-ca.server1.future-crl.db  test-ca.server1.future-crl.opensslconf
+	$(FAKETIME) '2028-12-31' $(OPENSSL) ca -gencrl -config test-ca.server1.future-crl.opensslconf -crldays 365 -passin "pass:$(test_ca_pwd_rsa)" -out $@
+
+server1_all: crl.pem crl-futureRevocationDate.pem server1.crt server1.noauthid.crt server1.crt.openssl server1.v1.crt server1.v1.crt.openssl server1.key_usage.crt server1.key_usage_noauthid.crt server1.key_usage.crt.openssl server1.cert_type.crt server1.cert_type_noauthid.crt server1.cert_type.crt.openssl server1.der server1.der.openssl server1.v1.der server1.v1.der.openssl server1.key_usage.der server1.key_usage.der.openssl server1.cert_type.der server1.cert_type.der.openssl
 
 # server2*
 
diff --git a/tests/data_files/Readme-x509.txt b/tests/data_files/Readme-x509.txt
index 6f54ed0..d07241a 100644
--- a/tests/data_files/Readme-x509.txt
+++ b/tests/data_files/Readme-x509.txt
@@ -111,7 +111,7 @@
 - crl-ec-sha*.pem: (2) server6.crt
 - crl-future.pem: (2) server6.crt + unknown
 - crl-rsa-pss-*.pem: (1) server9{,badsign,with-ca}.crt + cert_sha384.crt + unknown
-- crl.pem, crl_expired.pem: (1) server1{,.cert_type,.key_usage,.v1}.crt + unknown
+- crl.pem, crl-futureRevocationDate.pem, crl_expired.pem: (1) server1{,.cert_type,.key_usage,.v1}.crt + unknown
 - crl_md*.pem: crl_sha*.pem: (1) same as crl.pem
 - crt_cat_*.pem: (1+2) concatenations in various orders:
     ec = crl-ec-sha256.pem, ecfut = crl-future.pem
diff --git a/tests/data_files/crl-futureRevocationDate.pem b/tests/data_files/crl-futureRevocationDate.pem
new file mode 100644
index 0000000..f147a8f
--- /dev/null
+++ b/tests/data_files/crl-futureRevocationDate.pem
@@ -0,0 +1,11 @@
+-----BEGIN X509 CRL-----
+MIIBqzCBlDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDERMA8GA1UECgwI
+UG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EXDTI4MTIzMDIzMDAw
+MFoXDTI5MTIzMDIzMDAwMFowKDASAgEBFw0yOTAxMDExMjQ0MDdaMBICAQMXDTI5
+MDEwMTEyNDQwN1owDQYJKoZIhvcNAQEFBQADggEBAKbL1mDpzCbLJmRZKM2KHPvK
+ijS4UMnanzzYpLAwom1NI69v2fE1/EfiXv0empE6mFqnLwOG4ZP8fECfxjMXO2Ee
+VhxYiRjly6q9hfIUk1e+N9ct8unNnLEBvf6Syfy9+FSO3Q/ahljpYlXsXxg62WXl
+9xp5b5Ok+/0sCv0eL5uFQKXQa8hS9dZo6py7jvFDQC+wVau1mXjQW85iXMLm7vik
+4lR+kfZloeq1jIbsx8cdMi32YVt7uccaqoFcjtrdrWfGmi0wvlDc8K5J0l4tIxZY
+9P+T4fzSgQLdqGZ3xADheEaGTRVL/5oe5L4zRH32BZONMFCijv+j1SpWLxHE8cM=
+-----END X509 CRL-----
diff --git a/tests/data_files/server2.key.enc b/tests/data_files/server2.key.enc
new file mode 100644
index 0000000..773aaad
--- /dev/null
+++ b/tests/data_files/server2.key.enc
@@ -0,0 +1,30 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-256-CBC,3DDADF5AEA525DD282D9D5E0B978AEE2
+
+thP0fyNhHEWvVWHpBSGAA4C6wlqWwuCbYTGVs6GW07YNiyvInE/XxtKCrEJ6ORpR
+tPZ0sTtmRFQgiAW4nSjol6AhnMAYCkt+bl2opihuKHr2IBKpGIytCwYwDB/soMw5
+/vYuZU3osENnWcv+R1+0PohU6eqo1bVBrk+Mrm+ZSX886uDNxAaqAW9dtsC7fZYV
+w/uCOlk78rtrJUOTKfh3VEXG1fb/rYAP7bZYwzkmJZRozFPzjhnZZSOssz4xwCwY
+04oHHrMDFCpbBmlZRLg60c5u0nduQx3SKig9o6gHCDoOYT0Bq64lvZLiPcwN7axV
+L7+7TJ9u/kALO0CqAltiuz18msaErXIE3pHEGDt5zxgUcLxT4IhhixWfOL09nqjl
+IltEBn0JAVC3qYsEzFGnr3C2NXLTYIFU8m1qtIyEc8vuhKw7HCgp3W/xw9f2jKZF
+JivFX80URuBTs2/TWuGBKTmIGLQFWYPKwhyl9HNbbI8q5XdxKNiVxDnZfPU/icef
+nJ+nM7msrkvXj4SdHO/if+rxQ07T/MHfU8PeqUL2LQAxY4gfBvkKJ/UAjfsHv0B2
+1WcZAt0yqrJu/ydOkQpwmQ/XCh/dITNYnxXZ0bjtY5fG+QGxA3RvqyfKbQFTi8qg
+Nx8cxOUD1dZwZ6KrosdSFGkNkZwgIWAbIK4O3TLN5lD42031kx4iiKlxdjw6Q2df
+MEVL6FqYXf4n5MhGQ5mu5MkEO9IDaz/iBdm2jkkjWaxozNC51r/i+STtsVQnY2f2
+pubekEnCOoqXN6BjuVLN28XSTLLTlJ5i9tdIMlIFUKfiNpJjOTjYBopZEf5hm3h4
+ollq6QhW9DIIsVuYgSpvoyLYLl57kvYgk1oGhV0KZyh7IPzRXTjEBiMTO+MZEoH0
+f3x2RU3LvMagb36zWs6CShV/TwAE08Mwbi7UDWYRHHaeO2bcKoEDGOXiOfsXE9HW
+OVmAlIheR/W1eVAcszHcSVtXOjlsJ02CeVEcATnJCk6Ug0vc0TspCnwOCvM8+RmE
+jQ0E6GeT6R/DVHW9XBNFxFxiS6ySd3yo9rKVLdGGPHns+qmlSMTAfYROoR1V8UiQ
+0Tvd1CfVVBeYCm9UrWUXvGzoC3rstbD7SinGbdSU4wATIPeb+v1Tz/vVhr8AoRLJ
+JK3jHMKCHH59Wx+tk8JdqAm8fgUK/69A5+gitZlM6sAmnfBJ6Vm8hqACLpjPXDWy
+LjNDwWGqgWgqDOubY+ZJQwjUGQdPdGbEUF0ABZ6si9wW+RVVGSPAfiFqE4b/QwA/
+RZh1nm7dc/3elXxwXP60MyEsVddAP691xlDdL9mRpbDMx/JSp/hABFmdPOEtu5EB
+02DS37+pOdI1kWkFiI4kkccZL04CTWLWh2lxb0RqUqQMeOf6j/WSTJ2In5etbHSB
+R8IQOsfRINm3fD11SXXKUM7IzMi9VBD7TblN2HR9iXbW7twa8O0MRH805eY+vjsM
+kcYoOtWSh+OFP9txcwjiXUBmVQDPtb+myGXmchSpMIFNV2tHVvVmUFBSipyAKr98
+3YI7mvWO0AVWXAqRHYmM3DLjlEXCauXCjgVicC/EUdA5CAO95X/ZQTNwBk8kYjy+
+-----END RSA PRIVATE KEY-----
diff --git a/tests/data_files/server5.key.enc b/tests/data_files/server5.key.enc
new file mode 100644
index 0000000..8e622c0
--- /dev/null
+++ b/tests/data_files/server5.key.enc
@@ -0,0 +1,8 @@
+-----BEGIN EC PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-256-CBC,69FEA263918128D4DD673B2732E2D7EC
+
++Q4P1nVcfGoittxagWHvyBLVPbhjmTA/SZ6W5TB+5scOzgfRlcse4jIII899EQxx
+HrfhgQwzQ12TgTZ2Y8neI+RsUqFLTLinvd8c/luBKLeDECjjhyBXOJic2dRPUaLQ
+Nyg3bI0Srr6aq6nETjh8i+dSzE/wjyNzXBMdN3KhOjE=
+-----END EC PRIVATE KEY-----
diff --git a/tests/data_files/test-ca.server1.future-crl.db b/tests/data_files/test-ca.server1.future-crl.db
new file mode 100644
index 0000000..763aa12
--- /dev/null
+++ b/tests/data_files/test-ca.server1.future-crl.db
@@ -0,0 +1,2 @@
+R	210212144406Z	290101124407Z	01	unknown	/C=NL/O=PolarSSL/CN=PolarSSL Server 1
+R	210212144400Z	290101124407Z	03	unknown	/C=NL/O=PolarSSL/CN=PolarSSL Test CA
diff --git a/tests/data_files/test-ca.server1.future-crl.opensslconf b/tests/data_files/test-ca.server1.future-crl.opensslconf
new file mode 100644
index 0000000..e9ce754
--- /dev/null
+++ b/tests/data_files/test-ca.server1.future-crl.opensslconf
@@ -0,0 +1,18 @@
+ [ ca ]
+ default_ca             = test-ca
+
+ [ test-ca ]
+ certificate            = test-ca.crt
+ private_key            = test-ca.key
+ serial                 = test-ca.server1.serial
+ default_md             = sha1
+ default_startdate      = 110212144406Z
+ default_enddate        = 210212144406Z
+ new_certs_dir          = ./
+ database               = ./test-ca.server1.future-crl.db
+ policy                 = policy_match
+
+ [policy_match]
+ countryName            = supplied
+ organizationName       = supplied
+ commonName             = supplied
diff --git a/tests/include/test/macros.h b/tests/include/test/macros.h
index 7177156..f404780 100644
--- a/tests/include/test/macros.h
+++ b/tests/include/test/macros.h
@@ -73,7 +73,7 @@
 /* A compile-time constant with the value 0. If `const_expr` is not a
  * compile-time constant with a nonzero value, cause a compile-time error. */
 #define STATIC_ASSERT_EXPR( const_expr )                                \
-    ( 0 && sizeof( struct { int STATIC_ASSERT : 1 - 2 * ! ( const_expr ); } ) )
+    ( 0 && sizeof( struct { unsigned int STATIC_ASSERT : 1 - 2 * ! ( const_expr ); } ) )
 /* Return the scalar value `value` (possibly promoted). This is a compile-time
  * constant if `value` is. `condition` must be a compile-time constant.
  * If `condition` is false, arrange to cause a compile-time error. */
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 0356923..ca73722 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1538,6 +1538,16 @@
     make test
 }
 
+component_test_no_date_time () {
+    msg "build: default config without MBEDTLS_HAVE_TIME_DATE"
+    scripts/config.py unset MBEDTLS_HAVE_TIME_DATE
+    CC=gcc cmake
+    make
+
+    msg "test: !MBEDTLS_HAVE_TIME_DATE - main suites"
+    make test
+}
+
 component_test_platform_calloc_macro () {
     msg "build: MBEDTLS_PLATFORM_{CALLOC/FREE}_MACRO enabled (ASan build)"
     scripts/config.py set MBEDTLS_PLATFORM_MEMORY
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 46dc83e..653d88d 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -1129,6 +1129,39 @@
             -s "Protocol is DTLSv1.2" \
             -s "Ciphersuite is TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256"
 
+run_test    "TLS client auth: required" \
+            "$P_SRV auth_mode=required" \
+            "$P_CLI" \
+            0 \
+            -s "Verifying peer X.509 certificate... ok"
+
+requires_config_enabled MBEDTLS_X509_CRT_PARSE_C
+requires_config_enabled MBEDTLS_ECDSA_C
+requires_config_enabled MBEDTLS_SHA256_C
+run_test    "TLS: password protected client key" \
+            "$P_SRV auth_mode=required" \
+            "$P_CLI crt_file=data_files/server5.crt key_file=data_files/server5.key.enc key_pwd=PolarSSLTest" \
+            0
+
+requires_config_enabled MBEDTLS_X509_CRT_PARSE_C
+requires_config_enabled MBEDTLS_ECDSA_C
+requires_config_enabled MBEDTLS_SHA256_C
+run_test    "TLS: password protected server key" \
+            "$P_SRV crt_file=data_files/server5.crt key_file=data_files/server5.key.enc key_pwd=PolarSSLTest" \
+            "$P_CLI" \
+            0
+
+requires_config_enabled MBEDTLS_X509_CRT_PARSE_C
+requires_config_enabled MBEDTLS_ECDSA_C
+requires_config_enabled MBEDTLS_RSA_C
+requires_config_enabled MBEDTLS_SHA256_C
+run_test    "TLS: password protected server key, two certificates" \
+            "$P_SRV \
+              key_file=data_files/server5.key.enc key_pwd=PolarSSLTest crt_file=data_files/server5.crt \
+              key_file2=data_files/server2.key.enc key_pwd2=PolarSSLTest crt_file2=data_files/server2.crt" \
+            "$P_CLI" \
+            0
+
 requires_config_enabled MBEDTLS_ZLIB_SUPPORT
 run_test    "Default (compression enabled)" \
             "$P_SRV debug_level=3" \
@@ -5748,12 +5781,12 @@
 
 # Tests for EC J-PAKE
 
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
 run_test    "ECJPAKE: client not configured" \
             "$P_SRV debug_level=3" \
             "$P_CLI debug_level=3" \
             0 \
-            -C "add ciphersuite: c0ff" \
+            -C "add ciphersuite: 0xc0ff" \
             -C "adding ecjpake_kkpp extension" \
             -S "found ecjpake kkpp extension" \
             -S "skip ecjpake kkpp extension" \
@@ -5762,13 +5795,13 @@
             -C "found ecjpake_kkpp extension" \
             -S "None of the common ciphersuites is usable"
 
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
 run_test    "ECJPAKE: server not configured" \
             "$P_SRV debug_level=3" \
             "$P_CLI debug_level=3 ecjpake_pw=bla \
              force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \
             1 \
-            -c "add ciphersuite: c0ff" \
+            -c "add ciphersuite: 0xc0ff" \
             -c "adding ecjpake_kkpp extension" \
             -s "found ecjpake kkpp extension" \
             -s "skip ecjpake kkpp extension" \
@@ -5777,13 +5810,13 @@
             -C "found ecjpake_kkpp extension" \
             -s "None of the common ciphersuites is usable"
 
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
 run_test    "ECJPAKE: working, TLS" \
             "$P_SRV debug_level=3 ecjpake_pw=bla" \
             "$P_CLI debug_level=3 ecjpake_pw=bla \
              force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \
             0 \
-            -c "add ciphersuite: c0ff" \
+            -c "add ciphersuite: 0xc0ff" \
             -c "adding ecjpake_kkpp extension" \
             -C "re-using cached ecjpake parameters" \
             -s "found ecjpake kkpp extension" \
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index a5285a3..7425a35 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -446,44 +446,51 @@
 #endif
 
 #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
-static int redirect_output( FILE** out_stream, const char* path )
+static int redirect_output( FILE* out_stream, const char* path )
 {
-    int stdout_fd = dup( fileno( *out_stream ) );
+    int out_fd, dup_fd;
+    FILE* path_stream;
 
-    if( stdout_fd == -1 )
+    out_fd = fileno( out_stream );
+    dup_fd = dup( out_fd );
+
+    if( dup_fd == -1 )
     {
-        return -1;
+        return( -1 );
     }
 
-    fflush( *out_stream );
-    fclose( *out_stream );
-    *out_stream = fopen( path, "w" );
-
-    if( *out_stream == NULL )
+    path_stream = fopen( path, "w" );
+    if( path_stream == NULL )
     {
-        close( stdout_fd );
-        return -1;
+        close( dup_fd );
+        return( -1 );
     }
 
-    return stdout_fd;
+    fflush( out_stream );
+    if( dup2( fileno( path_stream ), out_fd ) == -1 )
+    {
+        close( dup_fd );
+        fclose( path_stream );
+        return( -1 );
+    }
+
+    fclose( path_stream );
+    return( dup_fd );
 }
 
-static int restore_output( FILE** out_stream, int old_fd )
+static int restore_output( FILE* out_stream, int dup_fd )
 {
-    fflush( *out_stream );
-    fclose( *out_stream );
+    int out_fd = fileno( out_stream );
 
-    *out_stream = fdopen( old_fd, "w" );
-    if( *out_stream == NULL )
+    fflush( out_stream );
+    if( dup2( dup_fd, out_fd ) == -1 )
     {
-        return -1;
+        close( out_fd );
+        close( dup_fd );
+        return( -1 );
     }
 
-    return 0;
-}
-
-static void close_output( FILE* out_stream )
-{
-    fclose( out_stream );
+    close( dup_fd );
+    return( 0 );
 }
 #endif /* __unix__ || __APPLE__ __MACH__ */
diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function
index a459eed..cce2899 100644
--- a/tests/suites/host_test.function
+++ b/tests/suites/host_test.function
@@ -692,7 +692,7 @@
                  */
                 if( !option_verbose )
                 {
-                    stdout_fd = redirect_output( &stdout, "/dev/null" );
+                    stdout_fd = redirect_output( stdout, "/dev/null" );
                     if( stdout_fd == -1 )
                     {
                         /* Redirection has failed with no stdout so exit */
@@ -712,7 +712,7 @@
                 }
 
 #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
-                if( !option_verbose && restore_output( &stdout, stdout_fd ) )
+                if( !option_verbose && restore_output( stdout, stdout_fd ) )
                 {
                         /* Redirection has failed with no stdout so exit */
                         exit( 1 );
@@ -817,10 +817,5 @@
     mbedtls_memory_buffer_alloc_free();
 #endif
 
-#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
-    if( stdout_fd != -1 )
-        close_output( stdout );
-#endif /* __unix__ || __APPLE__ __MACH__ */
-
     return( total_errors != 0 );
 }
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index d982f81..cd26017 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -799,6 +799,10 @@
 PSA hash compute: bad algorithm (not a hash)
 hash_compute_fail:PSA_ALG_HMAC(PSA_ALG_SHA_256):"":32:PSA_ERROR_INVALID_ARGUMENT
 
+PSA hash compute: output buffer empty
+depends_on:MBEDTLS_SHA256_C
+hash_compute_fail:PSA_ALG_SHA_256:"":0:PSA_ERROR_BUFFER_TOO_SMALL
+
 PSA hash compute: output buffer too small
 depends_on:MBEDTLS_SHA256_C
 hash_compute_fail:PSA_ALG_SHA_256:"":31:PSA_ERROR_BUFFER_TOO_SMALL
@@ -828,6 +832,10 @@
 depends_on:MBEDTLS_SHA256_C
 hash_compare_fail:PSA_ALG_SHA_256:"":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8":PSA_ERROR_INVALID_SIGNATURE
 
+PSA hash compare: empty hash
+depends_on:MBEDTLS_SHA256_C
+hash_compare_fail:PSA_ALG_SHA_256:"":"":PSA_ERROR_INVALID_SIGNATURE
+
 PSA hash compare: good
 depends_on:MBEDTLS_SHA256_C
 hash_compare_fail:PSA_ALG_SHA_256:"":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855":PSA_SUCCESS
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index f4b9a8f..665580b 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -3028,17 +3028,21 @@
     psa_algorithm_t alg = alg_arg;
     psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    /* Leave a little extra room in the output buffer. At the end of the
-     * test, we'll check that the implementation didn't overwrite onto
-     * this extra room. */
-    uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
+    uint8_t *actual_mac = NULL;
     size_t mac_buffer_size =
         PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
     size_t mac_length = 0;
+    const size_t output_sizes_to_test[] = {
+        0,
+        1,
+        expected_mac->len - 1,
+        expected_mac->len,
+        expected_mac->len + 1,
+    };
 
-    memset( actual_mac, '+', sizeof( actual_mac ) );
     TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
-    TEST_ASSERT( expected_mac->len <= mac_buffer_size );
+    /* We expect PSA_MAC_FINAL_SIZE to be exact. */
+    TEST_ASSERT( expected_mac->len == mac_buffer_size );
 
     PSA_ASSERT( psa_crypto_init( ) );
 
@@ -3048,26 +3052,41 @@
 
     PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
 
-    /* Calculate the MAC. */
-    PSA_ASSERT( psa_mac_sign_setup( &operation,
-                                    handle, alg ) );
-    PSA_ASSERT( psa_mac_update( &operation,
-                                input->x, input->len ) );
-    PSA_ASSERT( psa_mac_sign_finish( &operation,
-                                     actual_mac, mac_buffer_size,
-                                     &mac_length ) );
+    for( size_t i = 0; i < ARRAY_LENGTH( output_sizes_to_test ); i++ )
+    {
+        const size_t output_size = output_sizes_to_test[i];
+        psa_status_t expected_status =
+            ( output_size >= expected_mac->len ? PSA_SUCCESS :
+              PSA_ERROR_BUFFER_TOO_SMALL );
 
-    /* Compare with the expected value. */
-    ASSERT_COMPARE( expected_mac->x, expected_mac->len,
-                    actual_mac, mac_length );
+        test_set_step( output_size );
+        ASSERT_ALLOC( actual_mac, output_size );
 
-    /* Verify that the end of the buffer is untouched. */
-    TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
-                              sizeof( actual_mac ) - mac_length ) );
+        /* Calculate the MAC. */
+        PSA_ASSERT( psa_mac_sign_setup( &operation,
+                                        handle, alg ) );
+        PSA_ASSERT( psa_mac_update( &operation,
+                                    input->x, input->len ) );
+        TEST_EQUAL( psa_mac_sign_finish( &operation,
+                                         actual_mac, output_size,
+                                         &mac_length ),
+                    expected_status );
+        PSA_ASSERT( psa_mac_abort( &operation ) );
+
+        if( expected_status == PSA_SUCCESS )
+        {
+            ASSERT_COMPARE( expected_mac->x, expected_mac->len,
+                            actual_mac, mac_length );
+        }
+        mbedtls_free( actual_mac );
+        actual_mac = NULL;
+    }
 
 exit:
+    psa_mac_abort( &operation );
     psa_destroy_key( handle );
     PSA_DONE( );
+    mbedtls_free( actual_mac );
 }
 /* END_CASE */
 
@@ -3083,6 +3102,7 @@
     psa_algorithm_t alg = alg_arg;
     psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    uint8_t *perturbed_mac = NULL;
 
     TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
 
@@ -3094,18 +3114,58 @@
 
     PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
 
+    /* Test the correct MAC. */
     PSA_ASSERT( psa_mac_verify_setup( &operation,
                                       handle, alg ) );
-    PSA_ASSERT( psa_destroy_key( handle ) );
     PSA_ASSERT( psa_mac_update( &operation,
                                 input->x, input->len ) );
     PSA_ASSERT( psa_mac_verify_finish( &operation,
                                        expected_mac->x,
                                        expected_mac->len ) );
 
+    /* Test a MAC that's too short. */
+    PSA_ASSERT( psa_mac_verify_setup( &operation,
+                                      handle, alg ) );
+    PSA_ASSERT( psa_mac_update( &operation,
+                                input->x, input->len ) );
+    TEST_EQUAL( psa_mac_verify_finish( &operation,
+                                       expected_mac->x,
+                                       expected_mac->len - 1 ),
+                PSA_ERROR_INVALID_SIGNATURE );
+
+    /* Test a MAC that's too long. */
+    ASSERT_ALLOC( perturbed_mac, expected_mac->len + 1 );
+    memcpy( perturbed_mac, expected_mac->x, expected_mac->len );
+    PSA_ASSERT( psa_mac_verify_setup( &operation,
+                                      handle, alg ) );
+    PSA_ASSERT( psa_mac_update( &operation,
+                                input->x, input->len ) );
+    TEST_EQUAL( psa_mac_verify_finish( &operation,
+                                       perturbed_mac,
+                                       expected_mac->len + 1 ),
+                PSA_ERROR_INVALID_SIGNATURE );
+
+    /* Test changing one byte. */
+    for( size_t i = 0; i < expected_mac->len; i++ )
+    {
+        test_set_step( i );
+        perturbed_mac[i] ^= 1;
+        PSA_ASSERT( psa_mac_verify_setup( &operation,
+                                          handle, alg ) );
+        PSA_ASSERT( psa_mac_update( &operation,
+                                    input->x, input->len ) );
+        TEST_EQUAL( psa_mac_verify_finish( &operation,
+                                           perturbed_mac,
+                                           expected_mac->len ),
+                    PSA_ERROR_INVALID_SIGNATURE );
+        perturbed_mac[i] ^= 1;
+    }
+
 exit:
+    psa_mac_abort( &operation );
     psa_destroy_key( handle );
     PSA_DONE( );
+    mbedtls_free( perturbed_mac );
 }
 /* END_CASE */
 
@@ -3183,6 +3243,7 @@
 #endif
 
 exit:
+    psa_cipher_abort( &operation );
     PSA_DONE( );
 }
 /* END_CASE */
@@ -3335,6 +3396,7 @@
     PSA_ASSERT( psa_destroy_key( handle ) );
 
 exit:
+    psa_cipher_abort( &operation );
     PSA_DONE( );
 }
 /* END_CASE */
@@ -3393,6 +3455,7 @@
     }
 
 exit:
+    psa_cipher_abort( &operation );
     mbedtls_free( output );
     psa_destroy_key( handle );
     PSA_DONE( );
@@ -3461,6 +3524,7 @@
                     output, total_output_length );
 
 exit:
+    psa_cipher_abort( &operation );
     mbedtls_free( output );
     psa_destroy_key( handle );
     PSA_DONE( );
@@ -3532,6 +3596,7 @@
                     output, total_output_length );
 
 exit:
+    psa_cipher_abort( &operation );
     mbedtls_free( output );
     psa_destroy_key( handle );
     PSA_DONE( );
@@ -3593,6 +3658,7 @@
     }
 
 exit:
+    psa_cipher_abort( &operation );
     mbedtls_free( output );
     psa_destroy_key( handle );
     PSA_DONE( );
@@ -3674,6 +3740,8 @@
     ASSERT_COMPARE( input->x, input->len, output2, output2_length );
 
 exit:
+    psa_cipher_abort( &operation1 );
+    psa_cipher_abort( &operation2 );
     mbedtls_free( output1 );
     mbedtls_free( output2 );
     psa_destroy_key( handle );
@@ -3777,6 +3845,8 @@
     ASSERT_COMPARE( input->x, input->len, output2, output2_length );
 
 exit:
+    psa_cipher_abort( &operation1 );
+    psa_cipher_abort( &operation2 );
     mbedtls_free( output1 );
     mbedtls_free( output2 );
     psa_destroy_key( handle );
@@ -5639,7 +5709,7 @@
         /* In case there was a test failure after creating the persistent key
          * but while it was not open, try to re-open the persistent key
          * to delete it. */
-        psa_open_key( key_id, &handle );
+        (void) psa_open_key( key_id, &handle );
     }
     psa_destroy_key( handle );
     PSA_DONE();
diff --git a/tests/suites/test_suite_psa_crypto_hash.function b/tests/suites/test_suite_psa_crypto_hash.function
index 6c577c0..1bc9331 100644
--- a/tests/suites/test_suite_psa_crypto_hash.function
+++ b/tests/suites/test_suite_psa_crypto_hash.function
@@ -31,6 +31,7 @@
                     actual_hash, actual_hash_length );
 
 exit:
+    psa_hash_abort( &operation );
     PSA_DONE( );
 }
 /* END_CASE */
@@ -52,6 +53,7 @@
                                  expected_hash->len ) );
 
 exit:
+    psa_hash_abort( &operation );
     PSA_DONE( );
 }
 /* END_CASE */
@@ -95,6 +97,8 @@
     } while( len++ != input->len );
 
 exit:
+    psa_hash_abort( &operation );
+    psa_hash_abort( &operation2 );
     PSA_DONE( );
 }
 /* END_CASE */
diff --git a/tests/suites/test_suite_psa_crypto_metadata.function b/tests/suites/test_suite_psa_crypto_metadata.function
index 1ba8466..7c0929e 100644
--- a/tests/suites/test_suite_psa_crypto_metadata.function
+++ b/tests/suites/test_suite_psa_crypto_metadata.function
@@ -57,8 +57,18 @@
     TEST_ASSERT( PSA_##flag( alg ) == !! ( ( flags ) & flag ) )
 
 /* Check the parity of value.
- * Return 0 if value has even parity and a nonzero value otherwise. */
-int test_parity( uint32_t value )
+ *
+ * There are several numerical encodings for which the PSA Cryptography API
+ * specification deliberately defines encodings that all have the same
+ * parity. This way, a data glitch that flips one bit in the data cannot
+ * possibly turn a valid encoding into another valid encoding. Here in
+ * the tests, we check that the values (including Mbed TLS vendor-specific
+ * values) have the expected parity.
+ *
+ * The expected parity is even so that 0 is considered a valid encoding.
+ *
+ * Return a nonzero value if value has even parity and 0 otherwise. */
+int has_even_parity( uint32_t value )
 {
     value ^= value >> 16;
     value ^= value >> 8;
@@ -66,7 +76,7 @@
     return( 0x9669 & 1 << ( value & 0xf ) );
 }
 #define TEST_PARITY( value )                    \
-    TEST_ASSERT( test_parity( value ) )
+    TEST_ASSERT( has_even_parity( value ) )
 
 void algorithm_classification( psa_algorithm_t alg, unsigned flags )
 {
@@ -497,7 +507,7 @@
     psa_key_type_t public_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY( curve );
     psa_key_type_t pair_type = PSA_KEY_TYPE_ECC_KEY_PAIR( curve );
 
-    test_parity( curve );
+    TEST_PARITY( curve );
 
     test_key_type( public_type, KEY_TYPE_IS_ECC | KEY_TYPE_IS_PUBLIC_KEY );
     test_key_type( pair_type, KEY_TYPE_IS_ECC | KEY_TYPE_IS_KEY_PAIR );
@@ -514,7 +524,7 @@
     psa_key_type_t public_type = PSA_KEY_TYPE_DH_PUBLIC_KEY( group );
     psa_key_type_t pair_type = PSA_KEY_TYPE_DH_KEY_PAIR( group );
 
-    test_parity( group );
+    TEST_PARITY( group );
 
     test_key_type( public_type, KEY_TYPE_IS_DH | KEY_TYPE_IS_PUBLIC_KEY );
     test_key_type( pair_type, KEY_TYPE_IS_DH | KEY_TYPE_IS_KEY_PAIR );
diff --git a/tests/suites/test_suite_psa_its.function b/tests/suites/test_suite_psa_its.function
index b6cc488..a7ce7b1 100644
--- a/tests/suites/test_suite_psa_its.function
+++ b/tests/suites/test_suite_psa_its.function
@@ -40,16 +40,23 @@
 
 static void cleanup( void )
 {
+    /* Call remove() on all the files that a test might have created.
+     * We ignore the error if the file exists but remove() fails because
+     * it can't be checked portably (except by attempting to open the file
+     * first, which is needlessly slow and complicated here). A failure of
+     * remove() on an existing file is very unlikely anyway and would not
+     * have significant consequences other than perhaps failing the next
+     * test case. */
     char filename[PSA_ITS_STORAGE_FILENAME_LENGTH];
     psa_storage_uid_t uid;
     for( uid = 0; uid < uid_max; uid++ )
     {
         psa_its_fill_filename( uid, filename );
-        remove( filename );
+        (void) remove( filename );
     }
     psa_its_fill_filename( (psa_storage_uid_t)( -1 ), filename );
-    remove( filename );
-    remove( PSA_ITS_STORAGE_TEMP );
+    (void) remove( filename );
+    (void) remove( PSA_ITS_STORAGE_TEMP );
     uid_max = 0;
 }
 
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 1b0316e..bfdbab2 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -911,6 +911,14 @@
 depends_on:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_ECDSA_C:MBEDTLS_SHA1_C
 x509_verify:"data_files/cert_sha256.crt":"data_files/test-ca.crt":"data_files/crl-ec-sha256.pem":"NULL":0:0:"next":"NULL"
 
+X509 CRT verification #98 (Revoked Cert, revocation date in the future, _with_ MBEDTLS_HAVE_TIME_DATE)
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_HAVE_TIME_DATE
+x509_verify:"data_files/server1.crt":"data_files/test-ca.crt":"data_files/crl-futureRevocationDate.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_REVOKED|MBEDTLS_X509_BADCRL_FUTURE:"compat":"NULL"
+
+X509 CRT verification #99 (Revoked Cert, revocation date in the future, _without_ MBEDTLS_HAVE_TIME_DATE)
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:!MBEDTLS_HAVE_TIME_DATE
+x509_verify:"data_files/server1.crt":"data_files/test-ca.crt":"data_files/crl-futureRevocationDate.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_REVOKED:"compat":"NULL"
+
 X509 CRT verification: domain identical to IPv4 in SubjectAltName
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_SHA256_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_RSA_C
 x509_verify:"data_files/server5-tricky-ip-san.crt":"data_files/server5-tricky-ip-san.crt":"data_files/crl_sha256.pem":"abcd":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_CN_MISMATCH:"":"NULL"