Merge pull request #3184 from gilles-peskine-arm/pylint-up-to-2.4-2.16

Backport 2.16: Pass Pylint up to 2.4
diff --git a/ChangeLog b/ChangeLog
index 6ec1e7ec..96fa9f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,10 +1,21 @@
 mbed TLS ChangeLog (Sorted per branch, date)
 
-= mbed TLS x.x.x branch released xxxx-xx-xx
+= mbed TLS 2.16.6 branch released 2020-04-14
+
+Security
+   * Fix side channel in ECC code that allowed an adversary with access to
+     precise enough timing and memory access information (typically an
+     untrusted operating system attacking a secure enclave) to fully recover
+     an ECDSA private key. Found and reported by Alejandro Cabrera Aldaya,
+     Billy Brumley and Cesar Pereida Garcia. CVE-2020-10932
+   * Fix a potentially remotely exploitable buffer overread in a
+     DTLS client when parsing the Hello Verify Request message.
 
 Bugfix
    * Fix compilation failure when both MBEDTLS_SSL_PROTO_DTLS and
      MBEDTLS_SSL_HW_RECORD_ACCEL are enabled.
+   * Fix a function name in a debug message. Contributed by Ercan Ozturk in
+     #3013.
 
 = mbed TLS 2.16.5 branch released 2020-02-20
 
diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h
index bc55d13..db5bb49 100644
--- a/doxygen/input/doc_mainpage.h
+++ b/doxygen/input/doc_mainpage.h
@@ -24,7 +24,7 @@
  */
 
 /**
- * @mainpage mbed TLS v2.16.5 source code documentation
+ * @mainpage mbed TLS v2.16.6 source code documentation
  *
  * This documentation describes the internal structure of mbed TLS.  It was
  * automatically generated from specially formatted comment blocks in
diff --git a/doxygen/mbedtls.doxyfile b/doxygen/mbedtls.doxyfile
index d0b1744..1edc9ce 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.16.5"
+PROJECT_NAME           = "mbed TLS v2.16.6"
 
 # 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/version.h b/include/mbedtls/version.h
index 8e2ce03..e0a2e7f 100644
--- a/include/mbedtls/version.h
+++ b/include/mbedtls/version.h
@@ -40,16 +40,16 @@
  */
 #define MBEDTLS_VERSION_MAJOR  2
 #define MBEDTLS_VERSION_MINOR  16
-#define MBEDTLS_VERSION_PATCH  5
+#define MBEDTLS_VERSION_PATCH  6
 
 /**
  * The single version number has the following structure:
  *    MMNNPP00
  *    Major version | Minor version | Patch version
  */
-#define MBEDTLS_VERSION_NUMBER         0x02100500
-#define MBEDTLS_VERSION_STRING         "2.16.5"
-#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.16.5"
+#define MBEDTLS_VERSION_NUMBER         0x02100600
+#define MBEDTLS_VERSION_STRING         "2.16.6"
+#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.16.6"
 
 #if defined(MBEDTLS_VERSION_C)
 
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 5c67d5b..93ce7b8 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -165,15 +165,15 @@
 
 if(USE_SHARED_MBEDTLS_LIBRARY)
     add_library(mbedcrypto SHARED ${src_crypto})
-    set_target_properties(mbedcrypto PROPERTIES VERSION 2.16.5 SOVERSION 3)
+    set_target_properties(mbedcrypto PROPERTIES VERSION 2.16.6 SOVERSION 3)
     target_link_libraries(mbedcrypto ${libs})
 
     add_library(mbedx509 SHARED ${src_x509})
-    set_target_properties(mbedx509 PROPERTIES VERSION 2.16.5 SOVERSION 0)
+    set_target_properties(mbedx509 PROPERTIES VERSION 2.16.6 SOVERSION 0)
     target_link_libraries(mbedx509 ${libs} mbedcrypto)
 
     add_library(mbedtls SHARED ${src_tls})
