Merge pull request #5863 from wernerlewis/csr_subject_comma_2.28

[Backport 2.28] Fix output of commas and other special characters in X509 DN values
diff --git a/ChangeLog.d/bug_x448.txt b/ChangeLog.d/bug_x448.txt
new file mode 100644
index 0000000..cebefc4
--- /dev/null
+++ b/ChangeLog.d/bug_x448.txt
@@ -0,0 +1,2 @@
+Bugfix
+    * Fix order value of curve x448.
diff --git a/ChangeLog.d/fix-time-format-pre-2000.txt b/ChangeLog.d/fix-time-format-pre-2000.txt
new file mode 100644
index 0000000..414201e
--- /dev/null
+++ b/ChangeLog.d/fix-time-format-pre-2000.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Encode X.509 dates before 1/1/2000 as UTCTime rather than
+     GeneralizedTime. Fixes #5465.
diff --git a/ChangeLog.d/fix-windows-cmake-build-with-shared-libraries.txt b/ChangeLog.d/fix-windows-cmake-build-with-shared-libraries.txt
index 6878645..a6540a1 100644
--- a/ChangeLog.d/fix-windows-cmake-build-with-shared-libraries.txt
+++ b/ChangeLog.d/fix-windows-cmake-build-with-shared-libraries.txt
@@ -1,3 +1,3 @@
 Bugfix
-   * Fix compilation on Windows when building shared library, by setting
-     library search path to CMAKE_CURRENT_BINARY_DIR.
+   * Fix the library search path when building a shared library with CMake
+     on Windows.
diff --git a/ChangeLog.d/fix-x25519-program.txt b/ChangeLog.d/fix-x25519-program.txt
new file mode 100644
index 0000000..bf5d6ac
--- /dev/null
+++ b/ChangeLog.d/fix-x25519-program.txt
@@ -0,0 +1,4 @@
+Bugfix
+   * Fix a bug in the x25519 example program where the removal of
+     MBEDTLS_ECDH_LEGACY_CONTEXT caused the program not to run. Fixes #4901 and
+     #3191.
diff --git a/ChangeLog.d/mbedtls_ssl_config_defaults-memleak.txt b/ChangeLog.d/mbedtls_ssl_config_defaults-memleak.txt
index d55c016..043b273 100644
--- a/ChangeLog.d/mbedtls_ssl_config_defaults-memleak.txt
+++ b/ChangeLog.d/mbedtls_ssl_config_defaults-memleak.txt
@@ -1,2 +1,2 @@
 Bugfix
-   * Fix memory leak if mbedtls_ssl_config_defaults() call is repeated
+   * Fix a memory leak if mbedtls_ssl_config_defaults() is called twice.
diff --git a/ChangeLog.d/raw-agreement-destroy-missing.txt b/ChangeLog.d/raw-agreement-destroy-missing.txt
deleted file mode 100644
index 7342b8c..0000000
--- a/ChangeLog.d/raw-agreement-destroy-missing.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
-   * Add missing key slot destruction calls when a raw key agreement or
-     a public key export fails in ssl_write_client_key_exchange.
diff --git a/ChangeLog.d/use-psa-ecdhe-curve.txt b/ChangeLog.d/use-psa-ecdhe-curve.txt
index cc432bd..658f88f 100644
--- a/ChangeLog.d/use-psa-ecdhe-curve.txt
+++ b/ChangeLog.d/use-psa-ecdhe-curve.txt
@@ -4,4 +4,4 @@
      client would fail to check that the curve selected by the server for
      ECDHE was indeed one that was offered. As a result, the client would
      accept any curve that it supported, even if that curve was not allowed
-     according to its configuration.
+     according to its configuration. Fixes #5291.
diff --git a/include/mbedtls/aes.h b/include/mbedtls/aes.h
index e280dbb..401ac39 100644
--- a/include/mbedtls/aes.h
+++ b/include/mbedtls/aes.h
@@ -564,7 +564,7 @@
  *             for example, with 96-bit random nonces, you should not encrypt
  *             more than 2**32 messages with the same key.
  *
- *             Note that for both stategies, sizes are measured in blocks and
+ *             Note that for both strategies, sizes are measured in blocks and
  *             that an AES block is 16 bytes.
  *
  * \warning    Upon return, \p stream_block contains sensitive data. Its
diff --git a/include/mbedtls/aria.h b/include/mbedtls/aria.h
index 6e47272..d294c47 100644
--- a/include/mbedtls/aria.h
+++ b/include/mbedtls/aria.h
@@ -321,7 +321,7 @@
  *             for example, with 96-bit random nonces, you should not encrypt
  *             more than 2**32 messages with the same key.
  *
