Merge remote-tracking branch 'origin/pr/2325' into mbedtls-2.16
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 3433ed0..010dffc 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -56,9 +56,9 @@
 
 Currently maintained LTS branches are:
 
-1. [mbedtls-2.1](https://github.com/ARMmbed/mbedtls/tree/mbedtls-2.1)
+1. [mbedtls-2.7](https://github.com/ARMmbed/mbedtls/tree/mbedtls-2.7)
 
-2. [mbedtls-2.7](https://github.com/ARMmbed/mbedtls/tree/mbedtls-2.7)
+1. [mbedtls-2.16](https://github.com/ARMmbed/mbedtls/tree/mbedtls-2.16)
 
 
 Tests
diff --git a/ChangeLog b/ChangeLog
index be28645..8310985 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,26 @@
 mbed TLS ChangeLog (Sorted per branch, date)
 
+= mbed TLS 2.x.x branch released xxxx-xx-xx
+
+Bugfix
+   * Fix a compilation issue with mbedtls_ecp_restart_ctx not being defined
+     when MBEDTLS_ECP_ALT is defined. Reported by jwhui. Fixes #2242.
+   * Run the AD too long test only if MBEDTLS_CCM_ALT is not defined.
+     Raised as a comment in #1996.
+   * Reduce the stack consumption of mbedtls_mpi_fill_random() which could
+     previously lead to a stack overflow on constrained targets.
+   * Add `MBEDTLS_SELF_TEST` for the mbedtls_self_test functions
+     in the header files, which missed the precompilation check. #971
+   * Fix clobber list in MIPS assembly for large integer multiplication.
+     Previously, this could lead to functionally incorrect assembly being
+     produced by some optimizing compilers, showing up as failures in
+     e.g. RSA or ECC signature operations. Reported in #1722, fix suggested
+     by Aurelien Jarno and submitted by Jeffrey Martin.
+   * Fix signed-to-unsigned integer conversion warning
+     in X.509 module. Fixes #2212.
+   * Reduce stack usage of `mpi_write_hlp()` by eliminating recursion.
+     Fixes #2190.
+
 = mbed TLS 2.16.0 branch released 2018-12-21
 
 Features
diff --git a/include/mbedtls/aes.h b/include/mbedtls/aes.h
index b42e564..94e7282 100644
--- a/include/mbedtls/aes.h
+++ b/include/mbedtls/aes.h
@@ -655,6 +655,8 @@
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
+
+#if defined(MBEDTLS_SELF_TEST)
 /**
  * \brief          Checkup routine.
  *
@@ -663,6 +665,8 @@
  */
 int mbedtls_aes_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/arc4.h b/include/mbedtls/arc4.h
index c43f406..fb044d5 100644
--- a/include/mbedtls/arc4.h
+++ b/include/mbedtls/arc4.h
@@ -123,6 +123,8 @@
 int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input,
                 unsigned char *output );
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          Checkup routine
  *
@@ -135,6 +137,8 @@
  */
 int mbedtls_arc4_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/base64.h b/include/mbedtls/base64.h
index 7a64f52..9af1149 100644
--- a/include/mbedtls/base64.h
+++ b/include/mbedtls/base64.h
@@ -75,6 +75,7 @@
 int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
                    const unsigned char *src, size_t slen );
 
+#if defined(MBEDTLS_SELF_TEST)
 /**
  * \brief          Checkup routine
  *
@@ -82,6 +83,8 @@
  */
 int mbedtls_base64_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h
index 141a8e9..a54c18e 100644
--- a/include/mbedtls/bignum.h
+++ b/include/mbedtls/bignum.h
@@ -943,6 +943,8 @@
                    int (*f_rng)(void *, unsigned char *, size_t),
                    void *p_rng );
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          Checkup routine
  *
@@ -950,6 +952,8 @@
  */
 int mbedtls_mpi_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/bn_mul.h b/include/mbedtls/bn_mul.h
index 2f7b72f..26cfa77 100644
--- a/include/mbedtls/bn_mul.h
+++ b/include/mbedtls/bn_mul.h
@@ -750,7 +750,7 @@
         "sw     $10, %2         \n\t"   \
         : "=m" (c), "=m" (d), "=m" (s)                      \
         : "m" (s), "m" (d), "m" (c), "m" (b)                \
-        : "$9", "$10", "$11", "$12", "$13", "$14", "$15"    \
+        : "$9", "$10", "$11", "$12", "$13", "$14", "$15", "lo", "hi" \
     );
 
 #endif /* MIPS */
diff --git a/include/mbedtls/camellia.h b/include/mbedtls/camellia.h
index 0f7c42c..3eeb663 100644
--- a/include/mbedtls/camellia.h
+++ b/include/mbedtls/camellia.h
@@ -308,6 +308,8 @@
                        unsigned char *output );
 #endif /* MBEDTLS_CIPHER_MODE_CTR */
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          Checkup routine
  *
@@ -315,6 +317,8 @@
  */
 int mbedtls_camellia_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h
index 10f9389..752c08e 100644
--- a/include/mbedtls/ctr_drbg.h
+++ b/include/mbedtls/ctr_drbg.h
@@ -350,6 +350,8 @@
 int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
 #endif /* MBEDTLS_FS_IO */
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief               The CTR_DRBG checkup routine.
  *
@@ -358,6 +360,8 @@
  */
 int mbedtls_ctr_drbg_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 /* Internal functions (do not call directly) */
 int mbedtls_ctr_drbg_seed_entropy_len( mbedtls_ctr_drbg_context *,
                                int (*)(void *, unsigned char *, size_t), void *,
diff --git a/include/mbedtls/des.h b/include/mbedtls/des.h
index d62042d..54e6b78 100644
--- a/include/mbedtls/des.h
+++ b/include/mbedtls/des.h
@@ -338,6 +338,8 @@
 void mbedtls_des_setkey( uint32_t SK[32],
                          const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          Checkup routine
  *
@@ -345,6 +347,8 @@
  */
 int mbedtls_des_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/dhm.h b/include/mbedtls/dhm.h
index a5452c1..2909f5f 100644
--- a/include/mbedtls/dhm.h
+++ b/include/mbedtls/dhm.h
@@ -334,6 +334,8 @@
 #endif /* MBEDTLS_FS_IO */
 #endif /* MBEDTLS_ASN1_PARSE_C */
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          The DMH checkup routine.
  *
@@ -342,6 +344,7 @@
  */
 int mbedtls_dhm_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index de3a343..1a96426 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -189,6 +189,68 @@
 }
 mbedtls_ecp_group;
 
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h, or define them using the compiler command line.
+ * \{
+ */
+
+#if !defined(MBEDTLS_ECP_MAX_BITS)
+/**
+ * The maximum size of the groups, that is, of \c N and \c P.
+ */
+#define MBEDTLS_ECP_MAX_BITS     521   /**< The maximum size of groups, in bits. */
+#endif
+
+#define MBEDTLS_ECP_MAX_BYTES    ( ( MBEDTLS_ECP_MAX_BITS + 7 ) / 8 )
+#define MBEDTLS_ECP_MAX_PT_LEN   ( 2 * MBEDTLS_ECP_MAX_BYTES + 1 )
+
+#if !defined(MBEDTLS_ECP_WINDOW_SIZE)
+/*
+ * Maximum "window" size used for point multiplication.
+ * Default: 6.
+ * Minimum value: 2. Maximum value: 7.
+ *
+ * Result is an array of at most ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) )
+ * points used for point multiplication. This value is directly tied to EC
+ * peak memory usage, so decreasing it by one should roughly cut memory usage
+ * by two (if large curves are in use).
+ *
+ * Reduction in size may reduce speed, but larger curves are impacted first.
+ * Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1):
+ *      w-size:     6       5       4       3       2
+ *      521       145     141     135     120      97
+ *      384       214     209     198     177     146
+ *      256       320     320     303     262     226
+ *      224       475     475     453     398     342
+ *      192       640     640     633     587     476
+ */
+#define MBEDTLS_ECP_WINDOW_SIZE    6   /**< The maximum window size used. */
+#endif /* MBEDTLS_ECP_WINDOW_SIZE */
+
+#if !defined(MBEDTLS_ECP_FIXED_POINT_OPTIM)
+/*
+ * Trade memory for speed on fixed-point multiplication.
+ *
+ * This speeds up repeated multiplication of the generator (that is, the
+ * multiplication in ECDSA signatures, and half of the multiplications in
+ * ECDSA verification and ECDHE) by a factor roughly 3 to 4.
+ *
+ * The cost is increasing EC peak memory usage by a factor roughly 2.
+ *
+ * Change this value to 0 to reduce peak memory usage.
+ */
+#define MBEDTLS_ECP_FIXED_POINT_OPTIM  1   /**< Enable fixed-point speed-up. */
+#endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */
+
+/* \} name SECTION: Module settings */
+
+#else  /* MBEDTLS_ECP_ALT */
+#include "ecp_alt.h"
+#endif /* MBEDTLS_ECP_ALT */
+
 #if defined(MBEDTLS_ECP_RESTARTABLE)
 
 /**
@@ -254,68 +316,6 @@
 #endif /* MBEDTLS_ECP_RESTARTABLE */
 
 /**
- * \name SECTION: Module settings
- *
- * The configuration options you can set for this module are in this section.
- * Either change them in config.h, or define them using the compiler command line.
- * \{
- */
-
-#if !defined(MBEDTLS_ECP_MAX_BITS)
-/**
- * The maximum size of the groups, that is, of \c N and \c P.
- */
-#define MBEDTLS_ECP_MAX_BITS     521   /**< The maximum size of groups, in bits. */
-#endif
-
-#define MBEDTLS_ECP_MAX_BYTES    ( ( MBEDTLS_ECP_MAX_BITS + 7 ) / 8 )
-#define MBEDTLS_ECP_MAX_PT_LEN   ( 2 * MBEDTLS_ECP_MAX_BYTES + 1 )
-
-#if !defined(MBEDTLS_ECP_WINDOW_SIZE)
-/*
- * Maximum "window" size used for point multiplication.
- * Default: 6.
- * Minimum value: 2. Maximum value: 7.
- *
- * Result is an array of at most ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) )
- * points used for point multiplication. This value is directly tied to EC
- * peak memory usage, so decreasing it by one should roughly cut memory usage
- * by two (if large curves are in use).
- *
- * Reduction in size may reduce speed, but larger curves are impacted first.
- * Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1):
- *      w-size:     6       5       4       3       2
- *      521       145     141     135     120      97
- *      384       214     209     198     177     146
- *      256       320     320     303     262     226
- *      224       475     475     453     398     342
- *      192       640     640     633     587     476
- */
-#define MBEDTLS_ECP_WINDOW_SIZE    6   /**< The maximum window size used. */
-#endif /* MBEDTLS_ECP_WINDOW_SIZE */
-
-#if !defined(MBEDTLS_ECP_FIXED_POINT_OPTIM)
-/*
- * Trade memory for speed on fixed-point multiplication.
- *
- * This speeds up repeated multiplication of the generator (that is, the
- * multiplication in ECDSA signatures, and half of the multiplications in
- * ECDSA verification and ECDHE) by a factor roughly 3 to 4.
- *
- * The cost is increasing EC peak memory usage by a factor roughly 2.
- *
- * Change this value to 0 to reduce peak memory usage.
- */
-#define MBEDTLS_ECP_FIXED_POINT_OPTIM  1   /**< Enable fixed-point speed-up. */
-#endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */
-
-/* \} name SECTION: Module settings */
-
-#else  /* MBEDTLS_ECP_ALT */
-#include "ecp_alt.h"
-#endif /* MBEDTLS_ECP_ALT */
-
-/**
  * \brief    The ECP key-pair structure.
  *
  * A generic key-pair that may be used for ECDSA and fixed ECDH, for example.
diff --git a/include/mbedtls/gcm.h b/include/mbedtls/gcm.h
index fccabb0..dfce951 100644
--- a/include/mbedtls/gcm.h
+++ b/include/mbedtls/gcm.h
@@ -300,6 +300,8 @@
  */
 void mbedtls_gcm_free( mbedtls_gcm_context *ctx );
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          The GCM checkup routine.
  *
@@ -308,6 +310,8 @@
  */
 int mbedtls_gcm_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/md2.h b/include/mbedtls/md2.h
index f9bd98f..fe97cf0 100644
--- a/include/mbedtls/md2.h
+++ b/include/mbedtls/md2.h
@@ -283,6 +283,8 @@
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          Checkup routine
  *
@@ -295,6 +297,8 @@
  */
 int mbedtls_md2_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/md4.h b/include/mbedtls/md4.h
index dc3c048..ce703c0 100644
--- a/include/mbedtls/md4.h
+++ b/include/mbedtls/md4.h
@@ -288,6 +288,8 @@
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          Checkup routine
  *
@@ -300,6 +302,8 @@
  */
 int mbedtls_md4_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/md5.h b/include/mbedtls/md5.h
index 6c3354f..6eed6cc 100644
--- a/include/mbedtls/md5.h
+++ b/include/mbedtls/md5.h
@@ -288,6 +288,8 @@
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          Checkup routine
  *
@@ -300,6 +302,8 @@
  */
 int mbedtls_md5_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/pkcs5.h b/include/mbedtls/pkcs5.h
index d4bb36d..c52350b 100644
--- a/include/mbedtls/pkcs5.h
+++ b/include/mbedtls/pkcs5.h
@@ -85,6 +85,8 @@
                        unsigned int iteration_count,
                        uint32_t key_length, unsigned char *output );
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          Checkup routine
  *
@@ -92,6 +94,8 @@
  */
 int mbedtls_pkcs5_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/ripemd160.h b/include/mbedtls/ripemd160.h
index c74b7d2..b42f6d2 100644
--- a/include/mbedtls/ripemd160.h
+++ b/include/mbedtls/ripemd160.h
@@ -219,6 +219,8 @@
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          Checkup routine
  *
@@ -226,6 +228,8 @@
  */
 int mbedtls_ripemd160_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h
index ed65a34..906c427 100644
--- a/include/mbedtls/rsa.h
+++ b/include/mbedtls/rsa.h
@@ -1252,6 +1252,8 @@
  */
 void mbedtls_rsa_free( mbedtls_rsa_context *ctx );
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          The RSA checkup routine.
  *
@@ -1260,6 +1262,8 @@
  */
 int mbedtls_rsa_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/sha1.h b/include/mbedtls/sha1.h
index 38ea10b..bb6ecf0 100644
--- a/include/mbedtls/sha1.h
+++ b/include/mbedtls/sha1.h
@@ -328,6 +328,8 @@
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          The SHA-1 checkup routine.
  *
@@ -341,6 +343,8 @@
  */
 int mbedtls_sha1_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/sha256.h b/include/mbedtls/sha256.h
index 0e42f0a..d647398 100644
--- a/include/mbedtls/sha256.h
+++ b/include/mbedtls/sha256.h
@@ -278,6 +278,8 @@
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          The SHA-224 and SHA-256 checkup routine.
  *
@@ -286,6 +288,8 @@
  */
 int mbedtls_sha256_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/sha512.h b/include/mbedtls/sha512.h
index 7b26cf5..c06ceed 100644
--- a/include/mbedtls/sha512.h
+++ b/include/mbedtls/sha512.h
@@ -253,6 +253,7 @@
 #else
 #define MBEDTLS_DEPRECATED
 #endif
+
 /**
  * \brief          This function calculates the SHA-512 or SHA-384
  *                 checksum of a buffer.
@@ -280,6 +281,9 @@
 
 #undef MBEDTLS_DEPRECATED
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+#if defined(MBEDTLS_SELF_TEST)
+
  /**
  * \brief          The SHA-384 or SHA-512 checkup routine.
  *
@@ -287,6 +291,7 @@
  * \return         \c 1 on failure.
  */
 int mbedtls_sha512_self_test( int verbose );
+#endif /* MBEDTLS_SELF_TEST */
 
 #ifdef __cplusplus
 }
diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h
index d6db9c6..9ae825c 100644
--- a/include/mbedtls/x509.h
+++ b/include/mbedtls/x509.h
@@ -269,6 +269,8 @@
  */
 int mbedtls_x509_time_is_future( const mbedtls_x509_time *from );
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          Checkup routine
  *
@@ -276,6 +278,8 @@
  */
 int mbedtls_x509_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 /*
  * Internal module functions. You probably do not want to use these unless you
  * know you do.
diff --git a/include/mbedtls/xtea.h b/include/mbedtls/xtea.h
index 6430c13..b47f553 100644
--- a/include/mbedtls/xtea.h
+++ b/include/mbedtls/xtea.h
@@ -121,6 +121,8 @@
                     unsigned char *output);
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
 
+#if defined(MBEDTLS_SELF_TEST)
+
 /**
  * \brief          Checkup routine
  *
@@ -128,6 +130,8 @@
  */
 int mbedtls_xtea_self_test( int verbose );
 
+#endif /* MBEDTLS_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/library/bignum.c b/library/bignum.c
index f968a0a..87015af 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -527,26 +527,38 @@
 }
 
 /*
- * Helper to write the digits high-order first
+ * Helper to write the digits high-order first.
  */
-static int mpi_write_hlp( mbedtls_mpi *X, int radix, char **p )
+static int mpi_write_hlp( mbedtls_mpi *X, int radix,
+                          char **p, const size_t buflen )
 {
     int ret;
     mbedtls_mpi_uint r;
+    size_t length = 0;
+    char *p_end = *p + buflen;
 
-    if( radix < 2 || radix > 16 )
-        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+    do
+    {
+        if( length >= buflen )
+        {
+            return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
+        }
 
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, radix ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_div_int( X, NULL, X, radix ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, radix ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_div_int( X, NULL, X, radix ) );
+        /*
+         * Write the residue in the current position, as an ASCII character.
+         */
+        if( r < 0xA )
+            *(--p_end) = (char)( '0' + r );
+        else
+            *(--p_end) = (char)( 'A' + ( r - 0xA ) );
 
-    if( mbedtls_mpi_cmp_int( X, 0 ) != 0 )
-        MBEDTLS_MPI_CHK( mpi_write_hlp( X, radix, p ) );
+        length++;
+    } while( mbedtls_mpi_cmp_int( X, 0 ) != 0 );
 
-    if( r < 10 )
-        *(*p)++ = (char)( r + 0x30 );
-    else
-        *(*p)++ = (char)( r + 0x37 );
+    memmove( *p, p_end, length );
+    *p += length;
 
 cleanup:
 
@@ -619,7 +631,7 @@
         if( T.s == -1 )
             T.s = 1;
 
-        MBEDTLS_MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
+        MBEDTLS_MPI_CHK( mpi_write_hlp( &T, radix, &p, buflen ) );
     }
 
     *p++ = '\0';
@@ -715,14 +727,101 @@
 }
 #endif /* MBEDTLS_FS_IO */
 
+
+/* Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint
+ * into the storage form used by mbedtls_mpi. */
+
+static mbedtls_mpi_uint mpi_uint_bigendian_to_host_c( mbedtls_mpi_uint x )
+{
+    uint8_t i;
+    mbedtls_mpi_uint tmp = 0;
+    /* This works regardless of the endianness. */
+    for( i = 0; i < ciL; i++, x >>= 8 )
+        tmp |= ( x & 0xFF ) << ( ( ciL - 1 - i ) << 3 );
+    return( tmp );
+}
+
+static mbedtls_mpi_uint mpi_uint_bigendian_to_host( mbedtls_mpi_uint x )
+{
+#if defined(__BYTE_ORDER__)
+
+/* Nothing to do on bigendian systems. */
+#if ( __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ )
+    return( x );
+#endif /* __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ */
+
+#if ( __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ )
+
+/* For GCC and Clang, have builtins for byte swapping. */
+#if defined(__GNUC__) && defined(__GNUC_PREREQ)
+#if __GNUC_PREREQ(4,3)
+#define have_bswap
+#endif
+#endif
+
+#if defined(__clang__) && defined(__has_builtin)
+#if __has_builtin(__builtin_bswap32)  &&                 \
+    __has_builtin(__builtin_bswap64)
+#define have_bswap
+#endif
+#endif
+
+#if defined(have_bswap)
+    /* The compiler is hopefully able to statically evaluate this! */
+    switch( sizeof(mbedtls_mpi_uint) )
+    {
+        case 4:
+            return( __builtin_bswap32(x) );
+        case 8:
+            return( __builtin_bswap64(x) );
+    }
+#endif
+#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
+#endif /* __BYTE_ORDER__ */
+
+    /* Fall back to C-based reordering if we don't know the byte order
+     * or we couldn't use a compiler-specific builtin. */
+    return( mpi_uint_bigendian_to_host_c( x ) );
+}
+
+static void mpi_bigendian_to_host( mbedtls_mpi_uint * const p, size_t limbs )
+{
+    mbedtls_mpi_uint *cur_limb_left;
+    mbedtls_mpi_uint *cur_limb_right;
+    if( limbs == 0 )
+        return;
+
+    /*
+     * Traverse limbs and
+     * - adapt byte-order in each limb
+     * - swap the limbs themselves.
+     * For that, simultaneously traverse the limbs from left to right
+     * and from right to left, as long as the left index is not bigger
+     * than the right index (it's not a problem if limbs is odd and the
+     * indices coincide in the last iteration).
+     */
+    for( cur_limb_left = p, cur_limb_right = p + ( limbs - 1 );
+         cur_limb_left <= cur_limb_right;
+         cur_limb_left++, cur_limb_right-- )
+    {
+        mbedtls_mpi_uint tmp;
+        /* Note that if cur_limb_left == cur_limb_right,
+         * this code effectively swaps the bytes only once. */
+        tmp             = mpi_uint_bigendian_to_host( *cur_limb_left  );
+        *cur_limb_left  = mpi_uint_bigendian_to_host( *cur_limb_right );
+        *cur_limb_right = tmp;
+    }
+}
+
 /*
  * Import X from unsigned binary data, big endian
  */
 int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen )
 {
     int ret;
-    size_t i, j;
-    size_t const limbs = CHARS_TO_LIMBS( buflen );
+    size_t const limbs    = CHARS_TO_LIMBS( buflen );
+    size_t const overhead = ( limbs * ciL ) - buflen;
+    unsigned char *Xp;
 
     MPI_VALIDATE_RET( X != NULL );
     MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
@@ -734,11 +833,17 @@
         mbedtls_mpi_init( X );
         MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
     }
-
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
 
-    for( i = buflen, j = 0; i > 0; i--, j++ )
-        X->p[j / ciL] |= ((mbedtls_mpi_uint) buf[i - 1]) << ((j % ciL) << 3);
+    /* Avoid calling `memcpy` with NULL source argument,
+     * even if buflen is 0. */
+    if( buf != NULL )
+    {
+        Xp = (unsigned char*) X->p;
+        memcpy( Xp + overhead, buf, buflen );
+
+        mpi_bigendian_to_host( X->p, limbs );
+    }
 
 cleanup:
 
@@ -2008,18 +2113,28 @@
                      void *p_rng )
 {
     int ret;
-    unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
+    size_t const limbs = CHARS_TO_LIMBS( size );
+    size_t const overhead = ( limbs * ciL ) - size;
+    unsigned char *Xp;
+
     MPI_VALIDATE_RET( X     != NULL );
     MPI_VALIDATE_RET( f_rng != NULL );
 
-    if( size > MBEDTLS_MPI_MAX_SIZE )
-        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+    /* Ensure that target MPI has exactly the necessary number of limbs */
+    if( X->n != limbs )
+    {
+        mbedtls_mpi_free( X );
+        mbedtls_mpi_init( X );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
+    }
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
 
-    MBEDTLS_MPI_CHK( f_rng( p_rng, buf, size ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( X, buf, size ) );
+    Xp = (unsigned char*) X->p;
+    f_rng( p_rng, Xp + overhead, size );
+
+    mpi_bigendian_to_host( X->p, limbs );
 
 cleanup:
-    mbedtls_platform_zeroize( buf, sizeof( buf ) );
     return( ret );
 }
 
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 7655834..325bbc0 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -368,7 +368,7 @@
     for( i = 0; i < MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE; i++ )
     {
         ver_chain->items[i].crt = NULL;
-        ver_chain->items[i].flags = -1;
+        ver_chain->items[i].flags = (uint32_t) -1;
     }
 
     ver_chain->len = 0;
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index d23a55e..f654e66 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -223,8 +223,12 @@
 #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
 
 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
-#define USAGE_PSK                                                   \
-    "    psk=%%s              default: \"\" (in hex, without 0x)\n" \
+#define USAGE_PSK                                                       \
+    "    psk=%%s              default: \"\" (in hex, without 0x)\n"     \
+    "    psk_list=%%s         default: \"\"\n"                          \
+    "                          A list of (PSK identity, PSK value) pairs.\n" \
+    "                          The PSK values are in hex, without 0x.\n" \
+    "                          id1,psk1[,id2,psk2[,...]]\n"             \
     "    psk_identity=%%s     default: \"Client_identity\"\n"
 #else
 #define USAGE_PSK ""
diff --git a/tests/scripts/generate_test_code.py b/tests/scripts/generate_test_code.py
index ce6f88c..1258024 100755
--- a/tests/scripts/generate_test_code.py
+++ b/tests/scripts/generate_test_code.py
@@ -184,7 +184,13 @@
 END_CASE_REGEX = r'/\*\s*END_CASE\s*\*/'
 
 DEPENDENCY_REGEX = r'depends_on:(?P<dependencies>.*)'
-C_IDENTIFIER_REGEX = r'!?[a-z_][a-z0-9_]*$'
+C_IDENTIFIER_REGEX = r'!?[a-z_][a-z0-9_]*'
+CONDITION_OPERATOR_REGEX = r'[!=]=|[<>]=?'
+# forbid 0ddd which might be accidentally octal or accidentally decimal
+CONDITION_VALUE_REGEX = r'[-+]?(0x[0-9a-f]+|0|[1-9][0-9]*)'
+CONDITION_REGEX = r'({})(?:\s*({})\s*({}))?$'.format(C_IDENTIFIER_REGEX,
+                                                     CONDITION_OPERATOR_REGEX,
+                                                     CONDITION_VALUE_REGEX)
 TEST_FUNCTION_VALIDATION_REGEX = r'\s*void\s+(?P<func_name>\w+)\s*\('
 INT_CHECK_REGEX = r'int\s+.*'
 CHAR_CHECK_REGEX = r'char\s*\*\s*.*'
@@ -383,7 +389,7 @@
     :return: input dependency stripped of leading & trailing white spaces.
     """
     dependency = dependency.strip()
-    if not re.match(C_IDENTIFIER_REGEX, dependency, re.I):
+    if not re.match(CONDITION_REGEX, dependency, re.I):
         raise GeneratorInputError('Invalid dependency %s' % dependency)
     return dependency
 
@@ -733,16 +739,27 @@
     _not, dep = ('!', dep[1:]) if dep[0] == '!' else ('', dep)
     if not dep:
         raise GeneratorInputError("Dependency should not be an empty string.")
+
+    dependency = re.match(CONDITION_REGEX, dep, re.I)
+    if not dependency:
+        raise GeneratorInputError('Invalid dependency %s' % dep)
+
+    _defined = '' if dependency.group(2) else 'defined'
+    _cond = dependency.group(2) if dependency.group(2) else ''
+    _value = dependency.group(3) if dependency.group(3) else ''
+
     dep_check = '''
         case {id}:
             {{
-#if {_not}defined({macro})
+#if {_not}{_defined}({macro}{_cond}{_value})
                 ret = DEPENDENCY_SUPPORTED;
 #else
                 ret = DEPENDENCY_NOT_SUPPORTED;
 #endif
             }}
-            break;'''.format(_not=_not, macro=dep, id=dep_id)
+            break;'''.format(_not=_not, _defined=_defined,
+                             macro=dependency.group(1), id=dep_id,
+                             _cond=_cond, _value=_value)
     return dep_check
 
 
diff --git a/tests/scripts/mbedtls_test.py b/tests/scripts/mbedtls_test.py
index f9e88cf..c702765 100755
--- a/tests/scripts/mbedtls_test.py
+++ b/tests/scripts/mbedtls_test.py
@@ -75,11 +75,10 @@
         :param split_char: Split character
         :return: List of splits
         """
+        split_colon_fn = lambda x: re.sub(r'\\' + split_char, split_char, x)
         if len(split_char) > 1:
             raise ValueError('Expected split character. Found string!')
-        out = re.sub(r'(\\.)|' + split_char,
-                     lambda m: m.group(1) or '\n', inp_str,
-                     len(inp_str)).split('\n')
+        out = map(split_colon_fn, re.split(r'(?<!\\)' + split_char, inp_str))
         out = [x for x in out if x]
         return out
 
@@ -112,8 +111,8 @@
             args = parts[1:]
             args_count = len(args)
             if args_count % 2 != 0:
-                raise TestDataParserError("Number of test arguments should "
-                                          "be even: %s" % line)
+                err_str_fmt = "Number of test arguments({}) should be even: {}"
+                raise TestDataParserError(err_str_fmt.format(args_count, line))
             grouped_args = [(args[i * 2], args[(i * 2) + 1])
                             for i in range(len(args)/2)]
             self.tests.append((name, function_name, dependencies,
@@ -163,6 +162,7 @@
         self.tests = []
         self.test_index = -1
         self.dep_index = 0
+        self.suite_passed = True
         self.error_str = dict()
         self.error_str[self.DEPENDENCY_SUPPORTED] = \
             'DEPENDENCY_SUPPORTED'
@@ -293,7 +293,7 @@
             name, function_id, dependencies, args = self.tests[self.test_index]
             self.run_test(name, function_id, dependencies, args)
         else:
-            self.notify_complete(True)
+            self.notify_complete(self.suite_passed)
 
     def run_test(self, name, function_id, dependencies, args):
         """
@@ -353,6 +353,8 @@
         self.log('{{__testcase_start;%s}}' % name)
         self.log('{{__testcase_finish;%s;%d;%d}}' % (name, int_val == 0,
                                                      int_val != 0))
+        if int_val != 0:
+            self.suite_passed = False
         self.run_next_test()
 
     @event_callback("F")
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index 2e227f0..1255ff4 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -342,6 +342,7 @@
 
     if( *out_stream == NULL )
     {
+        close( stdout_fd );
         return -1;
     }
 
diff --git a/tests/suites/test_suite_ccm.data b/tests/suites/test_suite_ccm.data
index 819b3b7..ac9c565 100644
--- a/tests/suites/test_suite_ccm.data
+++ b/tests/suites/test_suite_ccm.data
@@ -42,6 +42,7 @@
 ccm_lengths:5:10:5:7:MBEDTLS_ERR_CCM_BAD_INPUT
 
 CCM lenghts #7 AD too long (2^16 - 2^8 + 1)
+depends_on:!MBEDTLS_CCM_ALT
 ccm_lengths:5:10:65281:8:MBEDTLS_ERR_CCM_BAD_INPUT
 
 CCM lengths #8 msg too long for this IV length (2^16, q = 2)
diff --git a/tests/suites/test_suite_rsa.data b/tests/suites/test_suite_rsa.data
index a25d61c..5f49ad6 100644
--- a/tests/suites/test_suite_rsa.data
+++ b/tests/suites/test_suite_rsa.data
@@ -330,6 +330,7 @@
 mbedtls_rsa_check_pubkey:16:"7edcba9876543210deadbeefcafe4321":16:"3":MBEDTLS_ERR_RSA_KEY_CHECK_FAILED
 
 RSA Check Public key #6 (N exactly 8192 bits)
+depends_on:MBEDTLS_MPI_MAX_SIZE>=1024
 mbedtls_rsa_check_pubkey:16:"88F48075BF29E95C1C6AE8716678B74E957B69CC2E49708C160C6343AAD2F076D25397ACE74220311ED18AEEB681F463611B3340C3945CAAEAD3ACC616E08A25A55683A32979BD55EA5DAB7630AF393886896F11DDC5F07E15EDF949324CF0F0B2A5C0E85DFA23167193182D1A43079DC8645F6C2C029629F475575802F7D326DE5BD891A9C5F84A433D45154181EC05685A4B368A5B6434775A00ABC6B0A04647D4598CEEE566B552230F691C98CA30B402A76C686A94B373CCD2F60EFA3878A867BB5F585D088E27C507937262D098A477B9218BE7C03B2E4C102D244CA701645F1827CD947E5E796446378B848862E689F0D1773F752056841A1F0EECE7CAB74921A42DBF2EF264ADCF4ABE05A1242E5F629A657A2D67958A2DAC9A2245074A37099B45064723ABE21241058252632C2BA6FE85AB1C75FF310891B84C9C40AB646FE1D90BC716FB3A4B56DA3EA25CA397C04B994F7C6AD1DD0CB9E994CA6B835F7830F4F4E0F976BBEA5AE8556BC7C90B3E50E21C19AD1F6BC4A8FF15F2909D9CC5F3DA533BADFF50F487869D631C3E34D69636B4C25A55127EF5B715F2FC0565734B38DF996D1970E56F7F64EBECB9D00A587AAEC608F2D3AAA51E66BF53E92C3096BF78D1DCBCE1A645FA4F0542E6F68E5A94AAA6E839F75620FABED5D2BCF40AB8EAF95F838BFA962429F281578882DF0F2721C27C8905C9E776B1D3251FC066A8BC64C0CE7FBA2B8E21F65EF6739AB6F19EC2AB07817DFF03DAB7C846AB5CC86C103642D7664A85DC2D846A8004CD6A144C72CCCAC86DB5901A047324927B80E281F5F7315FA2F9083BDE0DB7AA46DC055E36BB73FB6DBD3A14759D06CBBE8D57CBC213C4D55DE4478679E0A5902C8655BE1391C0E88D2B1FBD57E9232A2CEBC67569ECD94E4BF0FCC6C003F9AA51A2A5E6EE084A46DAE65E52400A727F9713D29E92CD6CA37FD599598B3F677624A2A484A8B36B98EFEAD662C0A23BC1D9280EF2A31F887065EB20A93B41F7A264ECFA65B3555F3E400927018186EAA2D4F00C6B7AB1BCED5F893D64478177592C7F2B945307AB474D7EC7FF2E7E55834CC763BEF81DA9BD70FB3D423AE5ADB86B336734C8A3BEC90CEB05438B5BA030D0D30DEC1442D2EB08450480FBAE090FFA1A5ADD748A415BDCDE45094E792420F0AF94BCA0A80A2096D1A478D3428A214A7E68C0F07F58C6FB232ECC3D8B821AE29AE76E13EB751193F6ECA670016D54F3D796937DDBB8900062EF116CCA3F5B3AECA618272875336C9C050FBC0FC7EDD5B88D85DA0061D21E176E1419CF573629BE7B0496E761EAD45FE32B59EB00D47CDD178AC8F8EC8D6F26DED34F7576CD938422E18E936F16A704B483A48EE3BEA59D95F688136119894930EC8E9282E5974740CF031DF8DBB07EB08F2DA0ACCADECE15A6A57502890F4A03740E60BD":16:"010001":0
 
 RSA Check Public key #7 (N larger than 8192 bits)