-    set_target_properties(mbedtls PROPERTIES VERSION 2.16.5 SOVERSION 12)
+    set_target_properties(mbedtls PROPERTIES VERSION 2.16.6 SOVERSION 12)
     target_link_libraries(mbedtls ${libs} mbedx509)
 
     install(TARGETS mbedtls mbedx509 mbedcrypto
diff --git a/library/ecp.c b/library/ecp.c
index 040c20b..725e176 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -1938,6 +1938,20 @@
 
 final_norm:
 #endif
+    /*
+     * Knowledge of the jacobian coordinates may leak the last few bits of the
+     * scalar [1], and since our MPI implementation isn't constant-flow,
+     * inversion (used for coordinate normalization) may leak the full value
+     * of its input via side-channels [2].
+     *
+     * [1] https://eprint.iacr.org/2003/191
+     * [2] https://eprint.iacr.org/2020/055
+     *
+     * Avoid the leak by randomizing coordinates before we normalize them.
+     */
+    if( f_rng != 0 )
+        MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, RR, f_rng, p_rng ) );
+
     MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV );
     MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, RR ) );
 
@@ -2308,6 +2322,20 @@
         MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) );
     }
 
+    /*
+     * Knowledge of the projective coordinates may leak the last few bits of the
+     * scalar [1], and since our MPI implementation isn't constant-flow,
+     * inversion (used for coordinate normalization) may leak the full value
+     * of its input via side-channels [2].
+     *
+     * [1] https://eprint.iacr.org/2003/191
+     * [2] https://eprint.iacr.org/2020/055
+     *
+     * Avoid the leak by randomizing coordinates before we normalize them.
+     */
+    if( f_rng != NULL )
+        MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, R, f_rng, p_rng ) );
+
     MBEDTLS_MPI_CHK( ecp_normalize_mxz( grp, R ) );
 
 cleanup:
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index afced7a..c5c3af6 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1417,6 +1417,19 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse hello verify request" ) );
 
+    /* Check that there is enough room for:
+     * - 2 bytes of version
+     * - 1 byte of cookie_len
+     */
+    if( mbedtls_ssl_hs_hdr_len( ssl ) + 3 > ssl->in_msglen )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1,
+            ( "incoming HelloVerifyRequest message is too short" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                    MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    }
+
     /*
      * struct {
      *   ProtocolVersion server_version;
@@ -1445,8 +1458,6 @@
     }
 
     cookie_len = *p++;
-    MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len );
-
     if( ( ssl->in_msg + ssl->in_msglen ) - p < cookie_len )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1,
@@ -1455,6 +1466,7 @@
                                     MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
+    MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len );
 
     mbedtls_free( ssl->handshake->verify_cookie );
 
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 9c2e365..176e885 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -514,6 +514,12 @@
         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
 
+    /* Do not accept max_pathlen equal to INT_MAX to avoid a signed integer
+     * overflow, which is an undefined behavior. */
+    if( *max_pathlen == INT_MAX )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+
     (*max_pathlen)++;
 
     return( 0 );
