Merge branch 'mbedtls-2.16-restricted' into prepare-rc-2.16.6-updated
* mbedtls-2.16-restricted:
Parse HelloVerifyRequest buffer overread: add changelog entry
Parse HelloVerifyRequest: avoid buffer overread at the start
Parse HelloVerifyRequest: avoid buffer overread on the cookie
diff --git a/ChangeLog b/ChangeLog
index dc2acf7..96fa9f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,6 @@
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
@@ -14,6 +14,8 @@
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/Makefile b/Makefile
index 1ae6bd9..0a9640f 100644
--- a/Makefile
+++ b/Makefile
@@ -123,8 +123,10 @@
## Editor navigation files
C_SOURCE_FILES = $(wildcard include/*/*.h library/*.[hc] programs/*/*.[hc] tests/suites/*.function)
+# Exuberant-ctags invocation. Other ctags implementations may require different options.
+CTAGS = ctags --langmap=c:+.h.function -o
tags: $(C_SOURCE_FILES)
- ctags -o $@ $(C_SOURCE_FILES)
+ $(CTAGS) $@ $(C_SOURCE_FILES)
TAGS: $(C_SOURCE_FILES)
etags -o $@ $(C_SOURCE_FILES)
GPATH GRTAGS GSYMS GTAGS: $(C_SOURCE_FILES)
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/check_config.h b/include/mbedtls/check_config.h
index d076c23..93de091 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -546,6 +546,23 @@
#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites"
#endif
+#if (defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \
+ !(defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) )
+#error "One or more versions of the TLS protocol are enabled " \
+ "but no key exchange methods defined with MBEDTLS_KEY_EXCHANGE_xxxx"
+#endif
+
#if defined(MBEDTLS_SSL_PROTO_DTLS) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
@@ -669,6 +686,10 @@
#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites"
#endif
+#if defined(MBEDTLS_CERTS_C) && !defined(MBEDTLS_X509_USE_C)
+#error "MBEDTLS_CERTS_C defined, but not all prerequisites"
+#endif
+
#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites"
#endif
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/ssl_tls.c b/library/ssl_tls.c
index 65f59fb..cbec74f 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4005,17 +4005,23 @@
if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED )
{
+ int send_ret;
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "sending HelloVerifyRequest" ) );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
+ ssl->out_buf, len );
/* Don't check write errors as we can't do anything here.
* If the error is permanent we'll catch it later,
* if it's not, then hopefully it'll work next time. */
- (void) ssl->f_send( ssl->p_bio, ssl->out_buf, len );
+ send_ret = ssl->f_send( ssl->p_bio, ssl->out_buf, len );
+ MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", send_ret );
+ (void) send_ret;
return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
}
if( ret == 0 )
{
- /* Got a valid cookie, partially reset context */
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "cookie is valid, resetting context" ) );
if( ( ret = ssl_session_reset_int( ssl, 1 ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret );
diff --git a/library/x509.c b/library/x509.c
index 2e0b0e8..4d25303 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -1063,7 +1063,7 @@
mbedtls_x509_crt_free( &clicert );
#else
((void) verbose);
-#endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA256_C */
return( ret );
}
diff --git a/programs/test/udp_proxy.c b/programs/test/udp_proxy.c
index e96e91b..4be0865 100644
--- a/programs/test/udp_proxy.c
+++ b/programs/test/udp_proxy.c
@@ -130,6 +130,7 @@
" bad_ad=0/1 default: 0 (don't add bad ApplicationData)\n" \
" protect_hvr=0/1 default: 0 (don't protect HelloVerifyRequest)\n" \
" protect_len=%%d default: (don't protect packets of this size)\n" \
+ " inject_clihlo=0/1 default: 0 (don't inject fake ClientHello)\n" \
"\n" \
" seed=%%d default: (use current time)\n" \
USAGE_PACK \
@@ -162,6 +163,7 @@
int bad_ad; /* inject corrupted ApplicationData record */
int protect_hvr; /* never drop or delay HelloVerifyRequest */
int protect_len; /* never drop/delay packet of the given size*/
+ int inject_clihlo; /* inject fake ClientHello after handshake */
unsigned pack; /* merge packets into single datagram for
* at most \c merge milliseconds if > 0 */
unsigned int seed; /* seed for "random" events */
@@ -304,6 +306,12 @@
if( opt.protect_len < 0 )
exit_usage( p, q );
}
+ else if( strcmp( p, "inject_clihlo" ) == 0 )
+ {
+ opt.inject_clihlo = atoi( q );
+ if( opt.inject_clihlo < 0 || opt.inject_clihlo > 1 )
+ exit_usage( p, q );
+ }
else if( strcmp( p, "seed" ) == 0 )
{
opt.seed = atoi( q );
@@ -503,11 +511,41 @@
fflush( stdout );
}
+/*
+ * In order to test the server's behaviour when receiving a ClientHello after
+ * the connection is established (this could be a hard reset from the client,
+ * but the server must not drop the existing connection before establishing
+ * client reachability, see RFC 6347 Section 4.2.8), we memorize the first
+ * ClientHello we see (which can't have a cookie), then replay it after the
+ * first ApplicationData record - then we're done.
+ *
+ * This is controlled by the inject_clihlo option.
+ *
+ * We want an explicit state and a place to store the packet.
+ */
+typedef enum {
+ ICH_INIT, /* haven't seen the first ClientHello yet */
+ ICH_CACHED, /* cached the initial ClientHello */
+ ICH_INJECTED, /* ClientHello already injected, done */
+} inject_clihlo_state_t;
+
+static inject_clihlo_state_t inject_clihlo_state;
+static packet initial_clihlo;
+
int send_packet( const packet *p, const char *why )
{
int ret;
mbedtls_net_context *dst = p->dst;
+ /* save initial ClientHello? */
+ if( opt.inject_clihlo != 0 &&
+ inject_clihlo_state == ICH_INIT &&
+ strcmp( p->type, "ClientHello" ) == 0 )
+ {
+ memcpy( &initial_clihlo, p, sizeof( packet ) );
+ inject_clihlo_state = ICH_CACHED;
+ }
+
/* insert corrupted ApplicationData record? */
if( opt.bad_ad &&
strcmp( p->type, "ApplicationData" ) == 0 )
@@ -553,6 +591,23 @@
}
}
+ /* Inject ClientHello after first ApplicationData */
+ if( opt.inject_clihlo != 0 &&
+ inject_clihlo_state == ICH_CACHED &&
+ strcmp( p->type, "ApplicationData" ) == 0 )
+ {
+ print_packet( &initial_clihlo, "injected" );
+
+ if( ( ret = dispatch_data( dst, initial_clihlo.buf,
+ initial_clihlo.len ) ) <= 0 )
+ {
+ mbedtls_printf( " ! dispatch returned %d\n", ret );
+ return( ret );
+ }
+
+ inject_clihlo_state = ICH_INJECTED;
+ }
+
return( 0 );
}
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 9fbf592..24c8616 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -5759,8 +5759,8 @@
not_with_valgrind # spurious resend
run_test "DTLS client reconnect from same port: reference" \
- "$P_SRV dtls=1 exchanges=2 read_timeout=1000" \
- "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=500-1000" \
+ "$P_SRV dtls=1 exchanges=2 read_timeout=20000 hs_timeout=10000-20000" \
+ "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=10000-20000" \
0 \
-C "resend" \
-S "The operation timed out" \
@@ -5768,8 +5768,8 @@
not_with_valgrind # spurious resend
run_test "DTLS client reconnect from same port: reconnect" \
- "$P_SRV dtls=1 exchanges=2 read_timeout=1000" \
- "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=500-1000 reconnect_hard=1" \
+ "$P_SRV dtls=1 exchanges=2 read_timeout=20000 hs_timeout=10000-20000" \
+ "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=10000-20000 reconnect_hard=1" \
0 \
-C "resend" \
-S "The operation timed out" \
@@ -5798,6 +5798,14 @@
-s "The operation timed out" \
-S "Client initiated reconnection from same port"
+run_test "DTLS client reconnect from same port: attacker-injected" \
+ -p "$P_PXY inject_clihlo=1" \
+ "$P_SRV dtls=1 exchanges=2 debug_level=1" \
+ "$P_CLI dtls=1 exchanges=2" \
+ 0 \
+ -s "possible client reconnect from the same port" \
+ -S "Client initiated reconnection from same port"
+
# Tests for various cases of client authentication with DTLS
# (focused on handshake flows and message parsing)
@@ -6867,8 +6875,8 @@
not_with_valgrind # spurious resend due to timeout
run_test "DTLS proxy: reference" \
-p "$P_PXY" \
- "$P_SRV dtls=1 debug_level=2" \
- "$P_CLI dtls=1 debug_level=2" \
+ "$P_SRV dtls=1 debug_level=2 hs_timeout=10000-20000" \
+ "$P_CLI dtls=1 debug_level=2 hs_timeout=10000-20000" \
0 \
-C "replayed record" \
-S "replayed record" \
@@ -6883,8 +6891,8 @@
not_with_valgrind # spurious resend due to timeout
run_test "DTLS proxy: duplicate every packet" \
-p "$P_PXY duplicate=1" \
- "$P_SRV dtls=1 dgram_packing=0 debug_level=2" \
- "$P_CLI dtls=1 dgram_packing=0 debug_level=2" \
+ "$P_SRV dtls=1 dgram_packing=0 debug_level=2 hs_timeout=10000-20000" \
+ "$P_CLI dtls=1 dgram_packing=0 debug_level=2 hs_timeout=10000-20000" \
0 \
-c "replayed record" \
-s "replayed record" \
diff --git a/tests/suites/test_suite_asn1write.function b/tests/suites/test_suite_asn1write.function
index 57a9741..7601439 100644
--- a/tests/suites/test_suite_asn1write.function
+++ b/tests/suites/test_suite_asn1write.function
@@ -78,7 +78,7 @@
}
/* END_CASE */
-/* BEGIN_CASE depends_on:MBEDTLS_ASN1PARSE_C */
+/* BEGIN_CASE depends_on:MBEDTLS_ASN1_PARSE_C */
void mbedtls_asn1_write_len( int len, data_t * asn1, int buf_len,
int result )
{
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