- *             Note that for both stategies, sizes are measured in blocks and
+ *             Note that for both strategies, sizes are measured in blocks and
  *             that an ARIA block is 16 bytes.
  *
  * \warning    Upon return, \p stream_block contains sensitive data. Its
diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h
index 9d2cff3..dd594c5 100644
--- a/include/mbedtls/bignum.h
+++ b/include/mbedtls/bignum.h
@@ -989,7 +989,7 @@
  *                 generate yourself and that are supposed to be prime, then
  *                 \p rounds should be at least the half of the security
  *                 strength of the cryptographic algorithm. On the other hand,
- *                 if \p X is chosen uniformly or non-adversially (as is the
+ *                 if \p X is chosen uniformly or non-adversarially (as is the
  *                 case when mbedtls_mpi_gen_prime calls this function), then
  *                 \p rounds can be much lower.
  *
diff --git a/include/mbedtls/blowfish.h b/include/mbedtls/blowfish.h
index 15a49c5..d5f8099 100644
--- a/include/mbedtls/blowfish.h
+++ b/include/mbedtls/blowfish.h
@@ -246,7 +246,7 @@
  *             The recommended way to ensure uniqueness is to use a message
  *             counter.
  *
- *             Note that for both stategies, sizes are measured in blocks and
+ *             Note that for both strategies, sizes are measured in blocks and
  *             that a Blowfish block is 8 bytes.
  *
  * \warning    Upon return, \p stream_block contains sensitive data. Its
diff --git a/include/mbedtls/camellia.h b/include/mbedtls/camellia.h
index 925a623..d39d932 100644
--- a/include/mbedtls/camellia.h
+++ b/include/mbedtls/camellia.h
@@ -273,7 +273,7 @@
  *             encrypted: for example, with 96-bit random nonces, you should
  *             not encrypt more than 2**32 messages with the same key.
  *
- *             Note that for both stategies, sizes are measured in blocks and
+ *             Note that for both strategies, sizes are measured in blocks and
  *             that a CAMELLIA block is \c 16 Bytes.
  *
  * \warning    Upon return, \p stream_block contains sensitive data. Its
diff --git a/include/mbedtls/chachapoly.h b/include/mbedtls/chachapoly.h
index c4ec7b5..ed568bc 100644
--- a/include/mbedtls/chachapoly.h
+++ b/include/mbedtls/chachapoly.h
@@ -161,7 +161,7 @@
  * \param ctx       The ChaCha20-Poly1305 context. This must be initialized
  *                  and bound to a key.
  * \param nonce     The nonce/IV to use for the message.
- *                  This must be a redable buffer of length \c 12 Bytes.
+ *                  This must be a readable buffer of length \c 12 Bytes.
  * \param mode      The operation to perform: #MBEDTLS_CHACHAPOLY_ENCRYPT or
  *                  #MBEDTLS_CHACHAPOLY_DECRYPT (discouraged, see warning).
  *
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 6acd9b1..1cd6eb6 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -2918,7 +2918,7 @@
  *
  * Requires: MBEDTLS_MD_C
  *
- * Uncomment to enable the HMAC_DRBG random number geerator.
+ * Uncomment to enable the HMAC_DRBG random number generator.
  */
 #define MBEDTLS_HMAC_DRBG_C
 
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index 9effa44..64a0bcc 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -315,7 +315,7 @@
 #if !defined(MBEDTLS_ECP_WINDOW_SIZE)
 /*
  * Maximum "window" size used for point multiplication.
- * Default: a point where higher memory usage yields disminishing performance
+ * Default: a point where higher memory usage yields diminishing performance
  *          returns.
  * Minimum value: 2. Maximum value: 7.
  *
diff --git a/include/mbedtls/oid.h b/include/mbedtls/oid.h
index 1c39186..0186217 100644
--- a/include/mbedtls/oid.h
+++ b/include/mbedtls/oid.h
@@ -143,7 +143,7 @@
 #define MBEDTLS_OID_AT_GIVEN_NAME               MBEDTLS_OID_AT "\x2A" /**< id-at-givenName AttributeType:= {id-at 42} */
 #define MBEDTLS_OID_AT_INITIALS                 MBEDTLS_OID_AT "\x2B" /**< id-at-initials AttributeType:= {id-at 43} */
 #define MBEDTLS_OID_AT_GENERATION_QUALIFIER     MBEDTLS_OID_AT "\x2C" /**< id-at-generationQualifier AttributeType:= {id-at 44} */
-#define MBEDTLS_OID_AT_UNIQUE_IDENTIFIER        MBEDTLS_OID_AT "\x2D" /**< id-at-uniqueIdentifier AttributType:= {id-at 45} */
+#define MBEDTLS_OID_AT_UNIQUE_IDENTIFIER        MBEDTLS_OID_AT "\x2D" /**< id-at-uniqueIdentifier AttributeType:= {id-at 45} */
 #define MBEDTLS_OID_AT_DN_QUALIFIER             MBEDTLS_OID_AT "\x2E" /**< id-at-dnQualifier AttributeType:= {id-at 46} */
 #define MBEDTLS_OID_AT_PSEUDONYM                MBEDTLS_OID_AT "\x41" /**< id-at-pseudonym AttributeType:= {id-at 65} */
 
diff --git a/include/mbedtls/platform_util.h b/include/mbedtls/platform_util.h
index f3af3ac..cd112ab 100644
--- a/include/mbedtls/platform_util.h
+++ b/include/mbedtls/platform_util.h
@@ -198,7 +198,7 @@
  *
  * 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
+ * has been analyzed for return-check usefulness, whereas the lack of
  * an annotation indicates that the function has not been analyzed and its
  * return-check usefulness is unknown.
  */
diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h
index ca0c6e1..062df73 100644
--- a/include/mbedtls/rsa.h
+++ b/include/mbedtls/rsa.h
@@ -687,7 +687,7 @@
  *                   mode being set to #MBEDTLS_RSA_PRIVATE and might instead
  *                   return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
  *
- * \param ctx        The initnialized RSA context to use.
+ * \param ctx        The initialized RSA context to use.
  * \param f_rng      The RNG function to use. This is needed for padding
  *                   generation and must be provided.
  * \param p_rng      The RNG context to be passed to \p f_rng. This may
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 8c2d8f8..5064ec5 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1152,7 +1152,7 @@
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
-    /** Callback to create & write a cookie for ClientHello veirifcation    */
+    /** Callback to create & write a cookie for ClientHello verification    */
     int (*f_cookie_write)( void *, unsigned char **, unsigned char *,
                            const unsigned char *, size_t );
     /** Callback to verify validity of a ClientHello cookie                 */
@@ -2498,7 +2498,7 @@
  *                 successfully cached, return 1 otherwise.
  *
  * \param conf           SSL configuration
- * \param p_cache        parmater (context) for both callbacks
+ * \param p_cache        parameter (context) for both callbacks
  * \param f_get_cache    session get callback
  * \param f_set_cache    session set callback
  */
@@ -2529,7 +2529,7 @@
 /**
  * \brief          Load serialized session data into a session structure.
  *                 On client, this can be used for loading saved sessions
- *                 before resuming them with mbedstls_ssl_set_session().
+ *                 before resuming them with mbedtls_ssl_set_session().
  *                 On server, this can be used for alternative implementations
  *                 of session cache or session tickets.
  *
@@ -3508,7 +3508,7 @@
  *                 \c mbedtls_ssl_get_record_expansion().
  *
  * \note           For DTLS, it is also possible to set a limit for the total
- *                 size of daragrams passed to the transport layer, including
+ *                 size of datagrams passed to the transport layer, including
  *                 record overhead, see \c mbedtls_ssl_set_mtu().
  *
  * \param conf     SSL configuration
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index 70a4e4d..0f2885a 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -107,7 +107,7 @@
 typedef struct mbedtls_x509_san_other_name
 {
     /**
-     * The type_id is an OID as deifned in RFC 5280.
+     * The type_id is an OID as defined in RFC 5280.
      * To check the value of the type id, you should use
      * \p MBEDTLS_OID_CMP with a known OID mbedtls_x509_buf.
      */
@@ -979,7 +979,7 @@
  * \param is_ca     is this a CA certificate
  * \param max_pathlen   maximum length of certificate chains below this
  *                      certificate (only for CA certificates, -1 is
- *                      inlimited)
+ *                      unlimited)
  *
  * \return          0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED
  */