diff --git a/tests/data_files/server1_pathlen_int_max-1.crt b/tests/data_files/server1_pathlen_int_max-1.crt
new file mode 100644
index 0000000..4944844
--- /dev/null
+++ b/tests/data_files/server1_pathlen_int_max-1.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDSDCCAjCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER
+MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
+MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G
+A1UECgwIUG9sYXJTU0wxGjAYBgNVBAMMEVBvbGFyU1NMIFNlcnZlciAxMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/
+uOhFkNvuiBZS0/FDUEeWEllkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFD
+d185fAkER4KwVzlw7aPsFRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVf
+CrFTxjB+FTms+Vruf5KepgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTr
+lZvc/kFeF6babFtpzAK6FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9w
+bp7OvViJ4lNZnm5akmXiiD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQAB
+o1YwVDASBgNVHRMECzAJAQH/AgR////+MB0GA1UdDgQWBBQfdNY/KcF0dEU7BRIs
+Pai9Q1kCpjAfBgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG
+9w0BAQUFAAOCAQEAfuvq7FomQTSJmGInVwQjQddgoXpnmCZ97TpVq7jHLCFADowQ
+jeiAsxmD8mwAQqw/By0U2PSmQcS7Vrn7Le0nFKNRYYrtpx5rsTFJzS/tQsgCe0Pf
+zhiBgD1Dhw6PWAPmy+JlvhJF7REmFsM8KHQd0xSvJzB1gLN9FVlnd87C73bdDJZQ
+Zdn977+Sn5anAFGHDWeKo8GYaYGnPBQqkX0Q2EKWR7yrwcKMogOevxELogB0jRj3
+L+nBpz7mO2J6XQ85ip+tLWAGCEHo0omAIQorAoCSqtLiaz47HxOdNK0hnM7V5k8P
+05AVhxDa3WqZ9FmMaDc8j8XqmOgKYVMC4/WS0g==
+-----END CERTIFICATE-----
diff --git a/tests/data_files/server1_pathlen_int_max.crt b/tests/data_files/server1_pathlen_int_max.crt
new file mode 100644
index 0000000..517e0d6
--- /dev/null
+++ b/tests/data_files/server1_pathlen_int_max.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDSDCCAjCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER
+MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
+MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G
+A1UECgwIUG9sYXJTU0wxGjAYBgNVBAMMEVBvbGFyU1NMIFNlcnZlciAxMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/
+uOhFkNvuiBZS0/FDUEeWEllkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFD
+d185fAkER4KwVzlw7aPsFRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVf
+CrFTxjB+FTms+Vruf5KepgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTr
+lZvc/kFeF6babFtpzAK6FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9w
+bp7OvViJ4lNZnm5akmXiiD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQAB
+o1YwVDASBgNVHRMECzAJAQH/AgR/////MB0GA1UdDgQWBBQfdNY/KcF0dEU7BRIs
+Pai9Q1kCpjAfBgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG
+9w0BAQUFAAOCAQEAe5jPPMyWrKYGljJH2uh1gEh7KoYhmGIUfYu5A8Z2ou04yFZh
+LDyWJnkE/qpNaIw3kPuoyGBTtADYzttPvxretUmaMyteOQe8DK/mmr8vl+gb54ZP
+2jUE+R27Jp5GSGfl20LNVTBkKJloSyDaVzPI3ozje2lAsXsil8NTKbVJtfjZ9un+
+mGrpywSV7RpZC2PznGFdqQehwwnOscz0cVeMQqGcMRH3D5Bk2SjVexCaPu47QSyE
+fNm6cATiNHjw/2dg5Aue7e4K+R6le+xY3Qy85Fq/lKDeMmbrJRrNyJ9lblCeihUd
+qhkAEPelpaq5ZRM6cYJQoo0Ak64j4svjOZeF0g==
+-----END CERTIFICATE-----
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index ccd4d42..278de16 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -229,6 +229,40 @@
     mbedtls_exit( 1 );                                             \
 }
 
+#if defined(__GNUC__)
+/* Test if arg and &(arg)[0] have the same type. This is true if arg is
+ * an array but not if it's a pointer. */
+#define IS_ARRAY_NOT_POINTER( arg )                                     \
+    ( ! __builtin_types_compatible_p( __typeof__( arg ),                \
+                                      __typeof__( &( arg )[0] ) ) )
+#else
+/* On platforms where we don't know how to implement this check,
+ * omit it. Oh well, a non-portable check is better than nothing. */
+#define IS_ARRAY_NOT_POINTER( arg ) 1
+#endif
+
+/* A compile-time constant with the value 0. If `const_expr` is not a
+ * compile-time constant with a nonzero value, cause a compile-time error. */
+#define STATIC_ASSERT_EXPR( const_expr )                                \
+    ( 0 && sizeof( struct { int STATIC_ASSERT : 1 - 2 * ! ( const_expr ); } ) )
+/* Return the scalar value `value` (possibly promoted). This is a compile-time
+ * constant if `value` is. `condition` must be a compile-time constant.
+ * If `condition` is false, arrange to cause a compile-time error. */
+#define STATIC_ASSERT_THEN_RETURN( condition, value )   \
+    ( STATIC_ASSERT_EXPR( condition ) ? 0 : ( value ) )
+
+#define ARRAY_LENGTH_UNSAFE( array )            \
+    ( sizeof( array ) / sizeof( *( array ) ) )
+/** Return the number of elements of a static or stack array.
+ *
+ * \param array         A value of array (not pointer) type.
+ *
+ * \return The number of elements of the array.
+ */
+#define ARRAY_LENGTH( array )                                           \
+    ( STATIC_ASSERT_THEN_RETURN( IS_ARRAY_NOT_POINTER( array ),         \
+                                 ARRAY_LENGTH_UNSAFE( array ) ) )
+
 /*
  * 32-bit integer manipulation macros (big endian)
  */
diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function
index 26a7be4..5951e46 100644
--- a/tests/suites/host_test.function
+++ b/tests/suites/host_test.function
@@ -385,15 +385,16 @@
     const char *default_filename = "DATA_FILE";
     const char *test_filename = NULL;
     const char **test_files = NULL;
-    int testfile_count = 0;
+    size_t testfile_count = 0;
     int option_verbose = 0;
     int function_id = 0;
 
     /* Other Local variables */
     int arg_index = 1;
     const char *next_arg;
-    int testfile_index, ret, i, cnt;
-    int total_errors = 0, total_tests = 0, total_skipped = 0;
+    size_t testfile_index, i, cnt;
+    int ret;
+    unsigned total_errors = 0, total_tests = 0, total_skipped = 0;
     FILE *file;
     char buf[5000];
     char *params[50];
@@ -473,8 +474,9 @@
           testfile_index < testfile_count;
           testfile_index++ )
     {
-        int unmet_dep_count = 0;
+        size_t unmet_dep_count = 0;
         int unmet_dependencies[20];
+        int missing_unmet_dependencies = 0;
 
         test_filename = test_files[ testfile_index ];
 
@@ -495,6 +497,7 @@
                 mbedtls_exit( MBEDTLS_EXIT_FAILURE );
             }
             unmet_dep_count = 0;
+            missing_unmet_dependencies = 0;
 
             if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
                 break;
@@ -520,8 +523,16 @@
                     int dep_id = strtol( params[i], NULL, 10 );
                     if( dep_check( dep_id ) != DEPENDENCY_SUPPORTED )
                     {
-                        unmet_dependencies[unmet_dep_count] = dep_id;
-                        unmet_dep_count++;
+                        if( unmet_dep_count <
+                            ARRAY_LENGTH( unmet_dependencies ) )
+                        {
+                            unmet_dependencies[unmet_dep_count] = dep_id;
+                            unmet_dep_count++;
+                        }
+                        else
+                        {
+                            missing_unmet_dependencies = 1;
+                        }
                     }
                 }
 
@@ -590,11 +601,14 @@
                         mbedtls_fprintf( stdout, "%d ",
                                         unmet_dependencies[i] );
                     }
+                    if( missing_unmet_dependencies )
+                        mbedtls_fprintf( stdout, "..." );
                 }
                 mbedtls_fprintf( stdout, "\n" );
                 fflush( stdout );
 
                 unmet_dep_count = 0;
+                missing_unmet_dependencies = 0;
             }
             else if( ret == DISPATCH_TEST_SUCCESS )
             {
@@ -641,8 +655,8 @@
     else
         mbedtls_fprintf( stdout, "FAILED" );
 
-    mbedtls_fprintf( stdout, " (%d / %d tests (%d skipped))\n",
-             total_tests - total_errors, total_tests, total_skipped );
+    mbedtls_fprintf( stdout, " (%u / %u tests (%u skipped))\n",
+                     total_tests - total_errors, total_tests, total_skipped );
 
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
     !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC)
diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data
index f8a2918..54c1220 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.16.5"
+check_compiletime_version:"2.16.6"
 
 Check runtime library version
-check_runtime_version:"2.16.5"
+check_runtime_version:"2.16.6"
 
 Check for MBEDTLS_VERSION_C
 check_feature:"MBEDTLS_VERSION_C":0
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 91f8ac9..2c52d08 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -1166,6 +1166,14 @@
 depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
 x509parse_crt:"30819f30819ca0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d010101050003190030160210ffffffffffffffffffffffffffffffff0202ffffa101aaa201bba314301230100603551d130101010406300402010102":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS + MBEDTLS_ERR_ASN1_OUT_OF_DATA
 
+X509 Certificate ASN1 (inv extBasicConstraint, pathlen is INT_MAX)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C:MBEDTLS_SHA1_C
+x509parse_crt_file:"data_files/server1_pathlen_int_max.crt":MBEDTLS_ERR_X509_INVALID_EXTENSIONS + MBEDTLS_ERR_ASN1_INVALID_LENGTH
+
+X509 Certificate ASN1 (pathlen is INT_MAX-1)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C:MBEDTLS_SHA1_C
+x509parse_crt_file:"data_files/server1_pathlen_int_max-1.crt":0
+
 X509 Certificate ASN1 (TBSCertificate v3, ext BasicContraint tag, octet len mismatch)
 depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
 x509parse_crt:"3081a230819fa0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d010101050003190030160210ffffffffffffffffffffffffffffffff0202ffffa101aaa201bba317301530130603551d130101010409300702010102010100":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH