Merge pull request #179 from mpg/sha512-no-sha384

Add option to build SHA-512 without SHA-384
diff --git a/doxygen/mbedtls.doxyfile b/doxygen/mbedtls.doxyfile
index 197941f..7f7ce32 100644
--- a/doxygen/mbedtls.doxyfile
+++ b/doxygen/mbedtls.doxyfile
@@ -28,7 +28,7 @@
 # identify the project. Note that if you do not use Doxywizard you need
 # to put quotes around the project name if it contains spaces.
 
-PROJECT_NAME           = "mbed TLS v2.19.1"
+PROJECT_NAME           = "mbed TLS v2.20.0"
 
 # The PROJECT_NUMBER tag can be used to enter a project or revision number.
 # This could be handy for archiving the generated documentation or
diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h
index 2c5ace6..1d00c56 100644
--- a/include/mbedtls/bignum.h
+++ b/include/mbedtls/bignum.h
@@ -185,7 +185,7 @@
  */
 typedef struct mbedtls_mpi
 {
-    int s;              /*!<  integer sign      */
+    int s;              /*!<  Sign: -1 if the mpi is negative, 1 otherwise */
     size_t n;           /*!<  total # of limbs  */
     mbedtls_mpi_uint *p;          /*!<  pointer to limbs  */
 }
@@ -595,6 +595,24 @@
 int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y );
 
 /**
+ * \brief          Check if an MPI is less than the other in constant time.
+ *
+ * \param X        The left-hand MPI. This must point to an initialized MPI
+ *                 with the same allocated length as Y.
+ * \param Y        The right-hand MPI. This must point to an initialized MPI
+ *                 with the same allocated length as X.
+ * \param ret      The result of the comparison:
+ *                 \c 1 if \p X is less than \p Y.
+ *                 \c 0 if \p X is greater than or equal to \p Y.
+ *
+ * \return         0 on success.
+ * \return         MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the allocated length of
+ *                 the two input MPIs is not the same.
+ */
+int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y,
+        unsigned *ret );
+
+/**
  * \brief          Compare an MPI with an integer.
  *
  * \param X        The left-hand MPI. This must point to an initialized MPI.
diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h
index 091f15a..234e6a0 100644
--- a/include/mbedtls/ctr_drbg.h
+++ b/include/mbedtls/ctr_drbg.h
@@ -177,7 +177,9 @@
                                  * minus one.
                                  * Before the initial seeding, this field
                                  * contains the amount of entropy in bytes
-                                 * to use as a nonce for the initial seeding.
+                                 * to use as a nonce for the initial seeding,
+                                 * or -1 if no nonce length has been explicitly
+                                 * set (see mbedtls_ctr_drbg_set_nonce_len()).
                                  */
     int prediction_resistance;  /*!< This determines whether prediction
                                      resistance is enabled, that is
diff --git a/include/mbedtls/version.h b/include/mbedtls/version.h
index ae694ee..d4e5d54 100644
--- a/include/mbedtls/version.h
+++ b/include/mbedtls/version.h
@@ -39,17 +39,17 @@
  * Major, Minor, Patchlevel
  */
 #define MBEDTLS_VERSION_MAJOR  2
-#define MBEDTLS_VERSION_MINOR  19
-#define MBEDTLS_VERSION_PATCH  1
+#define MBEDTLS_VERSION_MINOR  20
+#define MBEDTLS_VERSION_PATCH  0
 
 /**
  * The single version number has the following structure:
  *    MMNNPP00
  *    Major version | Minor version | Patch version
  */
-#define MBEDTLS_VERSION_NUMBER         0x02130100
-#define MBEDTLS_VERSION_STRING         "2.19.1"
-#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.19.1"
+#define MBEDTLS_VERSION_NUMBER         0x02140000
+#define MBEDTLS_VERSION_STRING         "2.20.0"
+#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.20.0"
 
 #if defined(MBEDTLS_VERSION_C)
 
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 5c5ddc2..1d4d371 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -157,7 +157,7 @@
 
 if(USE_SHARED_MBEDTLS_LIBRARY)
     add_library(mbedcrypto SHARED ${src_crypto})
-    set_target_properties(mbedcrypto PROPERTIES VERSION 2.17.0 SOVERSION 3)
+    set_target_properties(mbedcrypto PROPERTIES VERSION 2.20.0 SOVERSION 4)
     target_link_libraries(mbedcrypto ${libs})
     target_include_directories(mbedcrypto
         PUBLIC ${MBEDTLS_DIR}/include/
diff --git a/library/Makefile b/library/Makefile
index 6aeb95f..ca063f4 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -36,7 +36,7 @@
 endif
 endif
 
-SOEXT_CRYPTO=so.3
+SOEXT_CRYPTO=so.4
 
 # Set AR_DASH= (empty string) to use an ar implementation that does not accept
 # the - prefix for command line options (e.g. llvm-ar)
diff --git a/library/aes.c b/library/aes.c
index 6e86990..604d0f3 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -919,6 +919,18 @@
     PUT_UINT32_LE( X2, output,  8 );
     PUT_UINT32_LE( X3, 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 ) );
+
     return( 0 );
 }
 #endif /* !MBEDTLS_AES_ENCRYPT_ALT */
@@ -987,6 +999,18 @@
     PUT_UINT32_LE( X2, output,  8 );
     PUT_UINT32_LE( X3, 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 ) );
+
     return( 0 );
 }
 #endif /* !MBEDTLS_AES_DECRYPT_ALT */
diff --git a/library/bignum.c b/library/bignum.c
index 1d258db..61d1810 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -1149,6 +1149,107 @@
     return( 0 );
 }
 
+/** Decide if an integer is less than the other, without branches.
+ *
+ * \param x         First integer.
+ * \param y         Second integer.
+ *
+ * \return          1 if \p x is less than \p y, 0 otherwise
+ */
+static unsigned ct_lt_mpi_uint( const mbedtls_mpi_uint x,
+        const mbedtls_mpi_uint y )
+{
+    mbedtls_mpi_uint ret;
+    mbedtls_mpi_uint cond;
+
+    /*
+     * Check if the most significant bits (MSB) of the operands are different.
+     */
+    cond = ( x ^ y );
+    /*
+     * If the MSB are the same then the difference x-y will be negative (and
+     * have its MSB set to 1 during conversion to unsigned) if and only if x<y.
+     */
+    ret = ( x - y ) & ~cond;
+    /*
+     * If the MSB are different, then the operand with the MSB of 1 is the
+     * bigger. (That is if y has MSB of 1, then x<y is true and it is false if
+     * the MSB of y is 0.)
+     */
+    ret |= y & cond;
+
+
+    ret = ret >> ( biL - 1 );
+
+    return (unsigned) ret;
+}
+
+/*
+ * Compare signed values in constant time
+ */
+int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y,
+        unsigned *ret )
+{
+    size_t i;
+    /* The value of any of these variables is either 0 or 1 at all times. */
+    unsigned cond, done, X_is_negative, Y_is_negative;
+
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
+    MPI_VALIDATE_RET( ret != NULL );
+
+    if( X->n != Y->n )
+        return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+
+    /*
+     * Set sign_N to 1 if N >= 0, 0 if N < 0.
+     * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
+     */
+    X_is_negative = ( X->s & 2 ) >> 1;
+    Y_is_negative = ( Y->s & 2 ) >> 1;
+
+    /*
+     * If the signs are different, then the positive operand is the bigger.
+     * That is if X is negative (X_is_negative == 1), then X < Y is true and it
+     * is false if X is positive (X_is_negative == 0).
+     */
+    cond = ( X_is_negative ^ Y_is_negative );
+    *ret = cond & X_is_negative;
+
+    /*
+     * This is a constant-time function. We might have the result, but we still
+     * need to go through the loop. Record if we have the result already.
+     */
+    done = cond;
+
+    for( i = X->n; i > 0; i-- )
+    {
+        /*
+         * If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both
+         * X and Y are negative.
+         *
+         * Again even if we can make a decision, we just mark the result and
+         * the fact that we are done and continue looping.
+         */
+        cond = ct_lt_mpi_uint( Y->p[i - 1], X->p[i - 1] );
+        *ret |= cond & ( 1 - done ) & X_is_negative;
+        done |= cond;
+
+        /*
+         * If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both
+         * X and Y are positive.
+         *
+         * Again even if we can make a decision, we just mark the result and
+         * the fact that we are done and continue looping.
+         */
+        cond = ct_lt_mpi_uint( X->p[i - 1], Y->p[i - 1] );
+        *ret |= cond & ( 1 - done ) & ( 1 - X_is_negative );
+        done |= cond;
+    }
+
+    return( 0 );
+}
+
 /*
  * Compare signed values
  */
diff --git a/library/cipher.c b/library/cipher.c
index b62f1d5..409c3fe 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -527,6 +527,10 @@
 
     *olen = 0;
     block_size = mbedtls_cipher_get_block_size( ctx );
+    if ( 0 == block_size )
+    {
+        return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
+    }
 
     if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB )
     {
@@ -562,11 +566,6 @@
     }
 #endif
 
-    if ( 0 == block_size )
-    {
-        return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
-    }
-
     if( input == output &&
        ( ctx->unprocessed_len != 0 || ilen % block_size ) )
     {
@@ -625,11 +624,6 @@
          */
         if( 0 != ilen )
         {
-            if( 0 == block_size )
-            {
-                return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
-            }
-
             /* Encryption: only cache partial blocks
              * Decryption w/ padding: always keep at least one whole block
              * Decryption w/o padding: only cache partial blocks
diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c
index 3f1be43..8a2920a 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -585,7 +585,7 @@
 exit:
     mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
     mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
-    return( 0 );
+    return( ret );
 }
 
 int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output,
diff --git a/library/ecdsa.c b/library/ecdsa.c
index a6ba75d..5acd2d0 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -298,7 +298,7 @@
     *p_sign_tries = 0;
     do
     {
-        if( *p_sign_tries++ > 10 )
+        if( (*p_sign_tries)++ > 10 )
         {
             ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
             goto cleanup;
@@ -311,7 +311,7 @@
         *p_key_tries = 0;
         do
         {
-            if( *p_key_tries++ > 10 )
+            if( (*p_key_tries)++ > 10 )
             {
                 ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
                 goto cleanup;
@@ -364,6 +364,7 @@
         MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &e, &e, s ) );
         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &e, &e, &t ) );
         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pk, pk, &t ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pk, pk, &grp->N ) );
         MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s, pk, &grp->N ) );
         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, s, &e ) );
         MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s, s, &grp->N ) );
diff --git a/library/ecp.c b/library/ecp.c
index 1ad1697..e156fcb 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -2804,6 +2804,7 @@
     {
         /* SEC1 3.2.1: Generate d such that 1 <= n < N */
         int count = 0;
+        unsigned cmp = 0;
 
         /*
          * Match the procedure given in RFC 6979 (deterministic ECDSA):
@@ -2828,9 +2829,14 @@
              */
             if( ++count > 30 )
                 return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
+
+            ret = mbedtls_mpi_lt_mpi_ct( d, &grp->N, &cmp );
+            if( ret != 0 )
+            {
+                goto cleanup;
+            }
         }
-        while( mbedtls_mpi_cmp_int( d, 1 ) < 0 ||
-               mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 );
+        while( mbedtls_mpi_cmp_int( d, 1 ) < 0 || cmp != 1 );
     }
 #endif /* ECP_SHORTWEIERSTRASS */
 
diff --git a/library/gcm.c b/library/gcm.c
index 26f6010..e34f1da 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -247,7 +247,7 @@
     for( i = 15; i >= 0; i-- )
     {
         lo = x[i] & 0xf;
-        hi = x[i] >> 4;
+        hi = ( x[i] >> 4 ) & 0xf;
 
         if( i != 15 )
         {
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index 0cce463..3e68c06 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -158,11 +158,10 @@
     }                                                             \
     while( 0 )
 
-/** Allocate memory dynamically. Exit the test if this fails, but do
- * not mark the test as failed.
+/** Allocate memory dynamically. If the allocation fails, skip the test case.
  *
  * This macro behaves like #ASSERT_ALLOC, except that if the allocation
- * fails, it jumps to the \c exit label without calling test_fail().
+ * fails, it marks the test as skipped rather than failed.
  */
 #define ASSERT_ALLOC_WEAK( pointer, length )                      \
     do                                                            \
@@ -172,8 +171,7 @@
         {                                                         \
             ( pointer ) = mbedtls_calloc( sizeof( *( pointer ) ), \
                                           ( length ) );           \
-            if( ( pointer ) == NULL )                             \
-                goto exit;                                        \
+            TEST_ASSUME( ( pointer ) != NULL );                   \
         }                                                         \
     }                                                             \
     while( 0 )
diff --git a/tests/suites/test_suite_asn1parse.function b/tests/suites/test_suite_asn1parse.function
index d747cc2..f07fd40 100644
--- a/tests/suites/test_suite_asn1parse.function
+++ b/tests/suites/test_suite_asn1parse.function
@@ -121,6 +121,7 @@
 {
     unsigned char *buf = NULL;
     unsigned char *p = NULL;
+    unsigned char *end;
     size_t parsed_length;
     int ret;
 
@@ -130,7 +131,8 @@
     if( buffer_size == 0 )
     {
         ASSERT_ALLOC( buf, 1 );
-        p = buf + 1;
+        end = buf + 1;
+        p = end;
     }
     else
     {
@@ -145,9 +147,10 @@
             memcpy( buf, input->x, buffer_size );
         }
         p = buf;
+        end = buf + buffer_size;
     }
 
-    ret = mbedtls_asn1_get_len( &p, buf + buffer_size, &parsed_length );
+    ret = mbedtls_asn1_get_len( &p, end, &parsed_length );
 
     if( buffer_size >= input->len + actual_length )
     {
diff --git a/tests/suites/test_suite_ecdsa.function b/tests/suites/test_suite_ecdsa.function
index ab3db3a..59c1c49 100644
--- a/tests/suites/test_suite_ecdsa.function
+++ b/tests/suites/test_suite_ecdsa.function
@@ -500,7 +500,9 @@
     TEST_ASSERT( md_info != NULL );
 
     hlen = mbedtls_md_get_size( md_info );
-    mbedtls_md( md_info, (const unsigned char *) msg, strlen( msg ), hash );
+    TEST_ASSERT( mbedtls_md( md_info,
+                             (const unsigned char *) msg, strlen( msg ),
+                             hash ) == 0 );
 
     mbedtls_ecp_set_max_ops( max_ops );
 
diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data
index f8ee09c..480768b 100644
--- a/tests/suites/test_suite_mpi.data
+++ b/tests/suites/test_suite_mpi.data
@@ -175,6 +175,93 @@
 Base test mbedtls_mpi_cmp_mpi (Mixed values) #6
 mbedtls_mpi_cmp_mpi:10:"-2":10:"31231231289798":-1
 
+Base test mbedtls_mpi_lt_mpi_ct #1
+mbedtls_mpi_lt_mpi_ct:1:"2B5":1:"2B5":0:0
+
+Base test mbedtls_mpi_lt_mpi_ct #2
+mbedtls_mpi_lt_mpi_ct:1:"2B5":1:"2B4":0:0
+
+Base test mbedtls_mpi_lt_mpi_ct #3
+mbedtls_mpi_lt_mpi_ct:1:"2B5":1:"2B6":1:0
+
+Base test mbedtls_mpi_lt_mpi_ct (Negative values) #1
+mbedtls_mpi_lt_mpi_ct:1:"-2":1:"-2":0:0
+
+Base test mbedtls_mpi_lt_mpi_ct (Negative values) #2
+mbedtls_mpi_lt_mpi_ct:1:"-2":1:"-3":0:0
+
+Base test mbedtls_mpi_lt_mpi_ct (Negative values) #3
+mbedtls_mpi_lt_mpi_ct:1:"-2":1:"-1":1:0
+
+Base test mbedtls_mpi_lt_mpi_ct (Mixed values) #1
+mbedtls_mpi_lt_mpi_ct:1:"-3":1:"2":1:0
+
+Base test mbedtls_mpi_lt_mpi_ct (Mixed values) #2
+mbedtls_mpi_lt_mpi_ct:1:"2":1:"-3":0:0
+
+Base test mbedtls_mpi_lt_mpi_ct (Mixed values) #3
+mbedtls_mpi_lt_mpi_ct:2:"-2":2:"1C67967269C6":1:0
+
+Base test mbedtls_mpi_lt_mpi_ct (X is longer in storage)
+mbedtls_mpi_lt_mpi_ct:3:"2B5":2:"2B5":0:MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+Base test mbedtls_mpi_lt_mpi_ct (Y is longer in storage)
+mbedtls_mpi_lt_mpi_ct:3:"2B5":4:"2B5":0:MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+Base test mbedtls_mpi_lt_mpi_ct (corner case - 64 bit) #1
+mbedtls_mpi_lt_mpi_ct:2:"7FFFFFFFFFFFFFFF":2:"FF":0:0
+
+Base test mbedtls_mpi_lt_mpi_ct (corner case - 64 bit) #2
+mbedtls_mpi_lt_mpi_ct:2:"8000000000000000":2:"7FFFFFFFFFFFFFFF":0:0
+
+Base test mbedtls_mpi_lt_mpi_ct (corner case - 64 bit) #3
+mbedtls_mpi_lt_mpi_ct:2:"8000000000000000":2:"1":0:0
+
+Base test mbedtls_mpi_lt_mpi_ct (corner case - 64 bit) #4
+mbedtls_mpi_lt_mpi_ct:2:"8000000000000000":2:"0":0:0
+
+Base test mbedtls_mpi_lt_mpi_ct (corner case - 64 bit) #5
+mbedtls_mpi_lt_mpi_ct:2:"FFFFFFFFFFFFFFFF":2:"FF":0:0
+
+Base test mbedtls_mpi_lt_mpi_ct (corner case - 32 bit) #1
+mbedtls_mpi_lt_mpi_ct:1:"7FFFFFFF":1:"FF":0:0
+
+Base test mbedtls_mpi_lt_mpi_ct (corner case - 32 bit) #2
+mbedtls_mpi_lt_mpi_ct:1:"80000000":1:"7FFFFFFF":0:0
+
+Base test mbedtls_mpi_lt_mpi_ct (corner case - 32 bit) #3
+mbedtls_mpi_lt_mpi_ct:1:"80000000":1:"1":0:0
+
+Base test mbedtls_mpi_lt_mpi_ct (corner case - 32 bit) #4
+mbedtls_mpi_lt_mpi_ct:1:"80000000":1:"0":0:0
+
+Base test mbedtls_mpi_lt_mpi_ct (corner case - 32 bit) #5
+mbedtls_mpi_lt_mpi_ct:1:"FFFFFFFF":1:"FF":0:0
+
+Multi-limb mbedtls_mpi_lt_mpi_ct (X<Y, zero vs non-zero MS limb)
+mbedtls_mpi_lt_mpi_ct:2:"0FFFFFFFFFFFFFFFF":2:"1FFFFFFFFFFFFFFFF":1:0
+
+Multi-limb mbedtls_mpi_lt_mpi_ct (X>Y, equal MS limbs)
+mbedtls_mpi_lt_mpi_ct:2:"-EEFFFFFFFFFFFFFFF1":2:"-EEFFFFFFFFFFFFFFFF":0:0
+
+Multi-limb mbedtls_mpi_lt_mpi_ct (X=Y)
+mbedtls_mpi_lt_mpi_ct:2:"EEFFFFFFFFFFFFFFFF":2:"EEFFFFFFFFFFFFFFFF":0:0
+
+Multi-limb mbedtls_mpi_lt_mpi_ct (X=-Y)
+mbedtls_mpi_lt_mpi_ct:2:"-EEFFFFFFFFFFFFFFFF":2:"EEFFFFFFFFFFFFFFFF":1:0
+
+Multi-limb mbedtls_mpi_lt_mpi_ct (Alternating limbs) #1
+mbedtls_mpi_lt_mpi_ct:2:"11FFFFFFFFFFFFFFFF":2:"FF1111111111111111":1:0
+
+Multi-limb mbedtls_mpi_lt_mpi_ct (Alternating limbs) #2
+mbedtls_mpi_lt_mpi_ct:2:"FF1111111111111111":2:"11FFFFFFFFFFFFFFFF":0:0
+
+Multi-limb mbedtls_mpi_lt_mpi_ct (Alternating limbs) #3
+mbedtls_mpi_lt_mpi_ct:2:"-11FFFFFFFFFFFFFFFF":2:"-FF1111111111111111":0:0
+
+Multi-limb mbedtls_mpi_lt_mpi_ct (Alternating limbs) #4
+mbedtls_mpi_lt_mpi_ct:2:"-FF1111111111111111":2:"-11FFFFFFFFFFFFFFFF":1:0
+
 Base test mbedtls_mpi_cmp_abs #1
 mbedtls_mpi_cmp_abs:10:"693":10:"693":0
 
diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function
index eaae196..0f35a2a 100644
--- a/tests/suites/test_suite_mpi.function
+++ b/tests/suites/test_suite_mpi.function
@@ -588,6 +588,31 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void mbedtls_mpi_lt_mpi_ct( int size_X, char * input_X,
+                            int size_Y, char * input_Y,
+                            int input_ret, int input_err )
+{
+    unsigned ret;
+    unsigned input_uret = input_ret;
+    mbedtls_mpi X, Y;
+    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
+
+    TEST_ASSERT( mbedtls_mpi_read_string( &X, 16, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_string( &Y, 16, input_Y ) == 0 );
+
+    TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
+
+    TEST_ASSERT( mbedtls_mpi_lt_mpi_ct( &X, &Y, &ret ) == input_err );
+    if( input_err == 0 )
+        TEST_ASSERT( ret == input_uret );
+
+exit:
+    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void mbedtls_mpi_cmp_abs( int radix_X, char * input_X, int radix_Y,
                           char * input_Y, int input_A )
 {
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index 926cec4..4742725 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -844,7 +844,9 @@
     TEST_ASSERT( md_info != NULL );
 
     hlen = mbedtls_md_get_size( md_info );
-    mbedtls_md( md_info, (const unsigned char *) msg, strlen( msg ), hash );
+    TEST_ASSERT( mbedtls_md( md_info,
+                             (const unsigned char *) msg, strlen( msg ),
+                             hash ) == 0 );
 
     mbedtls_ecp_set_max_ops( max_ops );
 
diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data
index b6dca23..ff0612b 100644
--- a/tests/suites/test_suite_version.data
+++ b/tests/suites/test_suite_version.data
@@ -1,8 +1,8 @@
 Check compiletime library version
-check_compiletime_version:"2.19.1"
+check_compiletime_version:"2.20.0"
 
 Check runtime library version
-check_runtime_version:"2.19.1"
+check_runtime_version:"2.20.0"
 
 Check for MBEDTLS_VERSION_C
 check_feature:"MBEDTLS_VERSION_C":0