Merge pull request #3925 from rodrigo-dc/mbedtls-2.16

Backport 2.16: Fix build failure on gcc-11
diff --git a/.gitignore b/.gitignore
index 789f57e..5fb0bde 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,4 +40,5 @@
 /GSYMS
 /GTAGS
 /TAGS
+/cscope*.out
 /tags
diff --git a/ChangeLog.d/aes-zeroize-pointer.txt b/ChangeLog.d/aes-zeroize-pointer.txt
new file mode 100644
index 0000000..ccc6dc1
--- /dev/null
+++ b/ChangeLog.d/aes-zeroize-pointer.txt
@@ -0,0 +1,5 @@
+Changes
+   * Remove the zeroization of a pointer variable in AES rounds. It was valid
+     but spurious and misleading since it looked like a mistaken attempt to
+     zeroize the pointed-to buffer. Reported by Antonio de la Piedra, CEA
+     Leti, France.
diff --git a/ChangeLog.d/arc4random_buf-implicit.txt b/ChangeLog.d/arc4random_buf-implicit.txt
new file mode 100644
index 0000000..d20e4c8
--- /dev/null
+++ b/ChangeLog.d/arc4random_buf-implicit.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Make arc4random_buf available on NetBSD and OpenBSD when _POSIX_C_SOURCE is
+     defined. Fix contributed in #3571. Adopted for LTS branch 2.16 in #3602.
diff --git a/ChangeLog.d/ecb_iv_fix.txt b/ChangeLog.d/ecb_iv_fix.txt
new file mode 100644
index 0000000..ae2ae25
--- /dev/null
+++ b/ChangeLog.d/ecb_iv_fix.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Correct the default IV size for mbedtls_cipher_info_t structures using
+     MBEDTLS_MODE_ECB to 0, since ECB mode ciphers don't use IVs.
diff --git a/Makefile b/Makefile
index 24d529a..3942fbd 100644
--- a/Makefile
+++ b/Makefile
@@ -129,5 +129,10 @@
 	$(CTAGS) $@ $(C_SOURCE_FILES)
 TAGS: $(C_SOURCE_FILES)
 	etags -o $@ $(C_SOURCE_FILES)
+global: GPATH GRTAGS GSYMS GTAGS
 GPATH GRTAGS GSYMS GTAGS: $(C_SOURCE_FILES)
 	ls $(C_SOURCE_FILES) | gtags -f - --gtagsconf .globalrc
+cscope: cscope.in.out cscope.po.out cscope.out
+cscope.in.out cscope.po.out cscope.out: $(C_SOURCE_FILES)
+	cscope -bq -u -Iinclude -Ilibrary $(patsubst %,-I%,$(wildcard 3rdparty/*/include)) -Itests/include $(C_SOURCE_FILES)
+.PHONY: cscope global
diff --git a/include/mbedtls/sha512.h b/include/mbedtls/sha512.h
index 9ff78ec..5e5a15e 100644
--- a/include/mbedtls/sha512.h
+++ b/include/mbedtls/sha512.h
@@ -152,8 +152,7 @@
 
 /**
  * \brief          This function finishes the SHA-512 operation, and writes
- *                 the result to the output buffer. This function is for
- *                 internal use only.
+ *                 the result to the output buffer.
  *
  * \param ctx      The SHA-512 context. This must be initialized
  *                 and have a hash operation started.
@@ -169,6 +168,7 @@
 /**
  * \brief          This function processes a single data block within
  *                 the ongoing SHA-512 computation.
+ *                 This function is for internal use only.
  *
  * \param ctx      The SHA-512 context. This must be initialized.
  * \param data     The buffer holding one block of data. This
diff --git a/library/aes.c b/library/aes.c
index 9b33750..da0e5b6 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -760,6 +760,7 @@
 
     return( ret );
 }
+#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
 
 #if defined(MBEDTLS_CIPHER_MODE_XTS)
 static int mbedtls_aes_xts_decode_keys( const unsigned char *key,
@@ -838,8 +839,6 @@
 }
 #endif /* MBEDTLS_CIPHER_MODE_XTS */
 
-#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
-
 #define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)                     \
     do                                                          \
     {                                                           \
@@ -897,63 +896,56 @@
                                   unsigned char output[16] )
 {
     int i;
-    uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+    uint32_t *RK = ctx->rk;
+    struct
+    {
+        uint32_t X[4];
+        uint32_t Y[4];
+    } t;
 
-    RK = ctx->rk;
-
-    GET_UINT32_LE( X0, input,  0 ); X0 ^= *RK++;
-    GET_UINT32_LE( X1, input,  4 ); X1 ^= *RK++;
-    GET_UINT32_LE( X2, input,  8 ); X2 ^= *RK++;
-    GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
+    GET_UINT32_LE( t.X[0], input,  0 ); t.X[0] ^= *RK++;
+    GET_UINT32_LE( t.X[1], input,  4 ); t.X[1] ^= *RK++;
+    GET_UINT32_LE( t.X[2], input,  8 ); t.X[2] ^= *RK++;
+    GET_UINT32_LE( t.X[3], input, 12 ); t.X[3] ^= *RK++;
 
     for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
     {
-        AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
-        AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
+        AES_FROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
+        AES_FROUND( t.X[0], t.X[1], t.X[2], t.X[3], t.Y[0], t.Y[1], t.Y[2], t.Y[3] );
     }
 
-    AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+    AES_FROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
 
-    X0 = *RK++ ^ \
-            ( (uint32_t) FSb[ ( Y0       ) & 0xFF ]       ) ^
-            ( (uint32_t) FSb[ ( Y1 >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
+    t.X[0] = *RK++ ^ \
+            ( (uint32_t) FSb[ ( t.Y[0]       ) & 0xFF ]       ) ^
+            ( (uint32_t) FSb[ ( t.Y[1] >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) FSb[ ( t.Y[2] >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) FSb[ ( t.Y[3] >> 24 ) & 0xFF ] << 24 );
 
-    X1 = *RK++ ^ \
-            ( (uint32_t) FSb[ ( Y1       ) & 0xFF ]       ) ^
-            ( (uint32_t) FSb[ ( Y2 >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
+    t.X[1] = *RK++ ^ \
+            ( (uint32_t) FSb[ ( t.Y[1]       ) & 0xFF ]       ) ^
+            ( (uint32_t) FSb[ ( t.Y[2] >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) FSb[ ( t.Y[3] >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) FSb[ ( t.Y[0] >> 24 ) & 0xFF ] << 24 );
 
-    X2 = *RK++ ^ \
-            ( (uint32_t) FSb[ ( Y2       ) & 0xFF ]       ) ^
-            ( (uint32_t) FSb[ ( Y3 >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
+    t.X[2] = *RK++ ^ \
+            ( (uint32_t) FSb[ ( t.Y[2]       ) & 0xFF ]       ) ^
+            ( (uint32_t) FSb[ ( t.Y[3] >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) FSb[ ( t.Y[0] >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) FSb[ ( t.Y[1] >> 24 ) & 0xFF ] << 24 );
 
-    X3 = *RK++ ^ \
-            ( (uint32_t) FSb[ ( Y3       ) & 0xFF ]       ) ^
-            ( (uint32_t) FSb[ ( Y0 >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
+    t.X[3] = *RK++ ^ \
+            ( (uint32_t) FSb[ ( t.Y[3]       ) & 0xFF ]       ) ^
+            ( (uint32_t) FSb[ ( t.Y[0] >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) FSb[ ( t.Y[1] >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) FSb[ ( t.Y[2] >> 24 ) & 0xFF ] << 24 );
 
-    PUT_UINT32_LE( X0, output,  0 );
-    PUT_UINT32_LE( X1, output,  4 );
-    PUT_UINT32_LE( X2, output,  8 );
-    PUT_UINT32_LE( X3, output, 12 );
+    PUT_UINT32_LE( t.X[0], output,  0 );
+    PUT_UINT32_LE( t.X[1], output,  4 );
+    PUT_UINT32_LE( t.X[2], output,  8 );
+    PUT_UINT32_LE( t.X[3], output, 12 );
 
-    mbedtls_platform_zeroize( &X0, sizeof( X0 ) );
-    mbedtls_platform_zeroize( &X1, sizeof( X1 ) );
-    mbedtls_platform_zeroize( &X2, sizeof( X2 ) );
-    mbedtls_platform_zeroize( &X3, sizeof( X3 ) );
-
-    mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) );
-    mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) );
-    mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) );
-    mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) );
-
-    mbedtls_platform_zeroize( &RK, sizeof( RK ) );
+    mbedtls_platform_zeroize( &t, sizeof( t ) );
 
     return( 0 );
 }
@@ -977,63 +969,56 @@
                                   unsigned char output[16] )
 {
     int i;
-    uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+    uint32_t *RK = ctx->rk;
+    struct
+    {
+        uint32_t X[4];
+        uint32_t Y[4];
+    } t;
 
-    RK = ctx->rk;
-
-    GET_UINT32_LE( X0, input,  0 ); X0 ^= *RK++;
-    GET_UINT32_LE( X1, input,  4 ); X1 ^= *RK++;
-    GET_UINT32_LE( X2, input,  8 ); X2 ^= *RK++;
-    GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
+    GET_UINT32_LE( t.X[0], input,  0 ); t.X[0] ^= *RK++;
+    GET_UINT32_LE( t.X[1], input,  4 ); t.X[1] ^= *RK++;
+    GET_UINT32_LE( t.X[2], input,  8 ); t.X[2] ^= *RK++;
+    GET_UINT32_LE( t.X[3], input, 12 ); t.X[3] ^= *RK++;
 
     for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
     {
-        AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
-        AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
+        AES_RROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
+        AES_RROUND( t.X[0], t.X[1], t.X[2], t.X[3], t.Y[0], t.Y[1], t.Y[2], t.Y[3] );
     }
 
-    AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+    AES_RROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
 
-    X0 = *RK++ ^ \
-            ( (uint32_t) RSb[ ( Y0       ) & 0xFF ]       ) ^
-            ( (uint32_t) RSb[ ( Y3 >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
+    t.X[0] = *RK++ ^ \
+            ( (uint32_t) RSb[ ( t.Y[0]       ) & 0xFF ]       ) ^
+            ( (uint32_t) RSb[ ( t.Y[3] >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) RSb[ ( t.Y[2] >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) RSb[ ( t.Y[1] >> 24 ) & 0xFF ] << 24 );
 
-    X1 = *RK++ ^ \
-            ( (uint32_t) RSb[ ( Y1       ) & 0xFF ]       ) ^
-            ( (uint32_t) RSb[ ( Y0 >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
+    t.X[1] = *RK++ ^ \
+            ( (uint32_t) RSb[ ( t.Y[1]       ) & 0xFF ]       ) ^
+            ( (uint32_t) RSb[ ( t.Y[0] >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) RSb[ ( t.Y[3] >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) RSb[ ( t.Y[2] >> 24 ) & 0xFF ] << 24 );
 
-    X2 = *RK++ ^ \
-            ( (uint32_t) RSb[ ( Y2       ) & 0xFF ]       ) ^
-            ( (uint32_t) RSb[ ( Y1 >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
+    t.X[2] = *RK++ ^ \
+            ( (uint32_t) RSb[ ( t.Y[2]       ) & 0xFF ]       ) ^
+            ( (uint32_t) RSb[ ( t.Y[1] >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) RSb[ ( t.Y[0] >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) RSb[ ( t.Y[3] >> 24 ) & 0xFF ] << 24 );
 
-    X3 = *RK++ ^ \
-            ( (uint32_t) RSb[ ( Y3       ) & 0xFF ]       ) ^
-            ( (uint32_t) RSb[ ( Y2 >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
+    t.X[3] = *RK++ ^ \
+            ( (uint32_t) RSb[ ( t.Y[3]       ) & 0xFF ]       ) ^
+            ( (uint32_t) RSb[ ( t.Y[2] >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) RSb[ ( t.Y[1] >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) RSb[ ( t.Y[0] >> 24 ) & 0xFF ] << 24 );
 
-    PUT_UINT32_LE( X0, output,  0 );
-    PUT_UINT32_LE( X1, output,  4 );
-    PUT_UINT32_LE( X2, output,  8 );
-    PUT_UINT32_LE( X3, output, 12 );
+    PUT_UINT32_LE( t.X[0], output,  0 );
+    PUT_UINT32_LE( t.X[1], output,  4 );
+    PUT_UINT32_LE( t.X[2], output,  8 );
+    PUT_UINT32_LE( t.X[3], output, 12 );
 
-    mbedtls_platform_zeroize( &X0, sizeof( X0 ) );
-    mbedtls_platform_zeroize( &X1, sizeof( X1 ) );
-    mbedtls_platform_zeroize( &X2, sizeof( X2 ) );
-    mbedtls_platform_zeroize( &X3, sizeof( X3 ) );
-
-    mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) );
-    mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) );
-    mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) );
-    mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) );
-
-    mbedtls_platform_zeroize( &RK, sizeof( RK ) );
+    mbedtls_platform_zeroize( &t, sizeof( t ) );
 
     return( 0 );
 }
diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c
index 1dcac21..5973ca6 100644
--- a/library/cipher_wrap.c
+++ b/library/cipher_wrap.c
@@ -779,7 +779,7 @@
     MBEDTLS_MODE_ECB,
     128,
     "CAMELLIA-128-ECB",
-    16,
+    0,
     0,
     16,
     &camellia_info
@@ -790,7 +790,7 @@
     MBEDTLS_MODE_ECB,
     192,
     "CAMELLIA-192-ECB",
-    16,
+    0,
     0,
     16,
     &camellia_info
@@ -801,7 +801,7 @@
     MBEDTLS_MODE_ECB,
     256,
     "CAMELLIA-256-ECB",
-    16,
+    0,
     0,
     16,
     &camellia_info
@@ -1155,7 +1155,7 @@
     MBEDTLS_MODE_ECB,
     128,
     "ARIA-128-ECB",
-    16,
+    0,
     0,
     16,
     &aria_info
@@ -1166,7 +1166,7 @@
     MBEDTLS_MODE_ECB,
     192,
     "ARIA-192-ECB",
-    16,
+    0,
     0,
     16,
     &aria_info
@@ -1177,7 +1177,7 @@
     MBEDTLS_MODE_ECB,
     256,
     "ARIA-256-ECB",
-    16,
+    0,
     0,
     16,
     &aria_info
@@ -1579,7 +1579,7 @@
     MBEDTLS_MODE_ECB,
     MBEDTLS_KEY_LENGTH_DES,
     "DES-ECB",
-    8,
+    0,
     0,
     8,
     &des_info
@@ -1630,7 +1630,7 @@
     MBEDTLS_MODE_ECB,
     MBEDTLS_KEY_LENGTH_DES_EDE,
     "DES-EDE-ECB",
-    8,
+    0,
     0,
     8,
     &des_ede_info
@@ -1681,7 +1681,7 @@
     MBEDTLS_MODE_ECB,
     MBEDTLS_KEY_LENGTH_DES_EDE3,
     "DES-EDE3-ECB",
-    8,
+    0,
     0,
     8,
     &des_ede3_info
@@ -1796,7 +1796,7 @@
     MBEDTLS_MODE_ECB,
     128,
     "BLOWFISH-ECB",
-    8,
+    0,
     MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
     8,
     &blowfish_info
diff --git a/library/error.c b/library/error.c
index eb52052..b83b8d1 100644
--- a/library/error.c
+++ b/library/error.c
@@ -51,20 +51,19 @@
 #endif
 
 #if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
+
 #include "mbedtls/error.h"
-#include <string.h>
-#endif
+
+#if defined(MBEDTLS_ERROR_C)
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
 #define mbedtls_snprintf snprintf
-#define mbedtls_time_t   time_t
 #endif
 
-#if defined(MBEDTLS_ERROR_C)
-
 #include <stdio.h>
+#include <string.h>
 
 #if defined(MBEDTLS_AES_C)
 #include "mbedtls/aes.h"
@@ -929,8 +928,6 @@
 
 #else /* MBEDTLS_ERROR_C */
 
-#if defined(MBEDTLS_ERROR_STRERROR_DUMMY)
-
 /*
  * Provide an non-function in case MBEDTLS_ERROR_C is not defined
  */
@@ -942,6 +939,6 @@
         buf[0] = '\0';
 }
 
-#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */
-
 #endif /* MBEDTLS_ERROR_C */
+
+#endif /* MBEDTLS_ERROR_C || MBEDTLS_ERROR_STRERROR_DUMMY */
diff --git a/library/platform_util.c b/library/platform_util.c
index 3ba2aea..c8cd52d 100644
--- a/library/platform_util.c
+++ b/library/platform_util.c
@@ -115,7 +115,7 @@
 
 #if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) ||     \
        ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) &&                     \
-         _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) )
+         _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) )
 /*
  * This is a convenience shorthand macro to avoid checking the long
  * preprocessor conditions above. Ideally, we could expose this macro in
@@ -129,7 +129,7 @@
 
 #endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) ||     \
              ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) &&                     \
-                _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */
+                _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) ) */
 
 struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
                                       struct tm *tm_buf )
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 97b7784..cbf6142 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -3587,11 +3587,12 @@
     /* In case of a failure in decryption, the decryption may write less than
      * 2 bytes of output, but we always read the first two bytes. It doesn't
      * matter in the end because diff will be nonzero in that case due to
-     * peer_pmslen being less than 48, and we only care whether diff is 0.
-     * But do initialize peer_pms for robustness anyway. This also makes
-     * memory analyzers happy (don't access uninitialized memory, even
-     * if it's an unsigned char). */
+     * ret being nonzero, and we only care whether diff is 0.
+     * But do initialize peer_pms and peer_pmslen for robustness anyway. This
+     * also makes memory analyzers happy (don't access uninitialized memory,
+     * even if it's an unsigned char). */
     peer_pms[0] = peer_pms[1] = ~0;
+    peer_pmslen = 0;
 
     ret = ssl_decrypt_encrypted_pms( ssl, p, end,
                                      peer_pms,
diff --git a/library/threading.c b/library/threading.c
index 61c4b94..f4f29cf 100644
--- a/library/threading.c
+++ b/library/threading.c
@@ -73,7 +73,7 @@
 
 #if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) ||     \
        ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) &&                     \
-         _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) )
+         _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) )
 /*
  * This is a convenience shorthand macro to avoid checking the long
  * preprocessor conditions above. Ideally, we could expose this macro in
@@ -88,7 +88,7 @@
 
 #endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) ||     \
              ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) &&                     \
-                _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */
+                _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) ) */
 
 #endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */
 
diff --git a/programs/ssl/CMakeLists.txt b/programs/ssl/CMakeLists.txt
index b3ef4f8..094543b 100644
--- a/programs/ssl/CMakeLists.txt
+++ b/programs/ssl/CMakeLists.txt
@@ -37,8 +37,8 @@
 add_executable(ssl_client1 ssl_client1.c)
 target_link_libraries(ssl_client1 ${libs})
 
-add_executable(ssl_client2 ssl_client2.c)
-target_sources(ssl_client2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/query_config.c)
+add_executable(ssl_client2 ssl_client2.c
+               ${CMAKE_CURRENT_SOURCE_DIR}/query_config.c)
 target_link_libraries(ssl_client2 ${libs})
 
 add_executable(ssl_fork_server ssl_fork_server.c)
@@ -50,8 +50,8 @@
 add_executable(ssl_server ssl_server.c)
 target_link_libraries(ssl_server ${libs})
 
-add_executable(ssl_server2 ssl_server2.c)
-target_sources(ssl_server2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/query_config.c)
+add_executable(ssl_server2 ssl_server2.c
+               ${CMAKE_CURRENT_SOURCE_DIR}/query_config.c)
 target_link_libraries(ssl_server2 ${libs})
 
 if(THREADS_FOUND)
diff --git a/programs/test/CMakeLists.txt b/programs/test/CMakeLists.txt
index 5feb317..a74db1e 100644
--- a/programs/test/CMakeLists.txt
+++ b/programs/test/CMakeLists.txt
@@ -27,8 +27,8 @@
 add_executable(zeroize zeroize.c)
 target_link_libraries(zeroize ${libs})
 
-add_executable(query_compile_time_config query_compile_time_config.c)
-target_sources(query_compile_time_config PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../ssl/query_config.c)
+add_executable(query_compile_time_config query_compile_time_config.c
+               ${CMAKE_CURRENT_SOURCE_DIR}/../ssl/query_config.c)
 target_link_libraries(query_compile_time_config ${libs})
 
 install(TARGETS selftest benchmark udp_proxy query_compile_time_config
diff --git a/scripts/data_files/error.fmt b/scripts/data_files/error.fmt
index 162d93b..c5c8707 100644
--- a/scripts/data_files/error.fmt
+++ b/scripts/data_files/error.fmt
@@ -51,20 +51,19 @@
 #endif
 
 #if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
+
 #include "mbedtls/error.h"
-#include <string.h>
-#endif
+
+#if defined(MBEDTLS_ERROR_C)
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
 #define mbedtls_snprintf snprintf
-#define mbedtls_time_t   time_t
 #endif
 
-#if defined(MBEDTLS_ERROR_C)
-
 #include <stdio.h>
+#include <string.h>
 
 HEADER_INCLUDED
 
@@ -130,8 +129,6 @@
 
 #else /* MBEDTLS_ERROR_C */
 
-#if defined(MBEDTLS_ERROR_STRERROR_DUMMY)
-
 /*
  * Provide an non-function in case MBEDTLS_ERROR_C is not defined
  */
@@ -143,6 +140,6 @@
         buf[0] = '\0';
 }
 
-#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */
-
 #endif /* MBEDTLS_ERROR_C */
+
+#endif /* MBEDTLS_ERROR_C || MBEDTLS_ERROR_STRERROR_DUMMY */
diff --git a/tests/compat.sh b/tests/compat.sh
index 7796bd2..8905430 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -117,12 +117,12 @@
 print_usage() {
     echo "Usage: $0"
     printf "  -h|--help\tPrint this help.\n"
-    printf "  -f|--filter\tOnly matching ciphersuites are tested (Default: '$FILTER')\n"
-    printf "  -e|--exclude\tMatching ciphersuites are excluded (Default: '$EXCLUDE')\n"
-    printf "  -m|--modes\tWhich modes to perform (Default: '$MODES')\n"
-    printf "  -t|--types\tWhich key exchange type to perform (Default: '$TYPES')\n"
-    printf "  -V|--verify\tWhich verification modes to perform (Default: '$VERIFIES')\n"
-    printf "  -p|--peers\tWhich peers to use (Default: '$PEERS')\n"
+    printf "  -f|--filter\tOnly matching ciphersuites are tested (Default: '%s')\n" "$FILTER"
+    printf "  -e|--exclude\tMatching ciphersuites are excluded (Default: '%s')\n" "$EXCLUDE"
+    printf "  -m|--modes\tWhich modes to perform (Default: '%s')\n" "$MODES"
+    printf "  -t|--types\tWhich key exchange type to perform (Default: '%s')\n" "$TYPES"
+    printf "  -V|--verify\tWhich verification modes to perform (Default: '%s')\n" "$VERIFIES"
+    printf "  -p|--peers\tWhich peers to use (Default: '%s')\n" "$PEERS"
     printf "            \tAlso available: GnuTLS (needs v3.2.15 or higher)\n"
     printf "  -M|--memcheck\tCheck memory leaks and errors.\n"
     printf "  -v|--verbose\tSet verbose output.\n"
@@ -1134,7 +1134,7 @@
     VERIF=$(echo $VERIFY | tr '[:upper:]' '[:lower:]')
     TITLE="`echo $1 | head -c1`->`echo $SERVER_NAME | head -c1`"
     TITLE="$TITLE $MODE,$VERIF $2"
-    printf "$TITLE "
+    printf "%s " "$TITLE"
     LEN=$(( 72 - `echo "$TITLE" | wc -c` ))
     for i in `seq 1 $LEN`; do printf '.'; done; printf ' '
 
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 07ff62d..a2a26b4 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1501,6 +1501,20 @@
     make test
 }
 
+component_test_no_strings () {
+    msg "build: no strings" # ~10s
+    scripts/config.pl full
+    # Disable options that activate a large amount of string constants.
+    scripts/config.pl unset MBEDTLS_DEBUG_C
+    scripts/config.pl unset MBEDTLS_ERROR_C
+    scripts/config.pl set MBEDTLS_ERROR_STRERROR_DUMMY
+    scripts/config.pl unset MBEDTLS_VERSION_FEATURES
+    make CFLAGS='-Werror -Os'
+
+    msg "test: no strings" # ~ 10s
+    make test
+}
+
 component_build_arm_none_eabi_gcc () {
     msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -O1" # ~ 10s
     scripts/config.pl baremetal
diff --git a/tests/scripts/check-names.sh b/tests/scripts/check-names.sh
index 5f3b5a7..7c979bc 100755
--- a/tests/scripts/check-names.sh
+++ b/tests/scripts/check-names.sh
@@ -92,7 +92,7 @@
 diff macros identifiers | sed -n -e 's/< //p' > actual-macros
 
 for THING in actual-macros enum-consts; do
-    printf "Names of $THING: "
+    printf 'Names of %s: ' "$THING"
     test -r $THING
     BAD=$( grep -v '^MBEDTLS_[0-9A-Z_]*[0-9A-Z]$' $THING || true )
     if [ "x$BAD" = "x" ]; then
@@ -105,7 +105,7 @@
 done
 
 for THING in identifiers; do
-    printf "Names of $THING: "
+    printf 'Names of %s: ' "$THING"
     test -r $THING
     BAD=$( grep -v '^mbedtls_[0-9a-z_]*[0-9a-z]$' $THING || true )
     if [ "x$BAD" = "x" ]; then
diff --git a/tests/scripts/test-ref-configs.pl b/tests/scripts/test-ref-configs.pl
index a8bfa6e..94fc335 100755
--- a/tests/scripts/test-ref-configs.pl
+++ b/tests/scripts/test-ref-configs.pl
@@ -55,15 +55,17 @@
 use strict;
 
 my %configs = (
+    'config-ccm-psk-tls1_2.h' => {
+        'compat' => '-m tls1_2 -f \'^TLS-PSK-WITH-AES-...-CCM-8\'',
+    },
     'config-mini-tls1_1.h' => {
         'compat' => '-m tls1_1 -f \'^DES-CBC3-SHA$\|^TLS-RSA-WITH-3DES-EDE-CBC-SHA$\'',
     },
+    'config-no-entropy.h' => {
+    },
     'config-suite-b.h' => {
         'compat' => "-m tls1_2 -f 'ECDHE-ECDSA.*AES.*GCM' -p mbedTLS",
     },
-    'config-ccm-psk-tls1_2.h' => {
-        'compat' => '-m tls1_2 -f \'^TLS-PSK-WITH-AES-...-CCM-8\'',
-    },
     'config-thread.h' => {
         'opt' => '-f ECJPAKE.*nolog',
     },
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index af6b0af..b9652ef 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -130,8 +130,8 @@
     echo "Usage: $0 [options]"
     printf "  -h|--help\tPrint this help.\n"
     printf "  -m|--memcheck\tCheck memory leaks and errors.\n"
-    printf "  -f|--filter\tOnly matching tests are executed (BRE; default: '$FILTER')\n"
-    printf "  -e|--exclude\tMatching tests are excluded (BRE; default: '$EXCLUDE')\n"
+    printf "  -f|--filter\tOnly matching tests are executed (BRE)\n"
+    printf "  -e|--exclude\tMatching tests are excluded (BRE)\n"
     printf "  -n|--number\tExecute only numbered test (comma-separated, e.g. '245,256')\n"
     printf "  -s|--show-numbers\tShow test numbers in front of test names\n"
     printf "  -p|--preserve-logs\tPreserve logs of successful tests as well\n"
@@ -384,7 +384,7 @@
     fi
 
     LINE="$LINE$1"
-    printf "$LINE "
+    printf "%s " "$LINE"
     LEN=$(( 72 - `echo "$LINE" | wc -c` ))
     for i in `seq 1 $LEN`; do printf '.'; done
     printf ' '
@@ -662,12 +662,12 @@
         fi
 
         check_osrv_dtls
-        printf "# $NAME\n$SRV_CMD\n" > $SRV_OUT
+        printf '# %s\n%s\n' "$NAME" "$SRV_CMD" > $SRV_OUT
         provide_input | $SRV_CMD >> $SRV_OUT 2>&1 &
         SRV_PID=$!
         wait_server_start "$SRV_PORT" "$SRV_PID"
 
-        printf "# $NAME\n$CLI_CMD\n" > $CLI_OUT
+        printf '# %s\n%s\n' "$NAME" "$CLI_CMD" > $CLI_OUT
         eval "$CLI_CMD" >> $CLI_OUT 2>&1 &
         wait_client_done
 
@@ -1877,12 +1877,12 @@
 # Tests for Max Fragment Length extension
 
 if [ "$MAX_CONTENT_LEN" -lt "4096" ]; then
-    printf "${CONFIG_H} defines MBEDTLS_SSL_MAX_CONTENT_LEN to be less than 4096. Fragment length tests will fail.\n"
+    printf '%s defines MBEDTLS_SSL_MAX_CONTENT_LEN to be less than 4096. Fragment length tests will fail.\n' "${CONFIG_H}"
     exit 1
 fi
 
 if [ $MAX_CONTENT_LEN -ne 16384 ]; then
-    printf "Using non-default maximum content length $MAX_CONTENT_LEN\n"
+    echo "Using non-default maximum content length $MAX_CONTENT_LEN"
 fi
 
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
@@ -2823,14 +2823,14 @@
 MAX_IM_CA_CONFIG=$( ../scripts/config.pl get MBEDTLS_X509_MAX_INTERMEDIATE_CA)
 
 if [ -n "$MAX_IM_CA_CONFIG" ] && [ "$MAX_IM_CA_CONFIG" -ne "$MAX_IM_CA" ]; then
-    printf "The ${CONFIG_H} file contains a value for the configuration of\n"
-    printf "MBEDTLS_X509_MAX_INTERMEDIATE_CA that is different from the script’s\n"
-    printf "test value of ${MAX_IM_CA}. \n"
-    printf "\n"
-    printf "The tests assume this value and if it changes, the tests in this\n"
-    printf "script should also be adjusted.\n"
-    printf "\n"
+    cat <<EOF
+${CONFIG_H} contains a value for the configuration of
+MBEDTLS_X509_MAX_INTERMEDIATE_CA that is different from the script's
+test value of ${MAX_IM_CA}.
 
+The tests assume this value and if it changes, the tests in this
+script should also be adjusted.
+EOF
     exit 1
 fi
 
diff --git a/tests/suites/main_test.function b/tests/suites/main_test.function
index f516d2c..9f36690 100644
--- a/tests/suites/main_test.function
+++ b/tests/suites/main_test.function
@@ -23,6 +23,15 @@
 #endif
 #endif
 
+/*
+ * for arc4random_buf() from <stdlib.h>
+ */
+#if defined(__NetBSD__)
+#define _NETBSD_SOURCE 1
+#elif defined(__OpenBSD__)
+#define _BSD_SOURCE 1
+#endif
+
 #if !defined(MBEDTLS_CONFIG_FILE)
 #include <mbedtls/config.h>
 #else