diff --git a/include/psa/crypto_config.h b/include/psa/crypto_config.h
index 9019ca9..f261e01 100644
--- a/include/psa/crypto_config.h
+++ b/include/psa/crypto_config.h
@@ -60,7 +60,6 @@
 #define PSA_WANT_ALG_CMAC                       1
 #define PSA_WANT_ALG_CFB                        1
 #define PSA_WANT_ALG_CHACHA20_POLY1305          1
-#define PSA_WANT_ALG_CMAC                       1
 #define PSA_WANT_ALG_CTR                        1
 #define PSA_WANT_ALG_DETERMINISTIC_ECDSA        1
 #define PSA_WANT_ALG_ECB_NO_PADDING             1
diff --git a/library/constant_time.c b/library/constant_time.c
index 7487b9b..e276d23 100644
--- a/library/constant_time.c
+++ b/library/constant_time.c
@@ -489,6 +489,12 @@
     MD_CHK( mbedtls_md_update( ctx, add_data, add_data_len ) );
     MD_CHK( mbedtls_md_update( ctx, data, min_data_len ) );
 
+    /* Fill the hash buffer in advance with something that is
+     * not a valid hash (barring an attack on the hash and
+     * deliberately-crafted input), in case the caller doesn't
+     * check the return status properly. */
+    memset( output, '!', hash_size );
+
     /* For each possible length, compute the hash up to that point */
     for( offset = min_data_len; offset <= max_data_len; offset++ )
     {
diff --git a/library/constant_time_internal.h b/library/constant_time_internal.h
index bbb3a90..a550b38 100644
--- a/library/constant_time_internal.h
+++ b/library/constant_time_internal.h
@@ -221,6 +221,13 @@
  * offset_secret, but only on \p offset_min, \p offset_max and \p len.
  * Functionally equivalent to `memcpy(dst, src + offset_secret, len)`.
  *
+ * \note                This function reads from \p dest, but the value that
+ *                      is read does not influence the result and this
+ *                      function's behavior is well-defined regardless of the
+ *                      contents of the buffers. This may result in false
+ *                      positives from static or dynamic analyzers, especially
+ *                      if \p dest is not initialized.
+ *
  * \param dest          The destination buffer. This must point to a writable
  *                      buffer of at least \p len bytes.
  * \param src           The base of the source buffer. This must point to a
diff --git a/library/ecp_curves.c b/library/ecp_curves.c
index ff26a18..2199be6 100644
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -755,6 +755,8 @@
     ECP_VALIDATE_RET( grp != NULL );
     mbedtls_ecp_group_free( grp );
 
+    mbedtls_ecp_group_init( grp );
+
     grp->id = id;
 
     switch( id )
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index 933d3d9..5a4574d 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -1590,8 +1590,8 @@
 #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
     if( auth_done == 0 )
     {
-        unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
-        unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD];
+        unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD] = { 0 };
+        unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD] = { 0 };
 
         /* If the initial value of padlen was such that
          * data_len < maclen + padlen + 1, then padlen
diff --git a/library/x509write_crt.c b/library/x509write_crt.c
index 184c90c..0c5e991 100644
--- a/library/x509write_crt.c
+++ b/library/x509write_crt.c
@@ -299,7 +299,7 @@
     /*
      * write MBEDTLS_ASN1_UTC_TIME if year < 2050 (2 bytes shorter)
      */
-    if( t[0] == '2' && t[1] == '0' && t[2] < '5' )
+    if( t[0] < '2' || ( t[0] == '2' && t[1] == '0' && t[2] < '5' ) )
     {
         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
                                              (const unsigned char *) t + 2,
diff --git a/programs/pkey/ecdh_curve25519.c b/programs/pkey/ecdh_curve25519.c
index 67f1363..65b206a 100644
--- a/programs/pkey/ecdh_curve25519.c
+++ b/programs/pkey/ecdh_curve25519.c
@@ -34,12 +34,12 @@
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
 
-#if !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDH_LEGACY_CONTEXT) || \
+#if !defined(MBEDTLS_ECDH_C) || \
     !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
     !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C)
 int main( void )
 {
-    mbedtls_printf( "MBEDTLS_ECDH_C and/or MBEDTLS_ECDH_LEGACY_CONTEXT and/or "
+    mbedtls_printf( "MBEDTLS_ECDH_C and/or "
                     "MBEDTLS_ECP_DP_CURVE25519_ENABLED and/or "
                     "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C "
                     "not defined\n" );
@@ -51,6 +51,8 @@
 #include "mbedtls/ctr_drbg.h"
 #include "mbedtls/ecdh.h"
 
+#include <string.h>
+
 
 int main( int argc, char *argv[] )
 {
@@ -59,8 +61,15 @@
     mbedtls_ecdh_context ctx_cli, ctx_srv;
     mbedtls_entropy_context entropy;
     mbedtls_ctr_drbg_context ctr_drbg;
-    unsigned char cli_to_srv[32], srv_to_cli[32];
+    unsigned char cli_to_srv[36], srv_to_cli[33];
     const char pers[] = "ecdh";
+
+    size_t srv_olen;
+    size_t cli_olen;
+    unsigned char secret_cli[32] = { 0 };
+    unsigned char secret_srv[32] = { 0 };
+    const unsigned char *p_cli_to_srv = cli_to_srv;
+
     ((void) argc);
     ((void) argv);
 
@@ -71,15 +80,17 @@
     /*
      * Initialize random number generation
      */
-    mbedtls_printf( "  . Seeding the random number generator..." );
+    mbedtls_printf( "  . Seed the random number generator..." );
     fflush( stdout );
 
     mbedtls_entropy_init( &entropy );
-    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
-                               (const unsigned char *) pers,
-                               sizeof pers ) ) != 0 )
+    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func,
+                                       &entropy,
+                                       (const unsigned char *) pers,
+                                       sizeof pers ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n",
+                        ret );
         goto exit;
     }
 
@@ -88,28 +99,23 @@
     /*
      * Client: initialize context and generate keypair
      */
-    mbedtls_printf( "  . Setting up client context..." );
+    mbedtls_printf( "  . Set up client context, generate EC key pair..." );
     fflush( stdout );
 
-    ret = mbedtls_ecp_group_load( &ctx_cli.grp, MBEDTLS_ECP_DP_CURVE25519 );
+    ret = mbedtls_ecdh_setup( &ctx_cli, MBEDTLS_ECP_DP_CURVE25519 );
     if( ret != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ecp_group_load returned %d\n", ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ecdh_setup returned %d\n", ret );
         goto exit;
     }
 
-    ret = mbedtls_ecdh_gen_public( &ctx_cli.grp, &ctx_cli.d, &ctx_cli.Q,
-                                   mbedtls_ctr_drbg_random, &ctr_drbg );
+    ret = mbedtls_ecdh_make_params( &ctx_cli, &cli_olen, cli_to_srv,
+                                    sizeof( cli_to_srv ),
+                                    mbedtls_ctr_drbg_random, &ctr_drbg );
     if( ret != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ecdh_gen_public returned %d\n", ret );
-        goto exit;
-    }
-
-    ret = mbedtls_mpi_write_binary( &ctx_cli.Q.X, cli_to_srv, 32 );
-    if( ret != 0 )
-    {
-        mbedtls_printf( " failed\n  ! mbedtls_mpi_write_binary returned %d\n", ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ecdh_make_params returned %d\n",
+                        ret );
         goto exit;
     }
 
@@ -118,90 +124,70 @@
     /*
      * Server: initialize context and generate keypair
      */
-    mbedtls_printf( "  . Setting up server context..." );
+    mbedtls_printf( "  . Server: read params, generate public key..." );
     fflush( stdout );
 
-    ret = mbedtls_ecp_group_load( &ctx_srv.grp, MBEDTLS_ECP_DP_CURVE25519 );
+    ret = mbedtls_ecdh_read_params( &ctx_srv, &p_cli_to_srv,
+                                    p_cli_to_srv + sizeof( cli_to_srv ) );
     if( ret != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ecp_group_load returned %d\n", ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ecdh_read_params returned %d\n",
+                        ret );
         goto exit;
     }
 
-    ret = mbedtls_ecdh_gen_public( &ctx_srv.grp, &ctx_srv.d, &ctx_srv.Q,
-                                   mbedtls_ctr_drbg_random, &ctr_drbg );
+    ret = mbedtls_ecdh_make_public( &ctx_srv, &srv_olen, srv_to_cli,
+                                    sizeof( srv_to_cli ),
+                                    mbedtls_ctr_drbg_random, &ctr_drbg );
     if( ret != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ecdh_gen_public returned %d\n", ret );
-        goto exit;
-    }
-
-    ret = mbedtls_mpi_write_binary( &ctx_srv.Q.X, srv_to_cli, 32 );
-    if( ret != 0 )
-    {
-        mbedtls_printf( " failed\n  ! mbedtls_mpi_write_binary returned %d\n", ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ecdh_make_public returned %d\n",
+                        ret );
         goto exit;
     }
 
     mbedtls_printf( " ok\n" );
 
     /*
-     * Server: read peer's key and generate shared secret
+     * Client: read public key
      */
-    mbedtls_printf( "  . Server reading client key and computing secret..." );
+    mbedtls_printf( "  . Client: read public key..." );
     fflush( stdout );
 
-    ret = mbedtls_mpi_lset( &ctx_srv.Qp.Z, 1 );
+    ret = mbedtls_ecdh_read_public( &ctx_cli, srv_to_cli,
+                                    sizeof( srv_to_cli ) );
     if( ret != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_mpi_lset returned %d\n", ret );
-        goto exit;
-    }
-
-    ret = mbedtls_mpi_read_binary( &ctx_srv.Qp.X, cli_to_srv, 32 );
-    if( ret != 0 )
-    {
-        mbedtls_printf( " failed\n  ! mbedtls_mpi_read_binary returned %d\n", ret );
-        goto exit;
-    }
-
-    ret = mbedtls_ecdh_compute_shared( &ctx_srv.grp, &ctx_srv.z,
-                                       &ctx_srv.Qp, &ctx_srv.d,
-                                       mbedtls_ctr_drbg_random, &ctr_drbg );
-    if( ret != 0 )
-    {
-        mbedtls_printf( " failed\n  ! mbedtls_ecdh_compute_shared returned %d\n", ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ecdh_read_public returned %d\n",
+                        ret );
         goto exit;
     }
 
     mbedtls_printf( " ok\n" );
 
     /*
-     * Client: read peer's key and generate shared secret
+     * Calculate secrets
      */
-    mbedtls_printf( "  . Client reading server key and computing secret..." );
+    mbedtls_printf( "  . Calculate secrets..." );
     fflush( stdout );
 
-    ret = mbedtls_mpi_lset( &ctx_cli.Qp.Z, 1 );
+    ret = mbedtls_ecdh_calc_secret( &ctx_cli, &cli_olen, secret_cli,
+                                    sizeof( secret_cli ),
+                                    mbedtls_ctr_drbg_random, &ctr_drbg );
     if( ret != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_mpi_lset returned %d\n", ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ecdh_calc_secret returned %d\n",
+                        ret );
         goto exit;
     }
 
-    ret = mbedtls_mpi_read_binary( &ctx_cli.Qp.X, srv_to_cli, 32 );
+    ret = mbedtls_ecdh_calc_secret( &ctx_srv, &srv_olen, secret_srv,
+                                    sizeof( secret_srv ),
+                                    mbedtls_ctr_drbg_random, &ctr_drbg );
     if( ret != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_mpi_read_binary returned %d\n", ret );
-        goto exit;
-    }
-
-    ret = mbedtls_ecdh_compute_shared( &ctx_cli.grp, &ctx_cli.z,
-                                       &ctx_cli.Qp, &ctx_cli.d,
-                                       mbedtls_ctr_drbg_random, &ctr_drbg );
-    if( ret != 0 )
-    {
-        mbedtls_printf( " failed\n  ! mbedtls_ecdh_compute_shared returned %d\n", ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ecdh_calc_secret returned %d\n",
+                        ret );
         goto exit;
     }
 
@@ -210,13 +196,13 @@
     /*
      * Verification: are the computed secrets equal?
      */
-    mbedtls_printf( "  . Checking if both computed secrets are equal..." );
+    mbedtls_printf( "  . Check if both calculated secrets are equal..." );
     fflush( stdout );
 
-    ret = mbedtls_mpi_cmp_mpi( &ctx_cli.z, &ctx_srv.z );
-    if( ret != 0 )
+    ret = memcmp( secret_srv, secret_cli, srv_olen );
+    if( ret != 0 || ( cli_olen != srv_olen ) )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ecdh_compute_shared returned %d\n", ret );
+        mbedtls_printf( " failed\n  ! Shared secrets not equal.\n" );
         goto exit;
     }
 
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index c2b5007..fb9746f 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -1140,7 +1140,11 @@
     wait_server_start "$SRV_PORT" "$SRV_PID"
 
     printf '# %s\n%s\n' "$NAME" "$CLI_CMD" > $CLI_OUT
-    eval "$CLI_CMD" >> $CLI_OUT 2>&1 &
+    # The client must be a subprocess of the script in order for killing it to
+    # work properly, that's why the ampersand is placed inside the eval command,
+    # not at the end of the line: the latter approach will spawn eval as a
+    # subprocess, and the $CLI_CMD as a grandchild.
+    eval "$CLI_CMD &" >> $CLI_OUT 2>&1
     wait_client_done
 
     sleep 0.05
diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data
index 79912eb..dd46603 100644
--- a/tests/suites/test_suite_ecp.data
+++ b/tests/suites/test_suite_ecp.data
@@ -796,3 +796,55 @@
 # The first call to fix_negative in the test case of issue #4296.
 ECP fix_negative: #4296.1
 fix_negative:"8A4DD4C8B42C5EAED15FE4F4579F4CE513EC90A94010BF000000000000000000":-1:256
+
+ECP check order for SECP192R1
+depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
+ecp_check_order:MBEDTLS_ECP_DP_SECP192R1:"FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"
+
+ECP check order for SECP224R1
+depends_on:MBEDTLS_ECP_DP_SECP224R1_ENABLED
+ecp_check_order:MBEDTLS_ECP_DP_SECP224R1:"FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"
+
+ECP check order for SECP256R1
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_check_order:MBEDTLS_ECP_DP_SECP256R1:"FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"
+
+ECP check order for SECP384R1
+depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED
+ecp_check_order:MBEDTLS_ECP_DP_SECP384R1:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"
+
+ECP check order for SECP521R1
+depends_on:MBEDTLS_ECP_DP_SECP521R1_ENABLED
+ecp_check_order:MBEDTLS_ECP_DP_SECP521R1:"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409"
+
+ECP check order for BP256R1
+depends_on:MBEDTLS_ECP_DP_BP256R1_ENABLED
+ecp_check_order:MBEDTLS_ECP_DP_BP256R1:"A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7"
+
+ECP check order for BP384R1
+depends_on:MBEDTLS_ECP_DP_BP384R1_ENABLED
+ecp_check_order:MBEDTLS_ECP_DP_BP384R1:"8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565"
+
+ECP check order for BP512R1
+depends_on:MBEDTLS_ECP_DP_BP512R1_ENABLED
+ecp_check_order:MBEDTLS_ECP_DP_BP512R1:"AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069"
+
+ECP check order for CURVE25519
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_check_order:MBEDTLS_ECP_DP_CURVE25519:"1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed"
+
+ECP check order for SECP192K1
+depends_on:MBEDTLS_ECP_DP_SECP192K1_ENABLED
+ecp_check_order:MBEDTLS_ECP_DP_SECP192K1:"fffffffffffffffffffffffe26f2fc170f69466a74defd8d"
+
+ECP check order for SECP224K1
+depends_on:MBEDTLS_ECP_DP_SECP224K1_ENABLED
+ecp_check_order:MBEDTLS_ECP_DP_SECP224K1:"10000000000000000000000000001dce8d2ec6184caf0a971769fb1f7"
+
+ECP check order for SECP256K1
+depends_on:MBEDTLS_ECP_DP_SECP256K1_ENABLED
+ecp_check_order:MBEDTLS_ECP_DP_SECP256K1:"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"
+
+ECP check order for CURVE448
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_check_order:MBEDTLS_ECP_DP_CURVE448:"3fffffffffffffffffffffffffffffffffffffffffffffffffffffff7cca23e9c44edb49aed63690216cc2728dc58f552378c292ab5844f3"
diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function
index 538c648..023f5fe 100644
--- a/tests/suites/test_suite_ecp.function
+++ b/tests/suites/test_suite_ecp.function
@@ -1297,3 +1297,27 @@
     TEST_ASSERT( mbedtls_ecp_self_test( 1 ) == 0 );
 }
 /* END_CASE */
+
+/* BEGIN_CASE */
+void ecp_check_order( int id, char * expected_order_hex )
+{
+    mbedtls_ecp_group grp;
+    mbedtls_mpi expected_n;
+
+    mbedtls_ecp_group_init( &grp );
+    mbedtls_mpi_init( &expected_n );
+
+    TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &expected_n, 16, expected_order_hex ) == 0);
+
+    // check sign bits are well-formed (i.e. 1 or -1) - see #5810
+    TEST_ASSERT( grp.N.s == -1 || grp.N.s == 1);
+    TEST_ASSERT( expected_n.s == -1 || expected_n.s == 1);
+
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &grp.N, &expected_n ) == 0 );
+
+exit:
+    mbedtls_ecp_group_free( &grp );
+    mbedtls_mpi_free( &expected_n );
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_x509write.data b/tests/suites/test_suite_x509write.data
index cce99d4..1c1cf30 100644
--- a/tests/suites/test_suite_x509write.data
+++ b/tests/suites/test_suite_x509write.data
@@ -58,6 +58,22 @@
 depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C
 x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:0:0:1:-1:"data_files/server1.crt":0:0
 
+Certificate write check Server1 SHA1, not before 1970
+depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"19700210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:0:0:1:-1:"":0:0
+
+Certificate write check Server1 SHA1, not after 2050
+depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20500210144406":MBEDTLS_MD_SHA1:0:0:0:0:1:-1:"":0:0
+
+Certificate write check Server1 SHA1, not before 1970, not after 2050
+depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"19700210144406":"20500210144406":MBEDTLS_MD_SHA1:0:0:0:0:1:-1:"":0:0
+
+Certificate write check Server1 SHA1, not before 2050, not after 2059
+depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20500210144406":"20590210144406":MBEDTLS_MD_SHA1:0:0:0:0:1:-1:"":0:0
+
 Certificate write check Server1 SHA1, key_usage
 depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C
 x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_NON_REPUDIATION | MBEDTLS_X509_KU_KEY_ENCIPHERMENT:1:0:0:1:-1:"data_files/server1.key_usage.crt":0:0
diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function
index ce475e6..6a9cfeb 100644
--- a/tests/suites/test_suite_x509write.function
+++ b/tests/suites/test_suite_x509write.function
@@ -208,8 +208,10 @@
     mbedtls_x509write_cert crt;
     unsigned char buf[4096];
     unsigned char check_buf[5000];
+    unsigned char *p, *end;
+    unsigned char tag, sz;
     mbedtls_mpi serial;
-    int ret;
+    int ret, before_tag, after_tag;
     size_t olen = 0, pem_len = 0, buf_index = 0;
     int der_len = -1;
     FILE *f;
@@ -287,14 +289,16 @@
         TEST_ASSERT( buf[buf_index] == 0 );
     }
 
-    f = fopen( cert_check_file, "r" );
-    TEST_ASSERT( f != NULL );
-    olen = fread( check_buf, 1, sizeof( check_buf ), f );
-    fclose( f );
-    TEST_ASSERT( olen < sizeof( check_buf ) );
-
-    TEST_ASSERT( olen >= pem_len - 1 );
-    TEST_ASSERT( memcmp( buf, check_buf, pem_len - 1 ) == 0 );
+    if( *cert_check_file != '\0' )
+    {
+        f = fopen( cert_check_file, "r" );
+        TEST_ASSERT( f != NULL );
+        olen = fread( check_buf, 1, sizeof( check_buf ), f );
+        fclose( f );
+        TEST_ASSERT( olen < sizeof( check_buf ) );
+        TEST_ASSERT( olen >= pem_len - 1 );
+        TEST_ASSERT( memcmp( buf, check_buf, pem_len - 1 ) == 0 );
+    }
 
     der_len = mbedtls_x509write_crt_der( &crt, buf, sizeof( buf ),
                                          mbedtls_test_rnd_pseudo_rand,
@@ -304,6 +308,54 @@
     if( der_len == 0 )
         goto exit;
 
+    // Not testing against file, check date format
+    if( *cert_check_file == '\0' )
+    {
+        // UTC tag if before 2050, 2 digits less for year
+        if( not_before[0] == '2' && ( not_before[1] > '0' || not_before[2] > '4' ) )
+        {
+            before_tag = MBEDTLS_ASN1_GENERALIZED_TIME;
+        }
+        else
+        {
+            before_tag = MBEDTLS_ASN1_UTC_TIME;
+            not_before += 2;
+        }
+        if( not_after[0] == '2' && ( not_after[1] > '0' || not_after[2] > '4' ) )
+        {
+            after_tag = MBEDTLS_ASN1_GENERALIZED_TIME;
+        }
+        else
+        {
+            after_tag = MBEDTLS_ASN1_UTC_TIME;
+            not_after += 2;
+        }
+        end = buf + sizeof( buf );
+        for( p = end - der_len ; p < end ; )
+        {
+            tag = *p++;
+            sz = *p++;
+            if( tag == MBEDTLS_ASN1_UTC_TIME || tag == MBEDTLS_ASN1_GENERALIZED_TIME )
+            {
+                // Check correct tag and time written
+                TEST_ASSERT( before_tag == tag );
+                TEST_ASSERT( memcmp( p, not_before, sz - 1 ) == 0 );
+                p += sz;
+                tag = *p++;
+                sz = *p++;
+                TEST_ASSERT( after_tag == tag );
+                TEST_ASSERT( memcmp( p, not_after, sz - 1 ) == 0 );
+                break;
+            }
+            // Increment if long form ASN1 length
+            if( sz & 0x80 )
+                p += sz & 0x0F;
+            if( tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
+                p += sz;
+        }
+        TEST_ASSERT( p < end );
+    }
+
     ret = mbedtls_x509write_crt_der( &crt, buf, (size_t)( der_len - 1 ),
                                      mbedtls_test_rnd_pseudo_rand, &rnd_info );
     TEST_ASSERT( ret == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );