Merge pull request #7803 from gilles-peskine-arm/psa-low-hash-mac-size

Start testing the PSA built-in drivers: hashes
diff --git a/.travis.yml b/.travis.yml
index 3a608f5..719654c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -32,6 +32,10 @@
           packages:
           - clang-10
           - gnutls-bin
+      env:
+        # Platform tests have an allocation that returns null
+        - ASAN_OPTIONS="allocator_may_return_null=1"
+        - MSAN_OPTIONS="allocator_may_return_null=1"
       script:
         # Do a manual build+test sequence rather than using all.sh,
         # because there's no all.sh component that does what we want,
@@ -89,6 +93,10 @@
         apt:
           packages:
           - gcc
+      env:
+        # Platform tests have an allocation that returns null
+        - ASAN_OPTIONS="allocator_may_return_null=1"
+        - MSAN_OPTIONS="allocator_may_return_null=1"
       script:
         # Do a manual build+test sequence rather than using all.sh.
         #
@@ -115,6 +123,10 @@
           packages:
           - clang
           - gnutls-bin
+      env:
+        # Platform tests have an allocation that returns null
+        - ASAN_OPTIONS="allocator_may_return_null=1"
+        - MSAN_OPTIONS="allocator_may_return_null=1"
       script:
         # Do a manual build+test sequence rather than using all.sh.
         #
diff --git a/ChangeLog.d/fix-a-few-unchecked-return.txt b/ChangeLog.d/fix-a-few-unchecked-return.txt
new file mode 100644
index 0000000..aadde36
--- /dev/null
+++ b/ChangeLog.d/fix-a-few-unchecked-return.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Fix some cases where mbedtls_mpi_mod_exp, RSA key construction or ECDSA
+     signature can silently return an incorrect result in low memory conditions.
diff --git a/ChangeLog.d/psa_crypto_user_config_file.txt b/ChangeLog.d/psa_crypto_user_config_file.txt
new file mode 100644
index 0000000..f538f47
--- /dev/null
+++ b/ChangeLog.d/psa_crypto_user_config_file.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Don't try to include MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE when
+     MBEDTLS_PSA_CRYPTO_CONFIG is disabled.
diff --git a/doxygen/mbedtls.doxyfile b/doxygen/mbedtls.doxyfile
index 8c7c7cc..7fd5dde 100644
--- a/doxygen/mbedtls.doxyfile
+++ b/doxygen/mbedtls.doxyfile
@@ -51,4 +51,5 @@
                          "MBEDTLS_CHECK_RETURN_TYPICAL="    \
                          "MBEDTLS_CHECK_RETURN_OPTIONAL="   \
                          "MBEDTLS_PRINTF_ATTRIBUTE(a,b)="   \
+                         "__DOXYGEN__"                      \
 
diff --git a/include/mbedtls/build_info.h b/include/mbedtls/build_info.h
index 985edd2..c0424da 100644
--- a/include/mbedtls/build_info.h
+++ b/include/mbedtls/build_info.h
@@ -59,6 +59,7 @@
 #define inline __inline
 #endif
 
+/* X.509, TLS and non-PSA crypto configuration */
 #if !defined(MBEDTLS_CONFIG_FILE)
 #include "mbedtls/mbedtls_config.h"
 #else
@@ -80,6 +81,18 @@
 #include MBEDTLS_USER_CONFIG_FILE
 #endif
 
+/* PSA crypto configuration */
+#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
+#if defined(MBEDTLS_PSA_CRYPTO_CONFIG_FILE)
+#include MBEDTLS_PSA_CRYPTO_CONFIG_FILE
+#else
+#include "psa/crypto_config.h"
+#endif
+#if defined(MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE)
+#include MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE
+#endif
+#endif /* defined(MBEDTLS_PSA_CRYPTO_CONFIG) */
+
 /* Auto-enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY if
  * MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH and MBEDTLS_CTR_DRBG_C defined
  * to ensure a 128-bit key size in CTR_DRBG.
diff --git a/include/mbedtls/config_psa.h b/include/mbedtls/config_psa.h
index 303758f..3b30c02 100644
--- a/include/mbedtls/config_psa.h
+++ b/include/mbedtls/config_psa.h
@@ -30,24 +30,8 @@
 #ifndef MBEDTLS_CONFIG_PSA_H
 #define MBEDTLS_CONFIG_PSA_H
 
-#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
-#if defined(MBEDTLS_PSA_CRYPTO_CONFIG_FILE)
-#include MBEDTLS_PSA_CRYPTO_CONFIG_FILE
-#else
-#include "psa/crypto_config.h"
-#endif
-#endif /* defined(MBEDTLS_PSA_CRYPTO_CONFIG) */
-
-#if defined(MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE)
-#include MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE
-#endif
-
 #include "psa/crypto_legacy.h"
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 
 
 /****************************************************************/
@@ -1074,8 +1058,4 @@
 #define PSA_WANT_KEY_TYPE_PASSWORD_HASH 1
 #define PSA_WANT_KEY_TYPE_RAW_DATA 1
 
-#ifdef __cplusplus
-}
-#endif
-
 #endif /* MBEDTLS_CONFIG_PSA_H */
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index 6ebda97..2a24a45 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -172,15 +172,47 @@
  * This allows different allocators (self-implemented or provided) to be
  * provided to the platform abstraction layer.
  *
- * Enabling MBEDTLS_PLATFORM_MEMORY without the
+ * Enabling #MBEDTLS_PLATFORM_MEMORY without the
  * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide
  * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and
  * free() function pointer at runtime.
  *
- * Enabling MBEDTLS_PLATFORM_MEMORY and specifying
+ * Enabling #MBEDTLS_PLATFORM_MEMORY and specifying
  * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the
  * alternate function at compile time.
  *
+ * An overview of how the value of mbedtls_calloc is determined:
+ *
+ * - if !MBEDTLS_PLATFORM_MEMORY
+ *     - mbedtls_calloc = calloc
+ * - if MBEDTLS_PLATFORM_MEMORY
+ *     - if (MBEDTLS_PLATFORM_CALLOC_MACRO && MBEDTLS_PLATFORM_FREE_MACRO):
+ *         - mbedtls_calloc = MBEDTLS_PLATFORM_CALLOC_MACRO
+ *     - if !(MBEDTLS_PLATFORM_CALLOC_MACRO && MBEDTLS_PLATFORM_FREE_MACRO):
+ *         - Dynamic setup via mbedtls_platform_set_calloc_free is now possible with a default value MBEDTLS_PLATFORM_STD_CALLOC.
+ *         - How is MBEDTLS_PLATFORM_STD_CALLOC handled?
+ *         - if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS:
+ *             - MBEDTLS_PLATFORM_STD_CALLOC is not set to anything;
+ *             - MBEDTLS_PLATFORM_STD_MEM_HDR can be included if present;
+ *         - if !MBEDTLS_PLATFORM_NO_STD_FUNCTIONS:
+ *             - if MBEDTLS_PLATFORM_STD_CALLOC is present:
+ *                 - User-defined MBEDTLS_PLATFORM_STD_CALLOC is respected;
+ *             - if !MBEDTLS_PLATFORM_STD_CALLOC:
+ *                 - MBEDTLS_PLATFORM_STD_CALLOC = calloc
+ *
+ *         - At this point the presence of MBEDTLS_PLATFORM_STD_CALLOC is checked.
+ *         - if !MBEDTLS_PLATFORM_STD_CALLOC
+ *             - MBEDTLS_PLATFORM_STD_CALLOC = uninitialized_calloc
+ *
+ *         - mbedtls_calloc = MBEDTLS_PLATFORM_STD_CALLOC.
+ *
+ * Defining MBEDTLS_PLATFORM_CALLOC_MACRO and #MBEDTLS_PLATFORM_STD_CALLOC at the same time is not possible.
+ * MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_FREE_MACRO must both be defined or undefined at the same time.
+ * #MBEDTLS_PLATFORM_STD_CALLOC and #MBEDTLS_PLATFORM_STD_FREE do not have to be defined at the same time, as, if they are used,
+ * dynamic setup of these functions is possible. See the tree above to see how are they handled in all cases.
+ * An uninitialized #MBEDTLS_PLATFORM_STD_CALLOC always fails, returning a null pointer.
+ * An uninitialized #MBEDTLS_PLATFORM_STD_FREE does not do anything.
+ *
  * Requires: MBEDTLS_PLATFORM_C
  *
  * Enable this layer to allow use of alternative memory allocators.
@@ -3708,8 +3740,29 @@
 
 /* Platform options */
 //#define MBEDTLS_PLATFORM_STD_MEM_HDR   <stdlib.h> /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */
-//#define MBEDTLS_PLATFORM_STD_CALLOC        calloc /**< Default allocator to use, can be undefined */
-//#define MBEDTLS_PLATFORM_STD_FREE            free /**< Default free to use, can be undefined */
+
+/** \def MBEDTLS_PLATFORM_STD_CALLOC
+ *
+ * Default allocator to use, can be undefined.
+ * It must initialize the allocated buffer memory to zeroes.
+ * The size of the buffer is the product of the two parameters.
+ * The calloc function returns either a null pointer or a pointer to the allocated space.
+ * If the product is 0, the function may either return NULL or a valid pointer to an array of size 0 which is a valid input to the deallocation function.
+ * An uninitialized #MBEDTLS_PLATFORM_STD_CALLOC always fails, returning a null pointer.
+ * See the description of #MBEDTLS_PLATFORM_MEMORY for more details.
+ * The corresponding deallocation function is #MBEDTLS_PLATFORM_STD_FREE.
+ */
+//#define MBEDTLS_PLATFORM_STD_CALLOC        calloc
+
+/** \def MBEDTLS_PLATFORM_STD_FREE
+ *
+ * Default free to use, can be undefined.
+ * NULL is a valid parameter, and the function must do nothing.
+ * A non-null parameter will always be a pointer previously returned by #MBEDTLS_PLATFORM_STD_CALLOC and not yet freed.
+ * An uninitialized #MBEDTLS_PLATFORM_STD_FREE does not do anything.
+ * See the description of #MBEDTLS_PLATFORM_MEMORY for more details (same principles as for MBEDTLS_PLATFORM_STD_CALLOC apply).
+ */
+//#define MBEDTLS_PLATFORM_STD_FREE            free
 //#define MBEDTLS_PLATFORM_STD_SETBUF      setbuf /**< Default setbuf to use, can be undefined */
 //#define MBEDTLS_PLATFORM_STD_EXIT            exit /**< Default exit to use, can be undefined */
 //#define MBEDTLS_PLATFORM_STD_TIME            time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
@@ -3723,10 +3776,10 @@
 //#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE  mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
 //#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE  "seedfile" /**< Seed file to read/write with default implementation */
 
-/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */
+/* To use the following function macros, MBEDTLS_PLATFORM_C must be enabled. */
 /* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */
-//#define MBEDTLS_PLATFORM_CALLOC_MACRO        calloc /**< Default allocator macro to use, can be undefined */
-//#define MBEDTLS_PLATFORM_FREE_MACRO            free /**< Default free macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_CALLOC_MACRO        calloc /**< Default allocator macro to use, can be undefined. See MBEDTLS_PLATFORM_STD_CALLOC for requirements. */
+//#define MBEDTLS_PLATFORM_FREE_MACRO            free /**< Default free macro to use, can be undefined. See MBEDTLS_PLATFORM_STD_FREE for requirements. */
 //#define MBEDTLS_PLATFORM_EXIT_MACRO            exit /**< Default exit macro to use, can be undefined */
 //#define MBEDTLS_PLATFORM_SETBUF_MACRO      setbuf /**< Default setbuf macro to use, can be undefined */
 //#define MBEDTLS_PLATFORM_TIME_MACRO            time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
diff --git a/include/mbedtls/net_sockets.h b/include/mbedtls/net_sockets.h
index 14316fb..1096d66 100644
--- a/include/mbedtls/net_sockets.h
+++ b/include/mbedtls/net_sockets.h
@@ -286,6 +286,10 @@
  * \brief          Closes down the connection and free associated data
  *
  * \param ctx      The context to close
+ *
+ * \note           This function frees and clears data associated with the
+ *                 context but does not free the memory pointed to by \p ctx.
+ *                 This memory is the responsibility of the caller.
  */
 void mbedtls_net_close(mbedtls_net_context *ctx);
 
@@ -293,6 +297,10 @@
  * \brief          Gracefully shutdown the connection and free associated data
  *
  * \param ctx      The context to free
+ *
+ * \note           This function frees and clears data associated with the
+ *                 context but does not free the memory pointed to by \p ctx.
+ *                 This memory is the responsibility of the caller.
  */
 void mbedtls_net_free(mbedtls_net_context *ctx);
 
diff --git a/include/mbedtls/platform.h b/include/mbedtls/platform.h
index 768c756..3fc1fd0 100644
--- a/include/mbedtls/platform.h
+++ b/include/mbedtls/platform.h
@@ -130,11 +130,22 @@
 #endif
 #endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
 
+/* Enable certain documented defines only when generating doxygen to avoid
+ * an "unrecognized define" error. */
+#if defined(__DOXYGEN__) && !defined(MBEDTLS_PLATFORM_STD_CALLOC)
+#define MBEDTLS_PLATFORM_STD_CALLOC
+#endif
+
+#if defined(__DOXYGEN__) && !defined(MBEDTLS_PLATFORM_STD_FREE)
+#define MBEDTLS_PLATFORM_STD_FREE
+#endif
 
 /** \} name SECTION: Module settings */
 
 /*
  * The function pointers for calloc and free.
+ * Please see MBEDTLS_PLATFORM_STD_CALLOC and MBEDTLS_PLATFORM_STD_FREE
+ * in mbedtls_config.h for more information about behaviour and requirements.
  */
 #if defined(MBEDTLS_PLATFORM_MEMORY)
 #if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \
diff --git a/include/psa/crypto_config.h b/include/psa/crypto_config.h
index af78dce..d8e8e19 100644
--- a/include/psa/crypto_config.h
+++ b/include/psa/crypto_config.h
@@ -92,7 +92,8 @@
 #define PSA_WANT_ALG_TLS12_PSK_TO_MS            1
 #define PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS       1
 
-/* Note: when adding support, also adjust include/mbedtls/config_psa.h */
+/* XTS is not yet supported via the PSA API in Mbed TLS.
+ * Note: when adding support, also adjust include/mbedtls/config_psa.h */
 //#define PSA_WANT_ALG_XTS                        1
 
 #define PSA_WANT_ECC_BRAINPOOL_P_R1_256         1
diff --git a/library/aes.c b/library/aes.c
index 774c2ee..47a5e3e 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -653,7 +653,7 @@
 #endif
 
 #if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
-    if (mbedtls_aesce_has_support()) {
+    if (MBEDTLS_AESCE_HAS_SUPPORT()) {
         return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
     }
 #endif
@@ -765,7 +765,7 @@
 #endif
 
 #if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
-    if (mbedtls_aesce_has_support()) {
+    if (MBEDTLS_AESCE_HAS_SUPPORT()) {
         mbedtls_aesce_inverse_key(
             (unsigned char *) RK,
             (const unsigned char *) (cty.buf + cty.rk_offset),
@@ -1092,7 +1092,7 @@
 #endif
 
 #if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
-    if (mbedtls_aesce_has_support()) {
+    if (MBEDTLS_AESCE_HAS_SUPPORT()) {
         return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
     }
 #endif
@@ -1911,7 +1911,7 @@
         } else
 #endif
 #if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
-        if (mbedtls_aesce_has_support()) {
+        if (MBEDTLS_AESCE_HAS_SUPPORT()) {
             mbedtls_printf("  AES note: using AESCE.\n");
         } else
 #endif
diff --git a/library/aesce.c b/library/aesce.c
index 8aa0789..6f75a67 100644
--- a/library/aesce.c
+++ b/library/aesce.c
@@ -94,28 +94,40 @@
 #endif /* !(__ARM_FEATURE_CRYPTO || __ARM_FEATURE_AES) ||
           MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG */
 
-#if defined(__linux__)
+#if defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
+
 #include <asm/hwcap.h>
 #include <sys/auxv.h>
-#endif
+
+signed char mbedtls_aesce_has_support_result = -1;
 
 #if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
 /*
  * AES instruction support detection routine
  */
-int mbedtls_aesce_has_support(void)
+int mbedtls_aesce_has_support_impl(void)
 {
-#if defined(__linux__)
-    unsigned long auxval = getauxval(AT_HWCAP);
-    return (auxval & (HWCAP_ASIMD | HWCAP_AES)) ==
-           (HWCAP_ASIMD | HWCAP_AES);
-#else
-    /* Assume AES instructions are supported. */
-    return 1;
-#endif
+    /* To avoid many calls to getauxval, cache the result. This is
+     * thread-safe, because we store the result in a char so cannot
+     * be vulnerable to non-atomic updates.
+     * It is possible that we could end up setting result more than
+     * once, but that is harmless.
+     */
+    if (mbedtls_aesce_has_support_result == -1) {
+        unsigned long auxval = getauxval(AT_HWCAP);
+        if ((auxval & (HWCAP_ASIMD | HWCAP_AES)) ==
+            (HWCAP_ASIMD | HWCAP_AES)) {
+            mbedtls_aesce_has_support_result = 1;
+        } else {
+            mbedtls_aesce_has_support_result = 0;
+        }
+    }
+    return mbedtls_aesce_has_support_result;
 }
 #endif
 
+#endif /* defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) */
+
 /* Single round of AESCE encryption */
 #define AESCE_ENCRYPT_ROUND                   \
     block = vaeseq_u8(block, vld1q_u8(keys)); \
diff --git a/library/aesce.h b/library/aesce.h
index 9b8b0bc..735c8cf 100644
--- a/library/aesce.h
+++ b/library/aesce.h
@@ -42,17 +42,29 @@
 extern "C" {
 #endif
 
+#if defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
+
+extern signed char mbedtls_aesce_has_support_result;
+
 /**
  * \brief          Internal function to detect the crypto extension in CPUs.
  *
  * \return         1 if CPU has support for the feature, 0 otherwise
  */
-#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
-int mbedtls_aesce_has_support(void);
-#else
-#define mbedtls_aesce_has_support() 1
-#endif
+int mbedtls_aesce_has_support_impl(void);
 
+#define MBEDTLS_AESCE_HAS_SUPPORT() (mbedtls_aesce_has_support_result == -1 ? \
+                                     mbedtls_aesce_has_support_impl() : \
+                                     mbedtls_aesce_has_support_result)
+
+#else /* defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) */
+
+/* If we are not on Linux, we can't detect support so assume that it's supported.
+ * Similarly, assume support if MBEDTLS_AES_USE_HARDWARE_ONLY is set.
+ */
+#define MBEDTLS_AESCE_HAS_SUPPORT() 1
+
+#endif /* defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) */
 
 /**
  * \brief          Internal AES-ECB block encryption and decryption
diff --git a/library/bignum.c b/library/bignum.c
index b1518ed..a08aa49 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -1826,8 +1826,9 @@
      * and squarings. Firstly, when multiplying by an element of the window
      * W[i], we do a constant-trace table lookup to obfuscate i. This leaves
      * squarings as having a different memory access patterns from other
-     * multiplications. So secondly, we put the accumulator X in the table as
-     * well, and also do a constant-trace table lookup to multiply by X.
+     * multiplications. So secondly, we put the accumulator in the table as
+     * well, and also do a constant-trace table lookup to multiply by the
+     * accumulator which is W[x_index].
      *
      * This way, all multiplications take the form of a lookup-and-multiply.
      * The number of lookup-and-multiply operations inside each iteration of
@@ -1840,19 +1841,16 @@
      * observe both memory accesses and branches. However, branch prediction
      * exploitation typically requires many traces of execution over the same
      * data, which is defeated by randomized blinding.
-     *
-     * To achieve this, we make a copy of X and we use the table entry in each
-     * calculation from this point on.
      */
     const size_t x_index = 0;
     mbedtls_mpi_init(&W[x_index]);
-    mbedtls_mpi_copy(&W[x_index], X);
 
     j = N->n + 1;
-    /* All W[i] and X must have at least N->n limbs for the mpi_montmul()
-     * and mpi_montred() calls later. Here we ensure that W[1] and X are
-     * large enough, and later we'll grow other W[i] to the same length.
-     * They must not be shrunk midway through this function!
+    /* All W[i] including the accumulator must have at least N->n limbs for
+     * the mpi_montmul() and mpi_montred() calls later. Here we ensure that
+     * W[1] and the accumulator W[x_index] are large enough. later we'll grow
+     * other W[i] to the same length. They must not be shrunk midway through
+     * this function!
      */
     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[x_index], j));
     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[1],  j));
@@ -2033,7 +2031,7 @@
     /*
      * Load the result in the output variable.
      */
-    mbedtls_mpi_copy(X, &W[x_index]);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, &W[x_index]));
 
 cleanup:
 
diff --git a/library/bignum_mod.c b/library/bignum_mod.c
index 4d67829..2f0e9ed 100644
--- a/library/bignum_mod.c
+++ b/library/bignum_mod.c
@@ -19,7 +19,7 @@
 
 #include "common.h"
 
-#if defined(MBEDTLS_BIGNUM_C)
+#if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_ECP_WITH_MPI_UINT)
 
 #include <string.h>
 
@@ -403,4 +403,4 @@
     return ret;
 }
 
-#endif /* MBEDTLS_BIGNUM_C */
+#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ECP_WITH_MPI_UINT */
diff --git a/library/bignum_mod_raw.c b/library/bignum_mod_raw.c
index 75cf8c4..5ee1b19 100644
--- a/library/bignum_mod_raw.c
+++ b/library/bignum_mod_raw.c
@@ -19,7 +19,7 @@
 
 #include "common.h"
 
-#if defined(MBEDTLS_BIGNUM_C)
+#if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_ECP_WITH_MPI_UINT)
 
 #include <string.h>
 
@@ -285,4 +285,4 @@
     (void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) borrow);
 }
 
-#endif /* MBEDTLS_BIGNUM_C */
+#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ECP_WITH_MPI_UINT */
diff --git a/library/ecdsa.c b/library/ecdsa.c
index 1faec16..6e55f22 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -373,7 +373,7 @@
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
     if (rs_ctx != NULL && rs_ctx->sig != NULL) {
-        mbedtls_mpi_copy(r, pr);
+        MBEDTLS_MPI_CHK(mbedtls_mpi_copy(r, pr));
     }
 #endif
 
@@ -447,7 +447,7 @@
     MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(d, data, grp_len));
     MBEDTLS_MPI_CHK(derive_mpi(grp, &h, buf, blen));
     MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&h, data + grp_len, grp_len));
-    mbedtls_hmac_drbg_seed_buf(p_rng, md_info, data, 2 * grp_len);
+    MBEDTLS_MPI_CHK(mbedtls_hmac_drbg_seed_buf(p_rng, md_info, data, 2 * grp_len));
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
     if (rs_ctx != NULL && rs_ctx->det != NULL) {
diff --git a/library/gcm.c b/library/gcm.c
index d49725c..786290f 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -98,7 +98,7 @@
 #endif
 
 #if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
-    if (mbedtls_aesce_has_support()) {
+    if (MBEDTLS_AESCE_HAS_SUPPORT()) {
         return 0;
     }
 #endif
@@ -209,7 +209,7 @@
 #endif /* MBEDTLS_AESNI_HAVE_CODE */
 
 #if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
-    if (mbedtls_aesce_has_support()) {
+    if (MBEDTLS_AESCE_HAS_SUPPORT()) {
         unsigned char h[16];
 
         /* mbedtls_aesce_gcm_mult needs big-endian input */
@@ -886,7 +886,7 @@
 #endif
 
 #if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
-        if (mbedtls_aesce_has_support()) {
+        if (MBEDTLS_AESCE_HAS_SUPPORT()) {
             mbedtls_printf("  GCM note: using AESCE.\n");
         } else
 #endif
diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c
index caba5a1..8de8569 100644
--- a/library/psa_crypto_pake.c
+++ b/library/psa_crypto_pake.c
@@ -178,12 +178,12 @@
         return status;
     }
 
-    psa_crypto_driver_pake_get_user_len(inputs, &user_len);
+    status = psa_crypto_driver_pake_get_user_len(inputs, &user_len);
     if (status != PSA_SUCCESS) {
         return status;
     }
 
-    psa_crypto_driver_pake_get_peer_len(inputs, &peer_len);
+    status = psa_crypto_driver_pake_get_peer_len(inputs, &peer_len);
     if (status != PSA_SUCCESS) {
         return status;
     }
diff --git a/library/rsa_alt_helpers.c b/library/rsa_alt_helpers.c
index 3451469..5cc4636 100644
--- a/library/rsa_alt_helpers.c
+++ b/library/rsa_alt_helpers.c
@@ -126,7 +126,7 @@
     }
 
     for (; attempt < num_primes; ++attempt) {
-        mbedtls_mpi_lset(&K, primes[attempt]);
+        MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&K, primes[attempt]));
 
         /* Check if gcd(K,N) = 1 */
         MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(P, &K, N));
diff --git a/programs/test/generate_cpp_dummy_build.sh b/programs/test/generate_cpp_dummy_build.sh
index 94e9115..2541683 100755
--- a/programs/test/generate_cpp_dummy_build.sh
+++ b/programs/test/generate_cpp_dummy_build.sh
@@ -63,6 +63,7 @@
     for header in include/mbedtls/*.h include/psa/*.h; do
         case ${header#include/} in
             mbedtls/mbedtls_config.h) :;; # not meant for direct inclusion
+            mbedtls/config_*.h) :;; # not meant for direct inclusion
             psa/crypto_config.h) :;; # not meant for direct inclusion
             # Some of the psa/crypto_*.h headers are not meant to be included
             # directly. They do have include guards that make them no-ops if
diff --git a/programs/test/selftest.c b/programs/test/selftest.c
index f896d4f..cc5e00e 100644
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -73,23 +73,51 @@
     void *empty2 = mbedtls_calloc(0, 1);
     void *buffer1 = mbedtls_calloc(1, 1);
     void *buffer2 = mbedtls_calloc(1, 1);
+    unsigned int buffer_3_size = 256;
+    unsigned int buffer_4_size = 4097; /* Allocate more than the usual page size */
+    unsigned char *buffer3 = mbedtls_calloc(buffer_3_size, 1);
+    unsigned char *buffer4 = mbedtls_calloc(buffer_4_size, 1);
 
     if (empty1 == NULL && empty2 == NULL) {
         if (verbose) {
-            mbedtls_printf("  CALLOC(0): passed (NULL)\n");
+            mbedtls_printf("  CALLOC(0,1): passed (NULL)\n");
         }
     } else if (empty1 == NULL || empty2 == NULL) {
         if (verbose) {
-            mbedtls_printf("  CALLOC(0): failed (mix of NULL and non-NULL)\n");
+            mbedtls_printf("  CALLOC(0,1): failed (mix of NULL and non-NULL)\n");
         }
         ++failures;
     } else if (empty1 == empty2) {
         if (verbose) {
-            mbedtls_printf("  CALLOC(0): passed (same non-null)\n");
+            mbedtls_printf("  CALLOC(0,1): passed (same non-null)\n");
         }
     } else {
         if (verbose) {
-            mbedtls_printf("  CALLOC(0): passed (distinct non-null)\n");
+            mbedtls_printf("  CALLOC(0,1): passed (distinct non-null)\n");
+        }
+    }
+
+    mbedtls_free(empty1);
+    mbedtls_free(empty2);
+
+    empty1 = mbedtls_calloc(1, 0);
+    empty2 = mbedtls_calloc(1, 0);
+    if (empty1 == NULL && empty2 == NULL) {
+        if (verbose) {
+            mbedtls_printf("  CALLOC(1,0): passed (NULL)\n");
+        }
+    } else if (empty1 == NULL || empty2 == NULL) {
+        if (verbose) {
+            mbedtls_printf("  CALLOC(1,0): failed (mix of NULL and non-NULL)\n");
+        }
+        ++failures;
+    } else if (empty1 == empty2) {
+        if (verbose) {
+            mbedtls_printf("  CALLOC(1,0): passed (same non-null)\n");
+        }
+    } else {
+        if (verbose) {
+            mbedtls_printf("  CALLOC(1,0): passed (distinct non-null)\n");
         }
     }
 
@@ -122,6 +150,28 @@
         }
     }
 
+    for (unsigned int i = 0; i < buffer_3_size; i++) {
+        if (buffer3[i] != 0) {
+            ++failures;
+            if (verbose) {
+                mbedtls_printf("  CALLOC(%u): failed (memory not initialized to 0)\n",
+                               buffer_3_size);
+            }
+            break;
+        }
+    }
+
+    for (unsigned int i = 0; i < buffer_4_size; i++) {
+        if (buffer4[i] != 0) {
+            ++failures;
+            if (verbose) {
+                mbedtls_printf("  CALLOC(%u): failed (memory not initialized to 0)\n",
+                               buffer_4_size);
+            }
+            break;
+        }
+    }
+
     if (verbose) {
         mbedtls_printf("\n");
     }
@@ -129,6 +179,8 @@
     mbedtls_free(empty2);
     mbedtls_free(buffer1);
     mbedtls_free(buffer2);
+    mbedtls_free(buffer3);
+    mbedtls_free(buffer4);
     return failures;
 }
 #endif /* MBEDTLS_SELF_TEST */
diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile
index a02ddd9..b5f0844 100644
--- a/tests/data_files/Makefile
+++ b/tests/data_files/Makefile
@@ -1590,7 +1590,7 @@
 	$(OPENSSL) x509 -inform PEM -in $< -outform DER -out $@
 server1.commas.crt: server1.key parse_input/server1.req.commas.sha256 $(test_ca_crt) $(test_ca_key_file_rsa)
 	$(MBEDTLS_CERT_WRITE) request_file=parse_input/server1.req.commas.sha256 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) version=1 not_before=20190210144406 not_after=20290210144406 md=SHA1 version=3 output_file=$@
-all_final += server1.crt server1.noauthid.crt server1.crt.der server1.commas.crt
+all_final += server1.crt server1.noauthid.crt parse_input/server1.crt.der server1.commas.crt
 
 parse_input/server1.key_usage.crt: parse_input/server1.req.sha256
 server1.key_usage.crt: server1.req.sha256
diff --git a/tests/include/test/drivers/config_test_driver.h b/tests/include/test/drivers/config_test_driver.h
index 2585fd9..81f9883 100644
--- a/tests/include/test/drivers/config_test_driver.h
+++ b/tests/include/test/drivers/config_test_driver.h
@@ -53,7 +53,4 @@
 //#define MBEDTLS_PEM_PARSE_C
 //#define MBEDTLS_BASE64_C
 
-#include "mbedtls/config_psa.h"
-#include "mbedtls/check_config.h"
-
 #endif /* MBEDTLS_CONFIG_H */
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 483e6f7..8e978ac 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -192,6 +192,10 @@
     # default to -O2, use -Ox _after_ this if you want another level
     ASAN_CFLAGS='-O2 -Werror -fsanitize=address,undefined -fno-sanitize-recover=all'
 
+    # Platform tests have an allocation that returns null
+    export ASAN_OPTIONS="allocator_may_return_null=1"
+    export MSAN_OPTIONS="allocator_may_return_null=1"
+
     # Gather the list of available components. These are the functions
     # defined in this script whose name starts with "component_".
     ALL_COMPONENTS=$(compgen -A function component_ | sed 's/component_//')
diff --git a/tests/src/bignum_helpers.c b/tests/src/bignum_helpers.c
index efb2eca..214530d 100644
--- a/tests/src/bignum_helpers.c
+++ b/tests/src/bignum_helpers.c
@@ -86,6 +86,7 @@
     return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
 }
 
+#if defined(MBEDTLS_ECP_WITH_MPI_UINT)
 int mbedtls_test_read_mpi_modulus(mbedtls_mpi_mod_modulus *N,
                                   const char *s,
                                   mbedtls_mpi_mod_rep_selector int_rep)
@@ -122,6 +123,7 @@
     mbedtls_free((mbedtls_mpi_uint *) N->p);
     mbedtls_mpi_mod_modulus_free(N);
 }
+#endif /* MBEDTLS_ECP_WITH_MPI_UINT */
 
 int mbedtls_test_read_mpi(mbedtls_mpi *X, const char *s)
 {
diff --git a/tests/suites/test_suite_bignum_mod.function b/tests/suites/test_suite_bignum_mod.function
index eaf2bd5..9d0fe93 100644
--- a/tests/suites/test_suite_bignum_mod.function
+++ b/tests/suites/test_suite_bignum_mod.function
@@ -35,7 +35,7 @@
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
- * depends_on:MBEDTLS_BIGNUM_C
+ * depends_on:MBEDTLS_BIGNUM_C:MBEDTLS_ECP_WITH_MPI_UINT
  * END_DEPENDENCIES
  */
 
diff --git a/tests/suites/test_suite_bignum_mod_raw.function b/tests/suites/test_suite_bignum_mod_raw.function
index 6b953f5..f7f8a59 100644
--- a/tests/suites/test_suite_bignum_mod_raw.function
+++ b/tests/suites/test_suite_bignum_mod_raw.function
@@ -11,7 +11,7 @@
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
- * depends_on:MBEDTLS_BIGNUM_C
+ * depends_on:MBEDTLS_BIGNUM_C:MBEDTLS_ECP_WITH_MPI_UINT
  * END_DEPENDENCIES
  */
 
diff --git a/tests/suites/test_suite_bignum_random.function b/tests/suites/test_suite_bignum_random.function
index 6e533bc..b43b1e7 100644
--- a/tests/suites/test_suite_bignum_random.function
+++ b/tests/suites/test_suite_bignum_random.function
@@ -192,7 +192,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_ECP_WITH_MPI_UINT */
 void mpi_mod_random_values(int min, char *max_hex, int rep)
 {
     /* Same RNG as in mpi_core_random_basic */
@@ -403,7 +403,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_ECP_WITH_MPI_UINT */
 void mpi_mod_random_validation(int min, char *bound_hex,
                                int result_limbs_delta,
                                int expected_ret)
diff --git a/tests/suites/test_suite_platform.data b/tests/suites/test_suite_platform.data
index 4276b8f..4d57450 100644
--- a/tests/suites/test_suite_platform.data
+++ b/tests/suites/test_suite_platform.data
@@ -4,3 +4,6 @@
 
 Time: get seconds
 time_get_seconds:
+
+Check mbedtls_calloc overallocation
+check_mbedtls_calloc_overallocation:SIZE_MAX/2:SIZE_MAX/2
diff --git a/tests/suites/test_suite_platform.function b/tests/suites/test_suite_platform.function
index 61681b8..c65d011 100644
--- a/tests/suites/test_suite_platform.function
+++ b/tests/suites/test_suite_platform.function
@@ -120,3 +120,17 @@
     goto exit;
 }
 /* END_CASE */
+
+/* BEGIN_CASE */
+void check_mbedtls_calloc_overallocation(intmax_t num, intmax_t size)
+{
+    unsigned char *buf;
+    buf = mbedtls_calloc((size_t) num, (size_t) size);
+    /* Dummy usage of the pointer to prevent optimizing it */
+    mbedtls_printf("calloc pointer : %p\n", buf);
+    TEST_ASSERT(buf == NULL);
+
+exit:
+    mbedtls_free(buf);
+}
+/* END_CASE */