Merge pull request #4542 from mpg/fix-ssl-cf-hmac-alt-2.16

[Backport 2.16] Fix misuse of MD API in SSL constant-flow HMAC
diff --git a/ChangeLog.d/aria-alt.txt b/ChangeLog.d/aria-alt.txt
new file mode 100644
index 0000000..20aaa2b
--- /dev/null
+++ b/ChangeLog.d/aria-alt.txt
@@ -0,0 +1,5 @@
+Bugfix
+   * Fix some issues affecting MBEDTLS_ARIA_ALT implementations: a misplaced
+     directive in a header and a missing initialization in the self-test.
+   * Fix a missing initialization in the Camellia self-test, affecting
+     MBEDTLS_CAMELLIA_ALT implementations.
diff --git a/ChangeLog.d/ciphersuite-sha1-sha384-guard.txt b/ChangeLog.d/ciphersuite-sha1-sha384-guard.txt
new file mode 100644
index 0000000..d253f34
--- /dev/null
+++ b/ChangeLog.d/ciphersuite-sha1-sha384-guard.txt
@@ -0,0 +1,4 @@
+Bugfix
+   * The cipher suite TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384 was not available
+     when SHA-1 was disabled and was offered when SHA-1 was enabled but SHA-384
+     was disabled. Fix the dependency. Fixes #4472.
diff --git a/ChangeLog.d/host_test-int32.txt b/ChangeLog.d/host_test-int32.txt
new file mode 100644
index 0000000..60ef8e9
--- /dev/null
+++ b/ChangeLog.d/host_test-int32.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Fix test suite code on platforms where int32_t is not int, such as
+     Arm Cortex-M. Fixes #4530.
diff --git a/include/mbedtls/aria.h b/include/mbedtls/aria.h
index 13763d4..20f43f2 100644
--- a/include/mbedtls/aria.h
+++ b/include/mbedtls/aria.h
@@ -88,14 +88,14 @@
 /* MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED is deprecated and should not be used. */
 #define MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED      -0x0058  /**< ARIA hardware accelerator failed. */
 
-#if !defined(MBEDTLS_ARIA_ALT)
-// Regular implementation
-//
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_ARIA_ALT)
+// Regular implementation
+//
+
 /**
  * \brief The ARIA context-type definition.
  */
diff --git a/include/mbedtls/padlock.h b/include/mbedtls/padlock.h
index d8246e2..0e4a6bb 100644
--- a/include/mbedtls/padlock.h
+++ b/include/mbedtls/padlock.h
@@ -98,7 +98,7 @@
  *
  * \param feature  The feature to detect
  *
- * \return         1 if CPU has support for the feature, 0 otherwise
+ * \return         non-zero if CPU has support for the feature, 0 otherwise
  */
 int mbedtls_padlock_has_support( int feature );
 
diff --git a/library/aria.c b/library/aria.c
index ef0392f..50ccb91 100644
--- a/library/aria.c
+++ b/library/aria.c
@@ -952,7 +952,7 @@
         {                                   \
             if( verbose )                   \
                 mbedtls_printf( "failed\n" );       \
-            return( 1 );                    \
+            goto exit;                              \
         } else {                            \
             if( verbose )                   \
                 mbedtls_printf( "passed\n" );       \
@@ -966,6 +966,7 @@
     int i;
     uint8_t blk[MBEDTLS_ARIA_BLOCKSIZE];
     mbedtls_aria_context ctx;
+    int ret = 1;
 
 #if (defined(MBEDTLS_CIPHER_MODE_CFB) || defined(MBEDTLS_CIPHER_MODE_CTR))
     size_t j;
@@ -977,6 +978,8 @@
     uint8_t buf[48], iv[MBEDTLS_ARIA_BLOCKSIZE];
 #endif
 
+    mbedtls_aria_init( &ctx );
+
     /*
      * Test set 1
      */
@@ -1096,7 +1099,11 @@
         mbedtls_printf( "\n" );
 #endif /* MBEDTLS_CIPHER_MODE_CTR */
 
-    return( 0 );
+    ret = 0;
+
+exit:
+    mbedtls_aria_free( &ctx );
+    return( ret );
 }
 
 #endif /* MBEDTLS_SELF_TEST */
diff --git a/library/camellia.c b/library/camellia.c
index 40d6212..6cf265e 100644
--- a/library/camellia.c
+++ b/library/camellia.c
@@ -973,9 +973,11 @@
     unsigned char nonce_counter[16];
     unsigned char stream_block[16];
 #endif
+    int ret = 1;
 
     mbedtls_camellia_context ctx;
 
+    mbedtls_camellia_init( &ctx );
     memset( key, 0, 32 );
 
     for( j = 0; j < 6; j++ ) {
@@ -1005,8 +1007,7 @@
         {
             if( verbose != 0 )
                 mbedtls_printf( "failed\n" );
-
-            return( 1 );
+            goto exit;
         }
     }
 
@@ -1058,8 +1059,7 @@
             {
                 if( verbose != 0 )
                     mbedtls_printf( "failed\n" );
-
-                return( 1 );
+                goto exit;
             }
         }
 
@@ -1102,8 +1102,7 @@
             {
                 if( verbose != 0 )
                     mbedtls_printf( "failed\n" );
-
-                return( 1 );
+                goto exit;
             }
         }
         else
@@ -1118,8 +1117,7 @@
             {
                 if( verbose != 0 )
                     mbedtls_printf( "failed\n" );
-
-                return( 1 );
+                goto exit;
             }
         }
 
@@ -1131,7 +1129,11 @@
         mbedtls_printf( "\n" );
 #endif /* MBEDTLS_CIPHER_MODE_CTR */
 
-    return( 0 );
+    ret = 0;
+
+exit:
+    mbedtls_camellia_free( &ctx );
+    return( ret );
 }
 
 #endif /* MBEDTLS_SELF_TEST */
diff --git a/library/nist_kw.c b/library/nist_kw.c
index 8341ff1..278b7e9 100644
--- a/library/nist_kw.c
+++ b/library/nist_kw.c
@@ -219,8 +219,6 @@
     uint64_t t = 0;
     unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2];
     unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2];
-    unsigned char *R2 = output + KW_SEMIBLOCK_LENGTH;
-    unsigned char *A = output;
 
     *out_len = 0;
     /*
@@ -296,6 +294,9 @@
     }
     else
     {
+        unsigned char *R2 = output + KW_SEMIBLOCK_LENGTH;
+        unsigned char *A = output;
+
         /*
          * Do the wrapping function W, as defined in RFC 3394 section 2.2.1
          */
@@ -359,7 +360,7 @@
     uint64_t t = 0;
     unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2];
     unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2];
-    unsigned char *R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH;
+    unsigned char *R = NULL;
     *out_len = 0;
 
     if( semiblocks < MIN_SEMIBLOCKS_COUNT )
@@ -369,6 +370,7 @@
 
     memcpy( A, input, KW_SEMIBLOCK_LENGTH );
     memmove( output, input + KW_SEMIBLOCK_LENGTH, ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH );
+    R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH;
 
     /* Calculate intermediate values */
     for( t = s; t >= 1; t-- )
diff --git a/library/ssl_ciphersuites.c b/library/ssl_ciphersuites.c
index 090040e..01df17a 100644
--- a/library/ssl_ciphersuites.c
+++ b/library/ssl_ciphersuites.c
@@ -918,13 +918,13 @@
       0 },
 #endif /* MBEDTLS_SHA256_C */
 
-#if defined(MBEDTLS_SHA1_C)
+#if defined(MBEDTLS_SHA512_C)
     { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384",
       MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
-#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_SHA512_C */
 #endif /* MBEDTLS_GCM_C */
 #endif /* MBEDTLS_CAMELLIA_C */
 
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index a6c6297..1a0794a 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -6367,8 +6367,6 @@
 
 #if defined(MBEDTLS_SHA512_C)
 
-typedef int (*finish_sha384_t)(mbedtls_sha512_context*, unsigned char*);
-
 static void ssl_calc_finished_tls_sha384(
                 mbedtls_ssl_context *ssl, unsigned char *buf, int from )
 {
@@ -6376,12 +6374,6 @@
     const char *sender;
     mbedtls_sha512_context sha512;
     unsigned char padbuf[48];
-    /*
-     * For SHA-384, we can save 16 bytes by keeping padbuf 48 bytes long.
-     * However, to avoid stringop-overflow warning in gcc, we have to cast
-     * mbedtls_sha512_finish_ret().
-     */
-    finish_sha384_t finish_sha384 = (finish_sha384_t)mbedtls_sha512_finish_ret;
 
     mbedtls_ssl_session *session = ssl->session_negotiate;
     if( !session )
@@ -6407,8 +6399,19 @@
     sender = ( from == MBEDTLS_SSL_IS_CLIENT )
              ? "client finished"
              : "server finished";
-
-    finish_sha384( &sha512, padbuf );
+    /* mbedtls_sha512_finish_ret's output parameter is declared as a
+     * 64-byte buffer, but sice we're using SHA-384, we know that the
+     * output fits in 48 bytes. This is correct C, but GCC 11.1 warns
+     * about it.
+     */
+#if defined(__GNUC__) && __GNUC__ >= 11
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstringop-overflow"
+#endif
+    mbedtls_sha512_finish_ret( &sha512, padbuf );
+#if defined(__GNUC__) && __GNUC__ >= 11
+#pragma GCC diagnostic pop
+#endif
 
     ssl->handshake->tls_prf( session->master, 48, sender,
                              padbuf, 48, buf, len );
diff --git a/programs/test/udp_proxy.c b/programs/test/udp_proxy.c
index 66ead4a..b77994e 100644
--- a/programs/test/udp_proxy.c
+++ b/programs/test/udp_proxy.c
@@ -991,8 +991,8 @@
 
     for( delay_idx = 0; delay_idx < MAX_DELAYED_HS; delay_idx++ )
     {
-        mbedtls_free( opt.delay_cli + delay_idx );
-        mbedtls_free( opt.delay_srv + delay_idx );
+        mbedtls_free( opt.delay_cli[delay_idx] );
+        mbedtls_free( opt.delay_srv[delay_idx] );
     }
 
     mbedtls_net_free( &client_fd );
diff --git a/tests/compat.sh b/tests/compat.sh
index 8905430..f2598b7 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -932,10 +932,23 @@
     fi
 
     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"
+    O_SERVER_ARGS="-accept $PORT -cipher NULL,ALL -$MODE"
     G_SERVER_ARGS="-p $PORT --http $G_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"
 
+    # The default prime for `openssl s_server` depends on the version:
+    # * OpenSSL <= 1.0.2a: 512-bit
+    # * OpenSSL 1.0.2b to 1.1.1b: 1024-bit
+    # * OpenSSL >= 1.1.1c: 2048-bit
+    # Mbed TLS wants >=1024, so force that for older versions. Don't force
+    # it for newer versions, which reject a 1024-bit prime. Indifferently
+    # force it or not for intermediate versions.
+    case $($OPENSSL_CMD version) in
+        "OpenSSL 1.0"*)
+            O_SERVER_ARGS="$O_SERVER_ARGS -dhparam data_files/dhparams.pem"
+            ;;
+    esac
+
     # with OpenSSL 1.0.1h, -www, -WWW and -HTTP break DTLS handshakes
     if is_dtls "$MODE"; then
         O_SERVER_ARGS="$O_SERVER_ARGS"
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 0123521..439e2c3 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -952,7 +952,7 @@
 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 -dhparam data_files/dhparams.pem"
+O_SRV="$O_SRV -accept $SRV_PORT"
 O_CLI="$O_CLI -connect localhost:+SRV_PORT"
 G_SRV="$G_SRV -p $SRV_PORT"
 G_CLI="$G_CLI -p +SRV_PORT"
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index ceac670..ae207fd 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -160,6 +160,66 @@
        }                                                    \
     } while( 0 )
 
+/** Evaluate two 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.
+ */
+#define TEST_EQUAL( expr1, expr2 )              \
+    TEST_ASSERT( ( expr1 ) == ( expr2 ) )
+
+/** Allocate memory dynamically and fail the test case if this fails.
+ * The allocated memory will be filled with zeros.
+ *
+ * You must set \p pointer to \c NULL before calling this macro and
+ * put `mbedtls_free( pointer )` in the test's cleanup code.
+ *
+ * If \p length is zero, the resulting \p pointer will be \c NULL.
+ * This is usually what we want in tests since API functions are
+ * supposed to accept null pointers when a buffer size is zero.
+ *
+ * This macro expands to an instruction, not an expression.
+ * It may jump to the \c exit label.
+ *
+ * \param pointer   An lvalue where the address of the allocated buffer
+ *                  will be stored.
+ *                  This expression may be evaluated multiple times.
+ * \param length    Number of elements to allocate.
+ *                  This expression may be evaluated multiple times.
+ *
+ */
+#define ASSERT_ALLOC( pointer, length )                           \
+    do                                                            \
+    {                                                             \
+        TEST_ASSERT( ( pointer ) == NULL );                       \
+        if( ( length ) != 0 )                                     \
+        {                                                         \
+            ( pointer ) = mbedtls_calloc( sizeof( *( pointer ) ), \
+                                          ( length ) );           \
+            TEST_ASSERT( ( pointer ) != NULL );                   \
+        }                                                         \
+    }                                                             \
+    while( 0 )
+
+/** Allocate memory dynamically. If the allocation fails, skip the test case.
+ *
+ * This macro behaves like #ASSERT_ALLOC, except that if the allocation
+ * fails, it marks the test as skipped rather than failed.
+ */
+#define ASSERT_ALLOC_WEAK( pointer, length )                      \
+    do                                                            \
+    {                                                             \
+        TEST_ASSERT( ( pointer ) == NULL );                       \
+        if( ( length ) != 0 )                                     \
+        {                                                         \
+            ( pointer ) = mbedtls_calloc( sizeof( *( pointer ) ), \
+                                          ( length ) );           \
+            TEST_ASSUME( ( pointer ) != NULL );                   \
+        }                                                         \
+    }                                                             \
+    while( 0 )
 /** Compare two buffers and fail the test case if they differ.
  *
  * This macro expands to an instruction, not an expression.
diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function
index 3f8a945..781bb77 100644
--- a/tests/suites/host_test.function
+++ b/tests/suites/host_test.function
@@ -33,7 +33,7 @@
  *
  * \return      0 if success else 1
  */
-int verify_int( char *str, int *value )
+int verify_int( char *str, int32_t *value )
 {
     size_t i;
     int minus = 0;
@@ -238,7 +238,7 @@
  *
  * \return      0 for success else 1
  */
-static int convert_params( size_t cnt , char ** params , int * int_params_store )
+static int convert_params( size_t cnt , char ** params , int32_t * int_params_store )
 {
     char ** cur = params;
     char ** out = params;
@@ -400,7 +400,7 @@
     char buf[5000];
     char *params[50];
     /* Store for proccessed integer params. */
-    int int_params[50];
+    int32_t int_params[50];
     void *pointer;
 #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
     int stdout_fd = -1;
diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function
index 9c90e9c..3e901f7 100644
--- a/tests/suites/test_suite_ecp.function
+++ b/tests/suites/test_suite_ecp.function
@@ -1,6 +1,25 @@
 /* BEGIN_HEADER */
 #include "mbedtls/ecp.h"
 
+/* Backported from Mbed TLS 2.x for test dependencies. */
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+#define MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED
+#endif
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+#define MBEDTLS_ECP_MONTGOMERY_ENABLED
+#endif
+
 #define ECP_PF_UNKNOWN     -1
 
 #define ECP_PT_RESET( x )           \
diff --git a/tests/suites/test_suite_pkparse.data b/tests/suites/test_suite_pkparse.data
index cd842cf..d4a0e44 100644
--- a/tests/suites/test_suite_pkparse.data
+++ b/tests/suites/test_suite_pkparse.data
@@ -989,7 +989,7 @@
 pk_parse_public_keyfile_ec:"data_files/ec_bp512_pub.pem":0
 
 Parse EC Key #1 (SEC1 DER)
-depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP192R1_ENABLED
+depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP192R1_ENABLED
 pk_parse_keyfile_ec:"data_files/ec_prv.sec1.der":"NULL":0
 
 Parse EC Key #2 (SEC1 PEM)
@@ -1005,15 +1005,15 @@
 pk_parse_keyfile_ec:"data_files/ec_prv.pk8.der":"NULL":0
 
 Parse EC Key #4a (PKCS8 DER, no public key)
-depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
 pk_parse_keyfile_ec:"data_files/ec_prv.pk8nopub.der":"NULL":0
 
 Parse EC Key #4b (PKCS8 DER, no public key, with parameters)
-depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
 pk_parse_keyfile_ec:"data_files/ec_prv.pk8nopubparam.der":"NULL":0
 
 Parse EC Key #4c (PKCS8 DER, with parameters)
-depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
 pk_parse_keyfile_ec:"data_files/ec_prv.pk8param.der":"NULL":0
 
 Parse EC Key #5 (PKCS8 PEM)
@@ -1069,7 +1069,7 @@
 pk_parse_keyfile_ec:"data_files/ec_bp512_prv.pem":"NULL":0
 
 Parse EC Key #15 (SEC1 DER, secp256k1, SpecifiedECDomain)
-depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256K1_ENABLED:MBEDTLS_PK_PARSE_EC_EXTENDED
+depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256K1_ENABLED:MBEDTLS_PK_PARSE_EC_EXTENDED
 pk_parse_keyfile_ec:"data_files/ec_prv.specdom.der":"NULL":0
 
 Key ASN1 (No data)